]> git.wh0rd.org - tt-rss.git/blob - functions.php
new filter action: tag article
[tt-rss.git] / functions.php
1 <?php
2
3 /* if ($_GET["debug"]) {
4 define('DEFAULT_ERROR_LEVEL', E_ALL);
5 } else {
6 define('DEFAULT_ERROR_LEVEL', E_ERROR | E_WARNING | E_PARSE);
7 } */
8
9 require_once 'config.php';
10 require_once 'db-prefs.php';
11 require_once 'compat.php';
12 require_once 'errors.php';
13 require_once 'version.php';
14
15 if (RSS_BACKEND_TYPE == "magpie") {
16 define('MAGPIE_USER_AGENT_EXT', ' (Tiny Tiny RSS/' . VERSION . ')');
17 require_once "magpierss/rss_fetch.inc";
18 require_once 'magpierss/rss_utils.inc';
19 } else if (RSS_BACKEND_TYPE == "simplepie") {
20 require_once 'simplepie/simplepie.inc';
21 }
22
23 define('MAGPIE_OUTPUT_ENCODING', 'UTF-8');
24
25 function purge_feed($link, $feed_id, $purge_interval, $debug = false) {
26
27 $rows = -1;
28
29 if (DB_TYPE == "pgsql") {
30 /* $result = db_query($link, "DELETE FROM ttrss_user_entries WHERE
31 marked = false AND feed_id = '$feed_id' AND
32 (SELECT date_entered FROM ttrss_entries WHERE
33 id = ref_id) < NOW() - INTERVAL '$purge_interval days'"); */
34
35 $pg_version = get_pgsql_version($link);
36
37 if (preg_match("/^7\./", $pg_version) || preg_match("/^8\.0/", $pg_version)) {
38
39 $result = db_query($link, "DELETE FROM ttrss_user_entries WHERE
40 ttrss_entries.id = ref_id AND
41 marked = false AND
42 feed_id = '$feed_id' AND
43 ttrss_entries.date_entered < NOW() - INTERVAL '$purge_interval days'");
44
45 } else {
46
47 $result = db_query($link, "DELETE FROM ttrss_user_entries
48 USING ttrss_entries
49 WHERE ttrss_entries.id = ref_id AND
50 marked = false AND
51 feed_id = '$feed_id' AND
52 ttrss_entries.date_entered < NOW() - INTERVAL '$purge_interval days'");
53 }
54
55 $rows = pg_affected_rows($result);
56
57 } else {
58
59 /* $result = db_query($link, "DELETE FROM ttrss_user_entries WHERE
60 marked = false AND feed_id = '$feed_id' AND
61 (SELECT date_entered FROM ttrss_entries WHERE
62 id = ref_id) < DATE_SUB(NOW(), INTERVAL $purge_interval DAY)"); */
63
64 $result = db_query($link, "DELETE FROM ttrss_user_entries
65 USING ttrss_user_entries, ttrss_entries
66 WHERE ttrss_entries.id = ref_id AND
67 marked = false AND
68 feed_id = '$feed_id' AND
69 ttrss_entries.date_entered < DATE_SUB(NOW(), INTERVAL $purge_interval DAY)");
70
71 $rows = mysql_affected_rows($link);
72
73 }
74
75 if ($debug) {
76 print "Purged feed $feed_id ($purge_interval): deleted $rows articles\n";
77 }
78 }
79
80 function global_purge_old_posts($link, $do_output = false, $limit = false) {
81
82 $random_qpart = sql_random_function();
83
84 if ($limit) {
85 $limit_qpart = "LIMIT $limit";
86 } else {
87 $limit_qpart = "";
88 }
89
90 $result = db_query($link,
91 "SELECT id,purge_interval,owner_uid FROM ttrss_feeds
92 ORDER BY $random_qpart $limit_qpart");
93
94 while ($line = db_fetch_assoc($result)) {
95
96 $feed_id = $line["id"];
97 $purge_interval = $line["purge_interval"];
98 $owner_uid = $line["owner_uid"];
99
100 if ($purge_interval == 0) {
101
102 $tmp_result = db_query($link,
103 "SELECT value FROM ttrss_user_prefs WHERE
104 pref_name = 'PURGE_OLD_DAYS' AND owner_uid = '$owner_uid'");
105
106 if (db_num_rows($tmp_result) != 0) {
107 $purge_interval = db_fetch_result($tmp_result, 0, "value");
108 }
109 }
110
111 if ($do_output) {
112 // print "Feed $feed_id: purge interval = $purge_interval\n";
113 }
114
115 if ($purge_interval > 0) {
116 purge_feed($link, $feed_id, $purge_interval, $do_output);
117 }
118 }
119
120 // purge orphaned posts in main content table
121 db_query($link, "DELETE FROM ttrss_entries WHERE
122 (SELECT COUNT(int_id) FROM ttrss_user_entries WHERE ref_id = id) = 0");
123
124 }
125
126 function purge_old_posts($link) {
127
128 $user_id = $_SESSION["uid"];
129
130 $result = db_query($link, "SELECT id,purge_interval FROM ttrss_feeds
131 WHERE owner_uid = '$user_id'");
132
133 while ($line = db_fetch_assoc($result)) {
134
135 $feed_id = $line["id"];
136 $purge_interval = $line["purge_interval"];
137
138 if ($purge_interval == 0) $purge_interval = get_pref($link, 'PURGE_OLD_DAYS');
139
140 if ($purge_interval > 0) {
141 purge_feed($link, $feed_id, $purge_interval);
142 }
143 }
144
145 // purge orphaned posts in main content table
146 db_query($link, "DELETE FROM ttrss_entries WHERE
147 (SELECT COUNT(int_id) FROM ttrss_user_entries WHERE ref_id = id) = 0");
148 }
149
150 function update_all_feeds($link, $fetch, $user_id = false, $force_daemon = false) {
151
152 if (WEB_DEMO_MODE) return;
153
154 if (!$user_id) {
155 $user_id = $_SESSION["uid"];
156 purge_old_posts($link);
157 }
158
159 // db_query($link, "BEGIN");
160
161 if (MAX_UPDATE_TIME > 0) {
162 if (DB_TYPE == "mysql") {
163 $q_order = "RAND()";
164 } else {
165 $q_order = "RANDOM()";
166 }
167 } else {
168 $q_order = "last_updated DESC";
169 }
170
171 $result = db_query($link, "SELECT feed_url,id,
172 SUBSTRING(last_updated,1,19) AS last_updated,
173 update_interval FROM ttrss_feeds WHERE owner_uid = '$user_id'
174 ORDER BY $q_order");
175
176 $upd_start = time();
177
178 while ($line = db_fetch_assoc($result)) {
179 $upd_intl = $line["update_interval"];
180
181 if (!$upd_intl || $upd_intl == 0) {
182 $upd_intl = get_pref($link, 'DEFAULT_UPDATE_INTERVAL', $user_id, false);
183 }
184
185 if ($upd_intl < 0) {
186 // Updates for this feed are disabled
187 continue;
188 }
189
190 if ($fetch || (!$line["last_updated"] ||
191 time() - strtotime($line["last_updated"]) > ($upd_intl * 60))) {
192
193 // print "<!-- feed: ".$line["feed_url"]." -->";
194
195 update_rss_feed($link, $line["feed_url"], $line["id"], $force_daemon);
196
197 $upd_elapsed = time() - $upd_start;
198
199 if (MAX_UPDATE_TIME > 0 && $upd_elapsed > MAX_UPDATE_TIME) {
200 return;
201 }
202 }
203 }
204
205 // db_query($link, "COMMIT");
206
207 }
208
209 function fetch_file_contents($url) {
210 if (USE_CURL_FOR_ICONS) {
211 $tmpfile = tempnam(TMP_DIRECTORY, "ttrss-tmp");
212
213 $ch = curl_init($url);
214 $fp = fopen($tmpfile, "w");
215
216 if ($fp) {
217 curl_setopt($ch, CURLOPT_FILE, $fp);
218 curl_exec($ch);
219 curl_close($ch);
220 fclose($fp);
221 }
222
223 $contents = file_get_contents($tmpfile);
224 unlink($tmpfile);
225
226 return $contents;
227
228 } else {
229 return file_get_contents($url);
230 }
231
232 }
233
234 // adapted from wordpress favicon plugin by Jeff Minard (http://thecodepro.com/)
235 // http://dev.wp-plugins.org/file/favatars/trunk/favatars.php
236
237 function get_favicon_url($url) {
238
239 if ($html = @fetch_file_contents($url)) {
240
241 if ( preg_match('/<link[^>]+rel="(?:shortcut )?icon"[^>]+?href="([^"]+?)"/si', $html, $matches)) {
242 // Attempt to grab a favicon link from their webpage url
243 $linkUrl = html_entity_decode($matches[1]);
244
245 if (substr($linkUrl, 0, 1) == '/') {
246 $urlParts = parse_url($url);
247 $faviconURL = $urlParts['scheme'].'://'.$urlParts['host'].$linkUrl;
248 } else if (substr($linkUrl, 0, 7) == 'http://') {
249 $faviconURL = $linkUrl;
250 } else if (substr($url, -1, 1) == '/') {
251 $faviconURL = $url.$linkUrl;
252 } else {
253 $faviconURL = $url.'/'.$linkUrl;
254 }
255
256 } else {
257 // If unsuccessful, attempt to "guess" the favicon location
258 $urlParts = parse_url($url);
259 $faviconURL = $urlParts['scheme'].'://'.$urlParts['host'].'/favicon.ico';
260 }
261 }
262
263 // Run a test to see if what we have attempted to get actually exists.
264 if(USE_CURL_FOR_ICONS || url_validate($faviconURL)) {
265 return $faviconURL;
266 } else {
267 return false;
268 }
269 }
270
271 function url_validate($link) {
272
273 $url_parts = @parse_url($link);
274
275 if ( empty( $url_parts["host"] ) )
276 return false;
277
278 if ( !empty( $url_parts["path"] ) ) {
279 $documentpath = $url_parts["path"];
280 } else {
281 $documentpath = "/";
282 }
283
284 if ( !empty( $url_parts["query"] ) )
285 $documentpath .= "?" . $url_parts["query"];
286
287 $host = $url_parts["host"];
288 $port = $url_parts["port"];
289
290 if ( empty($port) )
291 $port = "80";
292
293 $socket = @fsockopen( $host, $port, $errno, $errstr, 30 );
294
295 if ( !$socket )
296 return false;
297
298 fwrite ($socket, "HEAD ".$documentpath." HTTP/1.0\r\nHost: $host\r\n\r\n");
299
300 $http_response = fgets( $socket, 22 );
301
302 $responses = "/(200 OK)|(30[0-9] Moved)/";
303 if ( preg_match($responses, $http_response) ) {
304 fclose($socket);
305 return true;
306 } else {
307 return false;
308 }
309
310 }
311
312 function check_feed_favicon($site_url, $feed, $link) {
313 $favicon_url = get_favicon_url($site_url);
314
315 # print "FAVICON [$site_url]: $favicon_url\n";
316
317 error_reporting(0);
318
319 $icon_file = ICONS_DIR . "/$feed.ico";
320
321 if ($favicon_url && !file_exists($icon_file)) {
322 $contents = fetch_file_contents($favicon_url);
323
324 $fp = fopen($icon_file, "w");
325
326 if ($fp) {
327 fwrite($fp, $contents);
328 fclose($fp);
329 chmod($icon_file, 0644);
330 }
331 }
332
333 error_reporting(DEFAULT_ERROR_LEVEL);
334
335 }
336
337 function update_rss_feed($link, $feed_url, $feed, $ignore_daemon = false) {
338
339 if (WEB_DEMO_MODE) return;
340
341 if (DAEMON_REFRESH_ONLY && !$_GET["daemon"] && !$ignore_daemon) {
342 return;
343 }
344
345 $result = db_query($link, "SELECT update_interval,auth_login,auth_pass
346 FROM ttrss_feeds WHERE id = '$feed'");
347
348 $auth_login = db_unescape_string(db_fetch_result($result, 0, "auth_login"));
349 $auth_pass = db_unescape_string(db_fetch_result($result, 0, "auth_pass"));
350
351 $update_interval = db_fetch_result($result, 0, "update_interval");
352
353 if ($update_interval < 0) { return; }
354
355 $feed = db_escape_string($feed);
356
357 $fetch_url = $feed_url;
358
359 if ($auth_login && $auth_pass) {
360 $url_parts = array();
361 preg_match("/(^[^:]*):\/\/(.*)/", $fetch_url, $url_parts);
362
363 if ($url_parts[1] && $url_parts[2]) {
364 $fetch_url = $url_parts[1] . "://$auth_login:$auth_pass@" . $url_parts[2];
365 }
366
367 }
368
369 if (RSS_BACKEND_TYPE == "magpie") {
370 error_reporting(0);
371 $rss = fetch_rss($fetch_url);
372 error_reporting (DEFAULT_ERROR_LEVEL);
373 } else if (RSS_BACKEND_TYPE == "simplepie") {
374
375 if (!file_exists(SIMPLEPIE_CACHE_DIR)) {
376 mkdir(SIMPLEPIE_CACHE_DIR);
377 }
378
379 $rss = new SimplePie();
380 $rss->feed_url($fetch_url);
381 $rss->cache_location(SIMPLEPIE_CACHE_DIR);
382 $rss->init();
383 }
384
385 $feed = db_escape_string($feed);
386
387 $rss_check = $rss;
388
389 if (RSS_BACKEND_TYPE == "simplepie") {
390 $rss_check = $rss->data;
391 }
392
393 if ($rss_check) {
394
395 // db_query($link, "BEGIN");
396
397 $result = db_query($link, "SELECT title,icon_url,site_url,owner_uid
398 FROM ttrss_feeds WHERE id = '$feed'");
399
400 $registered_title = db_fetch_result($result, 0, "title");
401 $orig_icon_url = db_fetch_result($result, 0, "icon_url");
402 $orig_site_url = db_fetch_result($result, 0, "site_url");
403
404 $owner_uid = db_fetch_result($result, 0, "owner_uid");
405
406 if (get_pref($link, 'ENABLE_FEED_ICONS', $owner_uid, false)) {
407 check_feed_favicon($rss->channel["link"], $feed, $link);
408 }
409
410 if (!$registered_title || $registered_title == "[Unknown]") {
411
412 if (RSS_BACKEND_TYPE == "magpie") {
413 $feed_title = db_escape_string($rss->channel["title"]);
414 } else {
415 $feed_title = $rss->get_feed_title();
416 }
417
418 db_query($link, "UPDATE ttrss_feeds SET
419 title = '$feed_title' WHERE id = '$feed'");
420 }
421
422 if (RSS_BACKEND_TYPE == "magpie") {
423 $site_url = $rss->channel["link"];
424 // weird, weird Magpie
425 if (!$site_url) $site_url = db_escape_string($rss->channel["link_"]);
426 } else {
427 $site_url = $rss->get_feed_link();
428 }
429
430 if ($site_url && $orig_site_url != db_escape_string($site_url)) {
431 db_query($link, "UPDATE ttrss_feeds SET
432 site_url = '$site_url' WHERE id = '$feed'");
433 }
434
435 // print "I: " . $rss->channel["image"]["url"];
436
437 if (RSS_BACKEND_TYPE == "magpie") {
438 $icon_url = $rss->image["url"];
439 } else {
440 $icon_url = $rss->get_image_url(); # FIXME
441 }
442
443 if ($icon_url && !$orig_icon_url != db_escape_string($icon_url)) {
444 $icon_url = db_escape_string($icon_url);
445 db_query($link, "UPDATE ttrss_feeds SET icon_url = '$icon_url' WHERE id = '$feed'");
446 }
447
448
449 $filters = array();
450
451 $result = db_query($link, "SELECT reg_exp,
452 ttrss_filter_types.name AS name,
453 ttrss_filter_actions.name AS action,
454 action_param
455 FROM ttrss_filters,ttrss_filter_types,ttrss_filter_actions WHERE
456 enabled = true AND
457 owner_uid = $owner_uid AND
458 ttrss_filter_types.id = filter_type AND
459 ttrss_filter_actions.id = action_id AND
460 (feed_id IS NULL OR feed_id = '$feed')");
461
462 while ($line = db_fetch_assoc($result)) {
463 if (!$filters[$line["name"]]) $filters[$line["name"]] = array();
464
465 $filter["reg_exp"] = $line["reg_exp"];
466 $filter["action"] = $line["action"];
467 $filter["action_param"] = $line["action_param"];
468
469 array_push($filters[$line["name"]], $filter);
470 }
471
472 if (RSS_BACKEND_TYPE == "magpie") {
473 $iterator = $rss->items;
474
475 if (!$iterator || !is_array($iterator)) $iterator = $rss->entries;
476 if (!$iterator || !is_array($iterator)) $iterator = $rss;
477
478 } else {
479 $iterator = $rss->get_items();
480 }
481
482 if (!is_array($iterator)) {
483 /* db_query($link, "UPDATE ttrss_feeds
484 SET last_error = 'Parse error: can\'t find any articles.'
485 WHERE id = '$feed'"); */
486 return; // WTF?
487 }
488
489 foreach ($iterator as $item) {
490
491 if (RSS_BACKEND_TYPE == "magpie") {
492
493 $entry_guid = $item["id"];
494
495 if (!$entry_guid) $entry_guid = $item["guid"];
496 if (!$entry_guid) $entry_guid = $item["link"];
497 if (!$entry_guid) $entry_guid = make_guid_from_title($item["title"]);
498
499 if (!$entry_guid) continue;
500
501 $entry_timestamp = "";
502
503 $rss_2_date = $item['pubdate'];
504 $rss_1_date = $item['dc']['date'];
505 $atom_date = $item['issued'];
506 if (!$atom_date) $atom_date = $item['updated'];
507
508 if ($atom_date != "") $entry_timestamp = parse_w3cdtf($atom_date);
509 if ($rss_1_date != "") $entry_timestamp = parse_w3cdtf($rss_1_date);
510 if ($rss_2_date != "") $entry_timestamp = strtotime($rss_2_date);
511
512 if ($entry_timestamp == "") {
513 $entry_timestamp = time();
514 $no_orig_date = 'true';
515 } else {
516 $no_orig_date = 'false';
517 }
518
519 $entry_timestamp_fmt = strftime("%Y/%m/%d %H:%M:%S", $entry_timestamp);
520
521 $entry_title = trim(strip_tags($item["title"]));
522
523 // strange Magpie workaround
524 $entry_link = $item["link_"];
525 if (!$entry_link) $entry_link = $item["link"];
526
527 if (!$entry_title) continue;
528 # if (!$entry_link) continue;
529
530 $entry_link = strip_tags($entry_link);
531
532 $entry_content = $item["content:escaped"];
533
534 if (!$entry_content) $entry_content = $item["content:encoded"];
535 if (!$entry_content) $entry_content = $item["content"];
536 if (!$entry_content) $entry_content = $item["atom_content"];
537 if (!$entry_content) $entry_content = $item["summary"];
538 if (!$entry_content) $entry_content = $item["description"];
539
540 // if (!$entry_content) continue;
541
542 // WTF
543 if (is_array($entry_content)) {
544 $entry_content = $entry_content["encoded"];
545 if (!$entry_content) $entry_content = $entry_content["escaped"];
546 }
547
548 // print_r($item);
549 // print_r(htmlspecialchars($entry_content));
550 // print "<br>";
551
552 $entry_content_unescaped = $entry_content;
553 $content_hash = "SHA1:" . sha1(strip_tags($entry_content));
554
555 $entry_comments = strip_tags($item["comments"]);
556
557 $entry_author = db_escape_string(strip_tags($item['dc']['creator']));
558
559 if (!$entry_author) {
560 $entry_author = db_escape_string(strip_tags($item['author']));
561 }
562
563 $entry_guid = db_escape_string(strip_tags($entry_guid));
564
565 $result = db_query($link, "SELECT id FROM ttrss_entries
566 WHERE guid = '$entry_guid'");
567
568 $entry_content = db_escape_string($entry_content);
569 $entry_title = db_escape_string($entry_title);
570 $entry_link = db_escape_string($entry_link);
571 $entry_comments = db_escape_string($entry_comments);
572
573 $num_comments = db_escape_string($item["slash"]["comments"]);
574
575 if (!$num_comments) $num_comments = 0;
576 }
577
578 # sanitize content
579
580 $entry_content = sanitize_rss($entry_content);
581
582 db_query($link, "BEGIN");
583
584 if (db_num_rows($result) == 0) {
585
586 // base post entry does not exist, create it
587
588 $result = db_query($link,
589 "INSERT INTO ttrss_entries
590 (title,
591 guid,
592 link,
593 updated,
594 content,
595 content_hash,
596 no_orig_date,
597 date_entered,
598 comments,
599 num_comments,
600 author)
601 VALUES
602 ('$entry_title',
603 '$entry_guid',
604 '$entry_link',
605 '$entry_timestamp_fmt',
606 '$entry_content',
607 '$content_hash',
608 $no_orig_date,
609 NOW(),
610 '$entry_comments',
611 '$num_comments',
612 '$entry_author')");
613 } else {
614 // we keep encountering the entry in feeds, so we need to
615 // update date_entered column so that we don't get horrible
616 // dupes when the entry gets purged and reinserted again e.g.
617 // in the case of SLOW SLOW OMG SLOW updating feeds
618
619 $base_entry_id = db_fetch_result($result, 0, "id");
620
621 db_query($link, "UPDATE ttrss_entries SET date_entered = NOW()
622 WHERE id = '$base_entry_id'");
623 }
624
625 // now it should exist, if not - bad luck then
626
627 $result = db_query($link, "SELECT
628 id,content_hash,no_orig_date,title,
629 substring(date_entered,1,19) as date_entered,
630 substring(updated,1,19) as updated,
631 num_comments
632 FROM
633 ttrss_entries
634 WHERE guid = '$entry_guid'");
635
636 if (db_num_rows($result) == 1) {
637
638 // this will be used below in update handler
639 $orig_content_hash = db_fetch_result($result, 0, "content_hash");
640 $orig_title = db_fetch_result($result, 0, "title");
641 $orig_num_comments = db_fetch_result($result, 0, "num_comments");
642 $orig_date_entered = strtotime(db_fetch_result($result,
643 0, "date_entered"));
644
645 $ref_id = db_fetch_result($result, 0, "id");
646
647 // check for user post link to main table
648
649 // do we allow duplicate posts with same GUID in different feeds?
650 if (get_pref($link, "ALLOW_DUPLICATE_POSTS", $owner_uid, false)) {
651 $dupcheck_qpart = "AND feed_id = '$feed'";
652 } else {
653 $dupcheck_qpart = "";
654 }
655
656 // error_reporting(0);
657
658 $tuple = get_filter_name($entry_title, $entry_content,
659 $entry_link, $filters);
660
661 $filter_name = $tuple[0];
662 $filter_param = $tuple[1];
663
664 if ($filter_name == "filter") {
665 continue;
666 }
667
668 // error_reporting (DEFAULT_ERROR_LEVEL);
669
670 $result = db_query($link,
671 "SELECT ref_id FROM ttrss_user_entries WHERE
672 ref_id = '$ref_id' AND owner_uid = '$owner_uid'
673 $dupcheck_qpart");
674
675 // okay it doesn't exist - create user entry
676 if (db_num_rows($result) == 0) {
677
678 if ($filter_name != 'catchup') {
679 $unread = 'true';
680 $last_read_qpart = 'NULL';
681 } else {
682 $unread = 'false';
683 $last_read_qpart = 'NOW()';
684 }
685
686 if ($filter_name == 'mark') {
687 $marked = 'true';
688 } else {
689 $marked = 'false';
690 }
691
692 $result = db_query($link,
693 "INSERT INTO ttrss_user_entries
694 (ref_id, owner_uid, feed_id, unread, last_read, marked)
695 VALUES ('$ref_id', '$owner_uid', '$feed', $unread,
696 $last_read_qpart, $marked)");
697 }
698
699 $post_needs_update = false;
700
701 if (get_pref($link, "UPDATE_POST_ON_CHECKSUM_CHANGE", $owner_uid, false) &&
702 ($content_hash != $orig_content_hash)) {
703 $post_needs_update = true;
704 }
705
706 if ($orig_title != $entry_title) {
707 $post_needs_update = true;
708 }
709
710 if ($orig_num_comments != $num_comments) {
711 $post_needs_update = true;
712 }
713
714 // this doesn't seem to be very reliable
715 //
716 // if ($orig_timestamp != $entry_timestamp && !$orig_no_orig_date) {
717 // $post_needs_update = true;
718 // }
719
720 // if post needs update, update it and mark all user entries
721 // linking to this post as updated
722 if ($post_needs_update) {
723
724 // print "<!-- post $orig_title needs update : $post_needs_update -->";
725
726 db_query($link, "UPDATE ttrss_entries
727 SET title = '$entry_title', content = '$entry_content',
728 num_comments = '$num_comments'
729 WHERE id = '$ref_id'");
730
731 if (get_pref($link, "MARK_UNREAD_ON_UPDATE", $owner_uid, false)) {
732 db_query($link, "UPDATE ttrss_user_entries
733 SET last_read = null, unread = true WHERE ref_id = '$ref_id'");
734 } else {
735 db_query($link, "UPDATE ttrss_user_entries
736 SET last_read = null WHERE ref_id = '$ref_id' AND unread = false");
737 }
738
739 }
740 }
741
742 db_query($link, "COMMIT");
743
744 /* taaaags */
745 // <a href="http://technorati.com/tag/Xorg" rel="tag">Xorg</a>, //
746
747 $entry_tags = null;
748
749 preg_match_all("/<a.*?href=.http:\/\/.*?technorati.com\/tag\/([^\"\'>]+)/i",
750 $entry_content_unescaped, $entry_tags);
751
752 // print "<br>$entry_title : $entry_content_unescaped<br>";
753 // print_r($entry_tags);
754 // print "<br>";
755
756 $entry_tags = $entry_tags[1];
757
758 # check for manual tags
759
760 if ($filter_name == "tag") {
761
762 $manual_tags = trim_array(split(",", $filter_param));
763
764 foreach ($manual_tags as $tag) {
765 if (!preg_match("/^[0-9]*$/", $tag)) {
766 array_push($entry_tags, $tag);
767 }
768 }
769 }
770
771 if (count($entry_tags) > 0) {
772
773 db_query($link, "BEGIN");
774
775 $result = db_query($link, "SELECT id,int_id
776 FROM ttrss_entries,ttrss_user_entries
777 WHERE guid = '$entry_guid'
778 AND feed_id = '$feed' AND ref_id = id
779 AND owner_uid = '$owner_uid'");
780
781 if (db_num_rows($result) == 1) {
782
783 $entry_id = db_fetch_result($result, 0, "id");
784 $entry_int_id = db_fetch_result($result, 0, "int_id");
785
786 foreach ($entry_tags as $tag) {
787 $tag = db_escape_string(strtolower($tag));
788
789 $tag = str_replace("+", " ", $tag);
790 $tag = str_replace("technorati tag: ", "", $tag);
791
792 $result = db_query($link, "SELECT id FROM ttrss_tags
793 WHERE tag_name = '$tag' AND post_int_id = '$entry_int_id' AND
794 owner_uid = '$owner_uid' LIMIT 1");
795
796 // print db_fetch_result($result, 0, "id");
797
798 if ($result && db_num_rows($result) == 0) {
799
800 // print "tagging $entry_id as $tag<br>";
801
802 db_query($link, "INSERT INTO ttrss_tags
803 (owner_uid,tag_name,post_int_id)
804 VALUES ('$owner_uid','$tag', '$entry_int_id')");
805 }
806 }
807 }
808 db_query($link, "COMMIT");
809 }
810 }
811
812 db_query($link, "UPDATE ttrss_feeds
813 SET last_updated = NOW(), last_error = '' WHERE id = '$feed'");
814
815 // db_query($link, "COMMIT");
816
817 } else {
818 $error_msg = db_escape_string(magpie_error());
819 db_query($link,
820 "UPDATE ttrss_feeds SET last_error = '$error_msg',
821 last_updated = NOW() WHERE id = '$feed'");
822 }
823
824 }
825
826 function print_select($id, $default, $values, $attributes = "") {
827 print "<select name=\"$id\" id=\"$id\" $attributes>";
828 foreach ($values as $v) {
829 if ($v == $default)
830 $sel = " selected";
831 else
832 $sel = "";
833
834 print "<option$sel>$v</option>";
835 }
836 print "</select>";
837 }
838
839 function print_select_hash($id, $default, $values, $attributes = "") {
840 print "<select name=\"$id\" id='$id' $attributes>";
841 foreach (array_keys($values) as $v) {
842 if ($v == $default)
843 $sel = "selected";
844 else
845 $sel = "";
846
847 print "<option $sel value=\"$v\">".$values[$v]."</option>";
848 }
849
850 print "</select>";
851 }
852
853 function get_filter_name($title, $content, $link, $filters) {
854
855 if ($filters["title"]) {
856 foreach ($filters["title"] as $filter) {
857 $reg_exp = $filter["reg_exp"];
858 if (preg_match("/$reg_exp/i", $title)) {
859 return array($filter["action"], $filter["action_param"]);
860 }
861 }
862 }
863
864 if ($filters["content"]) {
865 foreach ($filters["content"] as $filter) {
866 $reg_exp = $filter["reg_exp"];
867 if (preg_match("/$reg_exp/i", $content)) {
868 return array($filter["action"], $filter["action_param"]);
869 }
870 }
871 }
872
873 if ($filters["both"]) {
874 foreach ($filters["both"] as $filter) {
875 $reg_exp = $filter["reg_exp"];
876 if (preg_match("/$reg_exp/i", $title) ||
877 preg_match("/$reg_exp/i", $content)) {
878 return array($filter["action"], $filter["action_param"]);
879 }
880 }
881 }
882
883 if ($filters["link"]) {
884 $reg_exp = $filter["reg_exp"];
885 foreach ($filters["link"] as $filter) {
886 $reg_exp = $filter["reg_exp"];
887 if (preg_match("/$reg_exp/i", $link)) {
888 return array($filter["action"], $filter["action_param"]);
889 }
890 }
891 }
892
893 return false;
894 }
895
896 function printFeedEntry($feed_id, $class, $feed_title, $unread, $icon_file, $link,
897 $rtl_content = false, $last_updated = false, $last_error = false) {
898
899 if (file_exists($icon_file) && filesize($icon_file) > 0) {
900 $feed_icon = "<img id=\"FIMG-$feed_id\" src=\"$icon_file\">";
901 } else {
902 $feed_icon = "<img id=\"FIMG-$feed_id\" src=\"images/blank_icon.gif\">";
903 }
904
905 if ($rtl_content) {
906 $rtl_tag = "dir=\"rtl\"";
907 } else {
908 $rtl_tag = "dir=\"ltr\"";
909 }
910
911 $error_notify_msg = "";
912
913 if ($last_error) {
914 $link_title = "Error: $last_error ($last_updated)";
915 $error_notify_msg = "(Error)";
916 } else if ($last_updated) {
917 $link_title = "Updated: $last_updated";
918 }
919
920 $feed = "<a title=\"$link_title\" id=\"FEEDL-$feed_id\"
921 href=\"#\" onclick=\"javascript:viewfeed('$feed_id', '', false);\">$feed_title</a>";
922
923 print "<li id=\"FEEDR-$feed_id\" class=\"$class\">";
924 if (get_pref($link, 'ENABLE_FEED_ICONS')) {
925 print "$feed_icon";
926 }
927
928 print "<span $rtl_tag id=\"FEEDN-$feed_id\">$feed</span>";
929
930 if ($unread != 0) {
931 $fctr_class = "";
932 } else {
933 $fctr_class = "class=\"invisible\"";
934 }
935
936 print " <span $rtl_tag $fctr_class id=\"FEEDCTR-$feed_id\">
937 (<span id=\"FEEDU-$feed_id\">$unread</span>)</span>";
938
939 if (get_pref($link, "EXTENDED_FEEDLIST")) {
940 print "<div class=\"feedExtInfo\">
941 <span id=\"FLUPD-$feed_id\">$last_updated $error_notify_msg</span></div>";
942 }
943
944 print "</li>";
945
946 }
947
948 function getmicrotime() {
949 list($usec, $sec) = explode(" ",microtime());
950 return ((float)$usec + (float)$sec);
951 }
952
953 function print_radio($id, $default, $values, $attributes = "") {
954 foreach ($values as $v) {
955
956 if ($v == $default)
957 $sel = "checked";
958 else
959 $sel = "";
960
961 if ($v == "Yes") {
962 $sel .= " value=\"1\"";
963 } else {
964 $sel .= " value=\"0\"";
965 }
966
967 print "<input class=\"noborder\"
968 type=\"radio\" $sel $attributes name=\"$id\">&nbsp;$v&nbsp;";
969
970 }
971 }
972
973 function initialize_user_prefs($link, $uid) {
974
975 $uid = db_escape_string($uid);
976
977 db_query($link, "BEGIN");
978
979 $result = db_query($link, "SELECT pref_name,def_value FROM ttrss_prefs");
980
981 $u_result = db_query($link, "SELECT pref_name
982 FROM ttrss_user_prefs WHERE owner_uid = '$uid'");
983
984 $active_prefs = array();
985
986 while ($line = db_fetch_assoc($u_result)) {
987 array_push($active_prefs, $line["pref_name"]);
988 }
989
990 while ($line = db_fetch_assoc($result)) {
991 if (array_search($line["pref_name"], $active_prefs) === FALSE) {
992 // print "adding " . $line["pref_name"] . "<br>";
993
994 db_query($link, "INSERT INTO ttrss_user_prefs
995 (owner_uid,pref_name,value) VALUES
996 ('$uid', '".$line["pref_name"]."','".$line["def_value"]."')");
997
998 }
999 }
1000
1001 db_query($link, "COMMIT");
1002
1003 }
1004
1005 function lookup_user_id($link, $user) {
1006
1007 $result = db_query($link, "SELECT id FROM ttrss_users WHERE
1008 login = '$login'");
1009
1010 if (db_num_rows($result) == 1) {
1011 return db_fetch_result($result, 0, "id");
1012 } else {
1013 return false;
1014 }
1015 }
1016
1017 function http_authenticate_user($link) {
1018
1019 if (!$_SERVER["PHP_AUTH_USER"]) {
1020
1021 header('WWW-Authenticate: Basic realm="Tiny Tiny RSS RSSGen"');
1022 header('HTTP/1.0 401 Unauthorized');
1023 exit;
1024
1025 } else {
1026 $auth_result = authenticate_user($link,
1027 $_SERVER["PHP_AUTH_USER"], $_SERVER["PHP_AUTH_PW"]);
1028
1029 if (!$auth_result) {
1030 header('WWW-Authenticate: Basic realm="Tiny Tiny RSS RSSGen"');
1031 header('HTTP/1.0 401 Unauthorized');
1032 exit;
1033 }
1034 }
1035
1036 return true;
1037 }
1038
1039 function authenticate_user($link, $login, $password, $force_auth = false) {
1040
1041 if (!SINGLE_USER_MODE) {
1042
1043 $pwd_hash = 'SHA1:' . sha1($password);
1044
1045 if ($force_auth && defined('_DEBUG_USER_SWITCH')) {
1046 $query = "SELECT id,login,access_level
1047 FROM ttrss_users WHERE
1048 login = '$login'";
1049 } else {
1050 $query = "SELECT id,login,access_level
1051 FROM ttrss_users WHERE
1052 login = '$login' AND pwd_hash = '$pwd_hash'";
1053 }
1054
1055 $result = db_query($link, $query);
1056
1057 if (db_num_rows($result) == 1) {
1058 $_SESSION["uid"] = db_fetch_result($result, 0, "id");
1059 $_SESSION["name"] = db_fetch_result($result, 0, "login");
1060 $_SESSION["access_level"] = db_fetch_result($result, 0, "access_level");
1061
1062 db_query($link, "UPDATE ttrss_users SET last_login = NOW() WHERE id = " .
1063 $_SESSION["uid"]);
1064
1065 $user_theme = get_user_theme_path($link);
1066
1067 $_SESSION["theme"] = $user_theme;
1068 $_SESSION["ip_address"] = $_SERVER["REMOTE_ADDR"];
1069
1070 initialize_user_prefs($link, $_SESSION["uid"]);
1071
1072 return true;
1073 }
1074
1075 return false;
1076
1077 } else {
1078
1079 $_SESSION["uid"] = 1;
1080 $_SESSION["name"] = "admin";
1081
1082 $user_theme = get_user_theme_path($link);
1083
1084 $_SESSION["theme"] = $user_theme;
1085 $_SESSION["ip_address"] = $_SERVER["REMOTE_ADDR"];
1086
1087 initialize_user_prefs($link, $_SESSION["uid"]);
1088
1089 return true;
1090 }
1091 }
1092
1093 function make_password($length = 8) {
1094
1095 $password = "";
1096 $possible = "0123456789abcdfghjkmnpqrstvwxyzABCDFGHJKMNPQRSTVWXYZ";
1097
1098 $i = 0;
1099
1100 while ($i < $length) {
1101 $char = substr($possible, mt_rand(0, strlen($possible)-1), 1);
1102
1103 if (!strstr($password, $char)) {
1104 $password .= $char;
1105 $i++;
1106 }
1107 }
1108 return $password;
1109 }
1110
1111 // this is called after user is created to initialize default feeds, labels
1112 // or whatever else
1113
1114 // user preferences are checked on every login, not here
1115
1116 function initialize_user($link, $uid) {
1117
1118 db_query($link, "insert into ttrss_labels (owner_uid,sql_exp,description)
1119 values ('$uid','unread = true', 'Unread articles')");
1120
1121 db_query($link, "insert into ttrss_labels (owner_uid,sql_exp,description)
1122 values ('$uid','last_read is null and unread = false', 'Updated articles')");
1123
1124 db_query($link, "insert into ttrss_feeds (owner_uid,title,feed_url)
1125 values ('$uid', 'Tiny Tiny RSS: New Releases',
1126 'http://tt-rss.spb.ru/releases.rss')");
1127
1128 }
1129
1130 function logout_user() {
1131 session_destroy();
1132 if (isset($_COOKIE[session_name()])) {
1133 setcookie(session_name(), '', time()-42000, '/');
1134 }
1135 }
1136
1137 function get_script_urlpath() {
1138 return preg_replace('/\/[^\/]*$/', "", $_SERVER["REQUEST_URI"]);
1139 }
1140
1141 function get_login_redirect() {
1142 $server = $_SERVER["SERVER_NAME"];
1143
1144 if (ENABLE_LOGIN_SSL) {
1145 $protocol = "https";
1146 } else {
1147 $protocol = "http";
1148 }
1149
1150 $url_path = get_script_urlpath();
1151
1152 $redirect_uri = "$protocol://$server$url_path/login.php";
1153
1154 return $redirect_uri;
1155 }
1156
1157 function validate_session($link) {
1158 if (SESSION_CHECK_ADDRESS && $_SESSION["uid"]) {
1159 if ($_SESSION["ip_address"]) {
1160 if ($_SESSION["ip_address"] != $_SERVER["REMOTE_ADDR"]) {
1161 return false;
1162 }
1163 }
1164 }
1165 return true;
1166 }
1167
1168 function basic_nosid_redirect_check() {
1169 if (!SINGLE_USER_MODE) {
1170 if (!$_COOKIE[get_session_cookie_name()]) {
1171 $redirect_uri = get_login_redirect();
1172 $return_to = preg_replace('/.*?\//', '', $_SERVER["REQUEST_URI"]);
1173 header("Location: $redirect_uri?rt=$return_to");
1174 exit;
1175 }
1176 }
1177 }
1178
1179 function login_sequence($link) {
1180 if (!SINGLE_USER_MODE) {
1181
1182 if (defined('_DEBUG_USER_SWITCH') && $_SESSION["uid"]) {
1183 $swu = db_escape_string($_REQUEST["swu"]);
1184 if ($swu) {
1185 $_SESSION["prefs_cache"] = false;
1186 return authenticate_user($link, $swu, null, true);
1187 }
1188 }
1189
1190 if (!validate_session($link)) {
1191 logout_user();
1192 $redirect_uri = get_login_redirect();
1193 $return_to = preg_replace('/.*?\//', '', $_SERVER["REQUEST_URI"]);
1194 header("Location: $redirect_uri?rt=$return_to");
1195 exit;
1196 }
1197
1198 if (!USE_HTTP_AUTH) {
1199 if (!$_SESSION["uid"]) {
1200 $redirect_uri = get_login_redirect();
1201 $return_to = preg_replace('/.*?\//', '', $_SERVER["REQUEST_URI"]);
1202 header("Location: $redirect_uri?rt=$return_to");
1203 exit;
1204 }
1205 } else {
1206 if (!$_SESSION["uid"]) {
1207 if (!$_SERVER["PHP_AUTH_USER"]) {
1208
1209 header('WWW-Authenticate: Basic realm="Tiny Tiny RSS"');
1210 header('HTTP/1.0 401 Unauthorized');
1211 exit;
1212
1213 } else {
1214 $auth_result = authenticate_user($link,
1215 $_SERVER["PHP_AUTH_USER"], $_SERVER["PHP_AUTH_PW"]);
1216
1217 if (!$auth_result) {
1218 header('WWW-Authenticate: Basic realm="Tiny Tiny RSS"');
1219 header('HTTP/1.0 401 Unauthorized');
1220 exit;
1221 }
1222 }
1223 }
1224 }
1225 } else {
1226 return authenticate_user($link, "admin", null);
1227 }
1228 }
1229
1230 function truncate_string($str, $max_len) {
1231 if (mb_strlen($str, "utf-8") > $max_len - 3) {
1232 return mb_substr($str, 0, $max_len, "utf-8") . "...";
1233 } else {
1234 return $str;
1235 }
1236 }
1237
1238 function get_user_theme_path($link) {
1239 $result = db_query($link, "SELECT theme_path
1240 FROM
1241 ttrss_themes,ttrss_users
1242 WHERE ttrss_themes.id = theme_id AND ttrss_users.id = " . $_SESSION["uid"]);
1243 if (db_num_rows($result) != 0) {
1244 return db_fetch_result($result, 0, "theme_path");
1245 } else {
1246 return null;
1247 }
1248 }
1249
1250 function smart_date_time($timestamp) {
1251 if (date("Y.m.d", $timestamp) == date("Y.m.d")) {
1252 return date("G:i", $timestamp);
1253 } else if (date("Y", $timestamp) == date("Y")) {
1254 return date("M d, G:i", $timestamp);
1255 } else {
1256 return date("Y/m/d G:i", $timestamp);
1257 }
1258 }
1259
1260 function smart_date($timestamp) {
1261 if (date("Y.m.d", $timestamp) == date("Y.m.d")) {
1262 return "Today";
1263 } else if (date("Y", $timestamp) == date("Y")) {
1264 return date("D m", $timestamp);
1265 } else {
1266 return date("Y/m/d", $timestamp);
1267 }
1268 }
1269
1270 function sql_bool_to_string($s) {
1271 if ($s == "t" || $s == "1") {
1272 return "true";
1273 } else {
1274 return "false";
1275 }
1276 }
1277
1278 function sql_bool_to_bool($s) {
1279 if ($s == "t" || $s == "1") {
1280 return true;
1281 } else {
1282 return false;
1283 }
1284 }
1285
1286
1287 function toggleEvenOdd($a) {
1288 if ($a == "even")
1289 return "odd";
1290 else
1291 return "even";
1292 }
1293
1294 function sanity_check($link) {
1295
1296 error_reporting(0);
1297
1298 $error_code = 0;
1299 $result = db_query($link, "SELECT schema_version FROM ttrss_version");
1300 $schema_version = db_fetch_result($result, 0, "schema_version");
1301
1302 if ($schema_version != SCHEMA_VERSION) {
1303 $error_code = 5;
1304 }
1305
1306 if (DB_TYPE == "mysql") {
1307 $result = db_query($link, "SELECT true", false);
1308 if (db_num_rows($result) != 1) {
1309 $error_code = 10;
1310 }
1311 }
1312
1313 error_reporting (DEFAULT_ERROR_LEVEL);
1314
1315 if ($error_code != 0) {
1316 print_error_xml($error_code);
1317 return false;
1318 } else {
1319 return true;
1320 }
1321 }
1322
1323 function file_is_locked($filename) {
1324 error_reporting(0);
1325 $fp = fopen($filename, "r");
1326 error_reporting(DEFAULT_ERROR_LEVEL);
1327 if ($fp) {
1328 if (flock($fp, LOCK_EX | LOCK_NB)) {
1329 flock($fp, LOCK_UN);
1330 fclose($fp);
1331 return false;
1332 }
1333 fclose($fp);
1334 return true;
1335 }
1336 return false;
1337 }
1338
1339 function make_lockfile($filename) {
1340 $fp = fopen($filename, "w");
1341
1342 if (flock($fp, LOCK_EX | LOCK_NB)) {
1343 return $fp;
1344 } else {
1345 return false;
1346 }
1347 }
1348
1349 function sql_random_function() {
1350 if (DB_TYPE == "mysql") {
1351 return "RAND()";
1352 } else {
1353 return "RANDOM()";
1354 }
1355 }
1356
1357 function catchup_feed($link, $feed, $cat_view) {
1358
1359 if (preg_match("/^-?[0-9][0-9]*$/", $feed) != false) {
1360
1361 if ($cat_view) {
1362
1363 if ($feed > 0) {
1364 $cat_qpart = "cat_id = '$feed'";
1365 } else {
1366 $cat_qpart = "cat_id IS NULL";
1367 }
1368
1369 $tmp_result = db_query($link, "SELECT id
1370 FROM ttrss_feeds WHERE $cat_qpart AND owner_uid = " .
1371 $_SESSION["uid"]);
1372
1373 while ($tmp_line = db_fetch_assoc($tmp_result)) {
1374
1375 $tmp_feed = $tmp_line["id"];
1376
1377 db_query($link, "UPDATE ttrss_user_entries
1378 SET unread = false,last_read = NOW()
1379 WHERE feed_id = '$tmp_feed' AND owner_uid = " . $_SESSION["uid"]);
1380 }
1381
1382 } else if ($feed > 0) {
1383
1384 $tmp_result = db_query($link, "SELECT id
1385 FROM ttrss_feeds WHERE parent_feed = '$feed'
1386 ORDER BY cat_id,title");
1387
1388 $parent_ids = array();
1389
1390 if (db_num_rows($tmp_result) > 0) {
1391 while ($p = db_fetch_assoc($tmp_result)) {
1392 array_push($parent_ids, "feed_id = " . $p["id"]);
1393 }
1394
1395 $children_qpart = implode(" OR ", $parent_ids);
1396
1397 db_query($link, "UPDATE ttrss_user_entries
1398 SET unread = false,last_read = NOW()
1399 WHERE (feed_id = '$feed' OR $children_qpart)
1400 AND owner_uid = " . $_SESSION["uid"]);
1401
1402 } else {
1403 db_query($link, "UPDATE ttrss_user_entries
1404 SET unread = false,last_read = NOW()
1405 WHERE feed_id = '$feed' AND owner_uid = " . $_SESSION["uid"]);
1406 }
1407
1408 } else if ($feed < 0 && $feed > -10) { // special, like starred
1409
1410 if ($feed == -1) {
1411 db_query($link, "UPDATE ttrss_user_entries
1412 SET unread = false,last_read = NOW()
1413 WHERE marked = true AND owner_uid = ".$_SESSION["uid"]);
1414 }
1415
1416 } else if ($feed < -10) { // label
1417
1418 // TODO make this more efficient
1419
1420 $label_id = -$feed - 11;
1421
1422 $tmp_result = db_query($link, "SELECT sql_exp FROM ttrss_labels
1423 WHERE id = '$label_id'");
1424
1425 if ($tmp_result) {
1426 $sql_exp = db_fetch_result($tmp_result, 0, "sql_exp");
1427
1428 db_query($link, "BEGIN");
1429
1430 $tmp2_result = db_query($link,
1431 "SELECT
1432 int_id
1433 FROM
1434 ttrss_user_entries,ttrss_entries,ttrss_feeds
1435 WHERE
1436 ref_id = ttrss_entries.id AND
1437 ttrss_user_entries.feed_id = ttrss_feeds.id AND
1438 $sql_exp AND
1439 ttrss_user_entries.owner_uid = " . $_SESSION["uid"]);
1440
1441 while ($tmp_line = db_fetch_assoc($tmp2_result)) {
1442 db_query($link, "UPDATE
1443 ttrss_user_entries
1444 SET
1445 unread = false, last_read = NOW()
1446 WHERE
1447 int_id = " . $tmp_line["int_id"]);
1448 }
1449
1450 db_query($link, "COMMIT");
1451
1452 /* db_query($link, "UPDATE ttrss_user_entries,ttrss_entries
1453 SET unread = false,last_read = NOW()
1454 WHERE $sql_exp
1455 AND ref_id = id
1456 AND owner_uid = ".$_SESSION["uid"]); */
1457 }
1458 }
1459 } else { // tag
1460 db_query($link, "BEGIN");
1461
1462 $tag_name = db_escape_string($feed);
1463
1464 $result = db_query($link, "SELECT post_int_id FROM ttrss_tags
1465 WHERE tag_name = '$tag_name' AND owner_uid = " . $_SESSION["uid"]);
1466
1467 while ($line = db_fetch_assoc($result)) {
1468 db_query($link, "UPDATE ttrss_user_entries SET
1469 unread = false, last_read = NOW()
1470 WHERE int_id = " . $line["post_int_id"]);
1471 }
1472 db_query($link, "COMMIT");
1473 }
1474 }
1475
1476 function update_generic_feed($link, $feed, $cat_view) {
1477 if ($cat_view) {
1478
1479 if ($feed > 0) {
1480 $cat_qpart = "cat_id = '$feed'";
1481 } else {
1482 $cat_qpart = "cat_id IS NULL";
1483 }
1484
1485 $tmp_result = db_query($link, "SELECT feed_url FROM ttrss_feeds
1486 WHERE $cat_qpart AND owner_uid = " . $_SESSION["uid"]);
1487
1488 while ($tmp_line = db_fetch_assoc($tmp_result)) {
1489 $feed_url = $tmp_line["feed_url"];
1490 update_rss_feed($link, $feed_url, $feed, ENABLE_UPDATE_DAEMON);
1491 }
1492
1493 } else {
1494 $tmp_result = db_query($link, "SELECT feed_url FROM ttrss_feeds
1495 WHERE id = '$feed'");
1496 $feed_url = db_fetch_result($tmp_result, 0, "feed_url");
1497 update_rss_feed($link, $feed_url, $feed, ENABLE_UPDATE_DAEMON);
1498 }
1499 }
1500
1501 function getAllCounters($link, $omode = "tflc") {
1502 /* getLabelCounters($link);
1503 getFeedCounters($link);
1504 getTagCounters($link);
1505 getGlobalCounters($link);
1506 if (get_pref($link, 'ENABLE_FEED_CATS')) {
1507 getCategoryCounters($link);
1508 } */
1509
1510 if (!$omode) $omode = "tflc";
1511
1512 getGlobalCounters($link);
1513
1514 if (strchr($omode, "l")) getLabelCounters($link);
1515 if (strchr($omode, "f")) getFeedCounters($link);
1516 if (strchr($omode, "t")) getTagCounters($link);
1517 if (strchr($omode, "c")) {
1518 if (get_pref($link, 'ENABLE_FEED_CATS')) {
1519 getCategoryCounters($link);
1520 }
1521 }
1522 }
1523
1524 function getCategoryCounters($link) {
1525 $result = db_query($link, "SELECT cat_id,SUM((SELECT COUNT(int_id)
1526 FROM ttrss_user_entries WHERE feed_id = ttrss_feeds.id
1527 AND unread = true)) AS unread FROM ttrss_feeds
1528 WHERE
1529 hidden = false AND owner_uid = ".$_SESSION["uid"]." GROUP BY cat_id");
1530
1531 while ($line = db_fetch_assoc($result)) {
1532 $line["cat_id"] = sprintf("%d", $line["cat_id"]);
1533 print "<counter type=\"category\" id=\"".$line["cat_id"]."\" counter=\"".
1534 $line["unread"]."\"/>";
1535 }
1536 }
1537
1538 function getCategoryUnread($link, $cat) {
1539
1540 if ($cat != 0) {
1541 $cat_query = "cat_id = '$cat'";
1542 } else {
1543 $cat_query = "cat_id IS NULL";
1544 }
1545
1546 $result = db_query($link, "SELECT id FROM ttrss_feeds WHERE $cat_query
1547 AND hidden = false
1548 AND owner_uid = " . $_SESSION["uid"]);
1549
1550 $cat_feeds = array();
1551 while ($line = db_fetch_assoc($result)) {
1552 array_push($cat_feeds, "feed_id = " . $line["id"]);
1553 }
1554
1555 if (count($cat_feeds) == 0) return 0;
1556
1557 $match_part = implode(" OR ", $cat_feeds);
1558
1559 $result = db_query($link, "SELECT COUNT(int_id) AS unread
1560 FROM ttrss_user_entries
1561 WHERE unread = true AND ($match_part) AND owner_uid = " . $_SESSION["uid"]);
1562
1563 $unread = 0;
1564
1565 # this needs to be rewritten
1566 while ($line = db_fetch_assoc($result)) {
1567 $unread += $line["unread"];
1568 }
1569
1570 return $unread;
1571
1572 }
1573
1574 function getFeedUnread($link, $feed, $is_cat = false) {
1575 $n_feed = sprintf("%d", $feed);
1576
1577 if ($is_cat) {
1578 return getCategoryUnread($link, $n_feed);
1579 } else if ($n_feed == -1) {
1580 $match_part = "marked = true";
1581 } else if ($n_feed > 0) {
1582
1583 $result = db_query($link, "SELECT id FROM ttrss_feeds
1584 WHERE parent_feed = '$n_feed'
1585 AND hidden = false
1586 AND owner_uid = " . $_SESSION["uid"]);
1587
1588 if (db_num_rows($result) > 0) {
1589
1590 $linked_feeds = array();
1591 while ($line = db_fetch_assoc($result)) {
1592 array_push($linked_feeds, "feed_id = " . $line["id"]);
1593 }
1594
1595 array_push($linked_feeds, "feed_id = $n_feed");
1596
1597 $match_part = implode(" OR ", $linked_feeds);
1598
1599 $result = db_query($link, "SELECT COUNT(int_id) AS unread
1600 FROM ttrss_user_entries
1601 WHERE unread = true AND ($match_part)
1602 AND owner_uid = " . $_SESSION["uid"]);
1603
1604 $unread = 0;
1605
1606 # this needs to be rewritten
1607 while ($line = db_fetch_assoc($result)) {
1608 $unread += $line["unread"];
1609 }
1610
1611 return $unread;
1612
1613 } else {
1614 $match_part = "feed_id = '$n_feed'";
1615 }
1616 } else if ($feed < -10) {
1617
1618 $label_id = -$feed - 11;
1619
1620 $result = db_query($link, "SELECT sql_exp FROM ttrss_labels WHERE
1621 id = '$label_id' AND owner_uid = " . $_SESSION["uid"]);
1622
1623 $match_part = db_fetch_result($result, 0, "sql_exp");
1624 }
1625
1626 if ($match_part) {
1627
1628 $result = db_query($link, "SELECT count(int_id) AS unread
1629 FROM ttrss_user_entries,ttrss_feeds,ttrss_entries WHERE
1630 ttrss_user_entries.feed_id = ttrss_feeds.id AND
1631 ttrss_user_entries.ref_id = ttrss_entries.id AND
1632 ttrss_feeds.hidden = false AND
1633 unread = true AND ($match_part) AND ttrss_user_entries.owner_uid = " . $_SESSION["uid"]);
1634
1635 } else {
1636
1637 $result = db_query($link, "SELECT COUNT(post_int_id) AS unread
1638 FROM ttrss_tags,ttrss_user_entries
1639 WHERE tag_name = '$feed' AND post_int_id = int_id AND unread = true AND
1640 ttrss_tags.owner_uid = " . $_SESSION["uid"]);
1641 }
1642
1643 $unread = db_fetch_result($result, 0, "unread");
1644
1645 return $unread;
1646 }
1647
1648 /* FIXME this needs reworking */
1649
1650 function getGlobalUnread($link, $user_id = false) {
1651
1652 if (!$user_id) {
1653 $user_id = $_SESSION["uid"];
1654 }
1655
1656 $result = db_query($link, "SELECT count(ttrss_entries.id) as c_id FROM ttrss_entries,ttrss_user_entries,ttrss_feeds
1657 WHERE unread = true AND
1658 ttrss_user_entries.feed_id = ttrss_feeds.id AND
1659 ttrss_user_entries.ref_id = ttrss_entries.id AND
1660 hidden = false AND
1661 ttrss_user_entries.owner_uid = '$user_id'");
1662 $c_id = db_fetch_result($result, 0, "c_id");
1663 return $c_id;
1664 }
1665
1666 function getGlobalCounters($link, $global_unread = -1) {
1667 if ($global_unread == -1) {
1668 $global_unread = getGlobalUnread($link);
1669 }
1670 print "<counter type=\"global\" id='global-unread'
1671 counter='$global_unread'/>";
1672
1673 $result = db_query($link, "SELECT COUNT(id) AS fn FROM
1674 ttrss_feeds WHERE owner_uid = " . $_SESSION["uid"]);
1675
1676 $subscribed_feeds = db_fetch_result($result, 0, "fn");
1677
1678 print "<counter type=\"global\" id='subscribed-feeds'
1679 counter='$subscribed_feeds'/>";
1680
1681 }
1682
1683 function getTagCounters($link, $smart_mode = SMART_RPC_COUNTERS) {
1684
1685 if ($smart_mode) {
1686 if (!$_SESSION["tctr_last_value"]) {
1687 $_SESSION["tctr_last_value"] = array();
1688 }
1689 }
1690
1691 $old_counters = $_SESSION["tctr_last_value"];
1692
1693 $tctrs_modified = false;
1694
1695 /* $result = db_query($link, "SELECT tag_name,count(ttrss_entries.id) AS count
1696 FROM ttrss_tags,ttrss_entries,ttrss_user_entries WHERE
1697 ttrss_user_entries.ref_id = ttrss_entries.id AND
1698 ttrss_tags.owner_uid = ".$_SESSION["uid"]." AND
1699 post_int_id = ttrss_user_entries.int_id AND unread = true GROUP BY tag_name
1700 UNION
1701 select tag_name,0 as count FROM ttrss_tags
1702 WHERE ttrss_tags.owner_uid = ".$_SESSION["uid"]); */
1703
1704 $result = db_query($link, "SELECT tag_name,SUM((SELECT COUNT(int_id)
1705 FROM ttrss_user_entries WHERE int_id = post_int_id
1706 AND unread = true)) AS count FROM ttrss_tags
1707 WHERE owner_uid = 2 GROUP BY tag_name ORDER BY tag_name");
1708
1709 $tags = array();
1710
1711 while ($line = db_fetch_assoc($result)) {
1712 $tags[$line["tag_name"]] += $line["count"];
1713 }
1714
1715 foreach (array_keys($tags) as $tag) {
1716 $unread = $tags[$tag];
1717
1718 $tag = htmlspecialchars($tag);
1719
1720 if (!$smart_mode || $old_counters[$tag] != $unread) {
1721 $old_counters[$tag] = $unread;
1722 $tctrs_modified = true;
1723 print "<counter type=\"tag\" id=\"$tag\" counter=\"$unread\"/>";
1724 }
1725
1726 }
1727
1728 if ($smart_mode && $tctrs_modified) {
1729 $_SESSION["tctr_last_value"] = $old_counters;
1730 }
1731
1732 }
1733
1734 function getLabelCounters($link, $smart_mode = SMART_RPC_COUNTERS, $ret_mode = false) {
1735
1736 if ($smart_mode) {
1737 if (!$_SESSION["lctr_last_value"]) {
1738 $_SESSION["lctr_last_value"] = array();
1739 }
1740 }
1741
1742 $ret_arr = array();
1743
1744 $old_counters = $_SESSION["lctr_last_value"];
1745 $lctrs_modified = false;
1746
1747 $result = db_query($link, "SELECT count(ttrss_entries.id) as count FROM ttrss_entries,ttrss_user_entries,ttrss_feeds
1748 WHERE marked = true AND ttrss_user_entries.ref_id = ttrss_entries.id AND
1749 ttrss_user_entries.feed_id = ttrss_feeds.id AND
1750 unread = true AND ttrss_user_entries.owner_uid = ".$_SESSION["uid"]);
1751
1752 $count = db_fetch_result($result, 0, "count");
1753
1754 if (!$ret_mode) {
1755 print "<counter type=\"label\" id=\"-1\" counter=\"$count\"/>";
1756 } else {
1757 $ret_arr["-1"]["counter"] = $count;
1758 $ret_arr["-1"]["description"] = "Starred";
1759 }
1760
1761 $result = db_query($link, "SELECT owner_uid,id,sql_exp,description FROM
1762 ttrss_labels WHERE owner_uid = ".$_SESSION["uid"]." ORDER by description");
1763
1764 while ($line = db_fetch_assoc($result)) {
1765
1766 $id = -$line["id"] - 11;
1767
1768 $label_name = $line["description"];
1769
1770 error_reporting (0);
1771
1772 $tmp_result = db_query($link, "SELECT count(ttrss_entries.id) as count FROM ttrss_user_entries,ttrss_entries,ttrss_feeds
1773 WHERE (" . $line["sql_exp"] . ") AND unread = true AND
1774 ttrss_feeds.hidden = false AND
1775 ttrss_user_entries.feed_id = ttrss_feeds.id AND
1776 ttrss_user_entries.ref_id = ttrss_entries.id AND
1777 ttrss_user_entries.owner_uid = ".$_SESSION["uid"]);
1778
1779 $count = db_fetch_result($tmp_result, 0, "count");
1780
1781 if (!$smart_mode || $old_counters[$id] != $count) {
1782 $old_counters[$id] = $count;
1783 $lctrs_modified = true;
1784 if (!$ret_mode) {
1785 print "<counter type=\"label\" id=\"$id\" counter=\"$count\"/>";
1786 } else {
1787 $ret_arr[$id]["counter"] = $count;
1788 $ret_arr[$id]["description"] = $label_name;
1789 }
1790 }
1791
1792 error_reporting (DEFAULT_ERROR_LEVEL);
1793 }
1794
1795 if ($smart_mode && $lctrs_modified) {
1796 $_SESSION["lctr_last_value"] = $old_counters;
1797 }
1798
1799 return $ret_arr;
1800 }
1801
1802 /* function getFeedCounter($link, $id) {
1803
1804 $result = db_query($link, "SELECT
1805 count(id) as count,last_error
1806 FROM ttrss_entries,ttrss_user_entries,ttrss_feeds
1807 WHERE feed_id = '$id' AND unread = true
1808 AND ttrss_user_entries.feed_id = ttrss_feeds.id
1809 AND ttrss_user_entries.ref_id = ttrss_entries.id");
1810
1811 $count = db_fetch_result($result, 0, "count");
1812 $last_error = htmlspecialchars(db_fetch_result($result, 0, "last_error"));
1813
1814 print "<counter type=\"feed\" id=\"$id\" counter=\"$count\" error=\"$last_error\"/>";
1815 } */
1816
1817 function getFeedCounters($link, $smart_mode = SMART_RPC_COUNTERS) {
1818
1819 if ($smart_mode) {
1820 if (!$_SESSION["fctr_last_value"]) {
1821 $_SESSION["fctr_last_value"] = array();
1822 }
1823 }
1824
1825 $old_counters = $_SESSION["fctr_last_value"];
1826
1827 $result = db_query($link, "SELECT id,last_error,parent_feed,
1828 SUBSTRING(last_updated,1,19) AS last_updated,
1829 (SELECT count(id)
1830 FROM ttrss_entries,ttrss_user_entries
1831 WHERE feed_id = ttrss_feeds.id AND
1832 ttrss_user_entries.ref_id = ttrss_entries.id
1833 AND unread = true AND owner_uid = ".$_SESSION["uid"].") as count
1834 FROM ttrss_feeds WHERE owner_uid = ".$_SESSION["uid"] . "
1835 AND parent_feed IS NULL");
1836
1837 $fctrs_modified = false;
1838
1839 $short_date = get_pref($link, 'SHORT_DATE_FORMAT');
1840
1841 while ($line = db_fetch_assoc($result)) {
1842
1843 $id = $line["id"];
1844 $count = $line["count"];
1845 $last_error = htmlspecialchars($line["last_error"]);
1846
1847 if (get_pref($link, 'HEADLINES_SMART_DATE')) {
1848 $last_updated = smart_date_time(strtotime($line["last_updated"]));
1849 } else {
1850 $last_updated = date($short_date, strtotime($line["last_updated"]));
1851 }
1852
1853 $has_img = is_file(ICONS_DIR . "/$id.ico");
1854
1855 $tmp_result = db_query($link,
1856 "SELECT id,COUNT(unread) AS unread
1857 FROM ttrss_feeds LEFT JOIN ttrss_user_entries
1858 ON (ttrss_feeds.id = ttrss_user_entries.feed_id)
1859 WHERE parent_feed = '$id' AND unread = true GROUP BY ttrss_feeds.id");
1860
1861 if (db_num_rows($tmp_result) > 0) {
1862 while ($l = db_fetch_assoc($tmp_result)) {
1863 $count += $l["unread"];
1864 }
1865 }
1866
1867 if (!$smart_mode || $old_counters[$id] != $count) {
1868 $old_counters[$id] = $count;
1869 $fctrs_modified = true;
1870
1871 if ($last_error) {
1872 $error_part = "error=\"$last_error\"";
1873 } else {
1874 $error_part = "";
1875 }
1876
1877 if ($has_img) {
1878 $has_img_part = "hi=\"$has_img\"";
1879 } else {
1880 $has_img_part = "";
1881 }
1882
1883 print "<counter type=\"feed\" id=\"$id\" counter=\"$count\" $has_img_part $error_part updated=\"$last_updated\"/>";
1884 }
1885 }
1886
1887 if ($smart_mode && $fctrs_modified) {
1888 $_SESSION["fctr_last_value"] = $old_counters;
1889 }
1890 }
1891
1892 function get_script_dt_add() {
1893 if (strpos(VERSION, "99") === false) {
1894 return VERSION;
1895 } else {
1896 return time();
1897 }
1898 }
1899
1900 function get_pgsql_version($link) {
1901 $result = db_query($link, "SELECT version() AS version");
1902 $version = split(" ", db_fetch_result($result, 0, "version"));
1903 return $version[1];
1904 }
1905
1906 function print_error_xml($code, $add_msg = "") {
1907 global $ERRORS;
1908
1909 $error_msg = $ERRORS[$code];
1910
1911 if ($add_msg) {
1912 $error_msg = "$error_msg; $add_msg";
1913 }
1914
1915 print "<rpc-reply>";
1916 print "<error error-code=\"$code\" error-msg=\"$error_msg\"/>";
1917 print "</rpc-reply>";
1918 }
1919
1920 function subscribe_to_feed($link, $feed_link, $cat_id = 0) {
1921
1922 $feed_link = trim(preg_replace("/^feed:/", "", $feed_link));
1923
1924 if ($feed_link == "") return;
1925
1926 if ($cat_id == "0" || !$cat_id) {
1927 $cat_qpart = "NULL";
1928 } else {
1929 $cat_qpart = "'$cat_id'";
1930 }
1931
1932 $result = db_query($link,
1933 "SELECT id FROM ttrss_feeds
1934 WHERE feed_url = '$feed_link' AND owner_uid = ".$_SESSION["uid"]);
1935
1936 if (db_num_rows($result) == 0) {
1937
1938 $result = db_query($link,
1939 "INSERT INTO ttrss_feeds (owner_uid,feed_url,title,cat_id)
1940 VALUES ('".$_SESSION["uid"]."', '$feed_link',
1941 '[Unknown]', $cat_qpart)");
1942
1943 $result = db_query($link,
1944 "SELECT id FROM ttrss_feeds WHERE feed_url = '$feed_link'
1945 AND owner_uid = " . $_SESSION["uid"]);
1946
1947 $feed_id = db_fetch_result($result, 0, "id");
1948
1949 if ($feed_id) {
1950 update_rss_feed($link, $feed_link, $feed_id, true);
1951 }
1952
1953 return true;
1954 } else {
1955 return false;
1956 }
1957 }
1958
1959 function print_feed_select($link, $id, $default_id = "",
1960 $attributes = "", $include_all_feeds = true) {
1961
1962 print "<select id=\"$id\" name=\"$id\" $attributes>";
1963 if ($include_all_feeds) {
1964 print "<option value=\"0\">All feeds</option>";
1965 }
1966
1967 $result = db_query($link, "SELECT id,title FROM ttrss_feeds
1968 WHERE owner_uid = ".$_SESSION["uid"]." ORDER BY title");
1969
1970 if (db_num_rows($result) > 0 && $include_all_feeds) {
1971 print "<option disabled>--------</option>";
1972 }
1973
1974 while ($line = db_fetch_assoc($result)) {
1975 if ($line["id"] == $default_id) {
1976 $is_selected = "selected";
1977 } else {
1978 $is_selected = "";
1979 }
1980 printf("<option $is_selected value='%d'>%s</option>",
1981 $line["id"], htmlspecialchars(db_unescape_string($line["title"])));
1982 }
1983
1984 print "</select>";
1985 }
1986
1987 function print_feed_cat_select($link, $id, $default_id = "",
1988 $attributes = "", $include_all_cats = true) {
1989
1990 print "<select id=\"$id\" name=\"$id\" $attributes>";
1991
1992 if ($include_all_cats) {
1993 print "<option value=\"0\">Uncategorized</option>";
1994 }
1995
1996 $result = db_query($link, "SELECT id,title FROM ttrss_feed_categories
1997 WHERE owner_uid = ".$_SESSION["uid"]." ORDER BY title");
1998
1999 if (db_num_rows($result) > 0 && $include_all_cats) {
2000 print "<option disabled>--------</option>";
2001 }
2002
2003 while ($line = db_fetch_assoc($result)) {
2004 if ($line["id"] == $default_id) {
2005 $is_selected = "selected";
2006 } else {
2007 $is_selected = "";
2008 }
2009 printf("<option $is_selected value='%d'>%s</option>",
2010 $line["id"], htmlspecialchars(db_unescape_string($line["title"])));
2011 }
2012
2013 print "</select>";
2014 }
2015
2016 function checkbox_to_sql_bool($val) {
2017 return ($val == "on") ? "true" : "false";
2018 }
2019
2020 function getFeedCatTitle($link, $id) {
2021 if ($id == -1) {
2022 return "Special";
2023 } else if ($id < -10) {
2024 return "Labels";
2025 } else if ($id > 0) {
2026 $result = db_query($link, "SELECT ttrss_feed_categories.title
2027 FROM ttrss_feeds, ttrss_feed_categories WHERE ttrss_feeds.id = '$id' AND
2028 cat_id = ttrss_feed_categories.id");
2029 if (db_num_rows($result) == 1) {
2030 return db_fetch_result($result, 0, "title");
2031 } else {
2032 return "Uncategorized";
2033 }
2034 } else {
2035 return "getFeedCatTitle($id) failed";
2036 }
2037
2038 }
2039
2040 function getFeedTitle($link, $id) {
2041 if ($id == -1) {
2042 return "Starred articles";
2043 } else if ($id < -10) {
2044 $label_id = -10 - $id;
2045 $result = db_query($link, "SELECT description FROM ttrss_labels WHERE id = '$label_id'");
2046 if (db_num_rows($result) == 1) {
2047 return db_fetch_result($result, 0, "description");
2048 } else {
2049 return "Unknown label ($label_id)";
2050 }
2051
2052 } else if ($id > 0) {
2053 $result = db_query($link, "SELECT title FROM ttrss_feeds WHERE id = '$id'");
2054 if (db_num_rows($result) == 1) {
2055 return db_fetch_result($result, 0, "title");
2056 } else {
2057 return "Unknown feed ($id)";
2058 }
2059 } else {
2060 return "getFeedTitle($id) failed";
2061 }
2062
2063 }
2064
2065 function get_session_cookie_name() {
2066 return ((!defined('TTRSS_SESSION_NAME')) ? "ttrss_sid" : TTRSS_SESSION_NAME);
2067 }
2068
2069 function print_init_params($link) {
2070 print "<init-params>";
2071 if ($_SESSION["stored-params"]) {
2072 foreach (array_keys($_SESSION["stored-params"]) as $key) {
2073 if ($key) {
2074 $value = htmlspecialchars($_SESSION["stored-params"][$key]);
2075 print "<param key=\"$key\" value=\"$value\"/>";
2076 }
2077 }
2078 }
2079
2080 print "<param key=\"daemon_enabled\" value=\"" . ENABLE_UPDATE_DAEMON . "\"/>";
2081 print "<param key=\"feeds_frame_refresh\" value=\"" . FEEDS_FRAME_REFRESH . "\"/>";
2082 print "<param key=\"daemon_refresh_only\" value=\"" . DAEMON_REFRESH_ONLY . "\"/>";
2083
2084 print "<param key=\"on_catchup_show_next_feed\" value=\"" .
2085 get_pref($link, "ON_CATCHUP_SHOW_NEXT_FEED") . "\"/>";
2086
2087 print "<param key=\"hide_read_feeds\" value=\"" .
2088 sprintf("%d", get_pref($link, "HIDE_READ_FEEDS")) . "\"/>";
2089
2090 print "<param key=\"feeds_sort_by_unread\" value=\"" .
2091 sprintf("%d", get_pref($link, "FEEDS_SORT_BY_UNREAD")) . "\"/>";
2092
2093 print "<param key=\"confirm_feed_catchup\" value=\"" .
2094 sprintf("%d", get_pref($link, "CONFIRM_FEED_CATCHUP")) . "\"/>";
2095
2096 print "</init-params>";
2097 }
2098
2099 function print_runtime_info($link) {
2100 print "<runtime-info>";
2101 if (ENABLE_UPDATE_DAEMON) {
2102 print "<param key=\"daemon_is_running\" value=\"".
2103 sprintf("%d", file_is_locked("update_daemon.lock")) . "\"/>";
2104 }
2105 print "</runtime-info>";
2106 }
2107
2108 function getSearchSql($search, $match_on) {
2109
2110 $search_query_part = "";
2111
2112 $keywords = split(" ", $search);
2113 $query_keywords = array();
2114
2115 if ($match_on == "both") {
2116
2117 foreach ($keywords as $k) {
2118 array_push($query_keywords, "(UPPER(ttrss_entries.title) LIKE UPPER('%$k%')
2119 OR UPPER(ttrss_entries.content) LIKE UPPER('%$k%'))");
2120 }
2121
2122 $search_query_part = implode("AND", $query_keywords) . " AND ";
2123
2124 } else if ($match_on == "title") {
2125
2126 foreach ($keywords as $k) {
2127 array_push($query_keywords, "(UPPER(ttrss_entries.title) LIKE UPPER('%$k%'))");
2128 }
2129
2130 $search_query_part = implode("AND", $query_keywords) . " AND ";
2131
2132 } else if ($match_on == "content") {
2133
2134 foreach ($keywords as $k) {
2135 array_push($query_keywords, "(UPPER(ttrss_entries.content) LIKE UPPER('%$k%'))");
2136 }
2137 }
2138
2139 $search_query_part = implode("AND", $query_keywords);
2140
2141 return $search_query_part;
2142 }
2143
2144 function queryFeedHeadlines($link, $feed, $limit, $view_mode, $cat_view, $search, $search_mode, $match_on, $override_order = false) {
2145 if ($search) {
2146
2147 $search_query_part = getSearchSql($search, $match_on);
2148 $search_query_part .= " AND ";
2149
2150 } else {
2151 $search_query_part = "";
2152 }
2153
2154 $view_query_part = "";
2155
2156 if ($view_mode == "adaptive") {
2157 if ($search) {
2158 $view_query_part = " ";
2159 } else if ($feed != -1) {
2160 $unread = getFeedUnread($link, $feed, $cat_view);
2161 if ($unread > 0) {
2162 $view_query_part = " unread = true AND ";
2163 }
2164 }
2165 }
2166
2167 if ($view_mode == "marked") {
2168 $view_query_part = " marked = true AND ";
2169 }
2170
2171 if ($view_mode == "unread") {
2172 $view_query_part = " unread = true AND ";
2173 }
2174
2175 if ($limit > 0) {
2176 $limit_query_part = "LIMIT " . $limit;
2177 }
2178
2179 $vfeed_query_part = "";
2180
2181 // override query strategy and enable feed display when searching globally
2182 if ($search && $search_mode == "all_feeds") {
2183 $query_strategy_part = "ttrss_entries.id > 0";
2184 $vfeed_query_part = "ttrss_feeds.title AS feed_title,";
2185 } else if (preg_match("/^-?[0-9][0-9]*$/", $feed) == false) {
2186 $query_strategy_part = "ttrss_entries.id > 0";
2187 $vfeed_query_part = "(SELECT title FROM ttrss_feeds WHERE
2188 id = feed_id) as feed_title,";
2189 } else if ($feed >= 0 && $search && $search_mode == "this_cat") {
2190
2191 $vfeed_query_part = "ttrss_feeds.title AS feed_title,";
2192
2193 $tmp_result = false;
2194
2195 if ($cat_view) {
2196 $tmp_result = db_query($link, "SELECT id
2197 FROM ttrss_feeds WHERE cat_id = '$feed'");
2198 } else {
2199 $tmp_result = db_query($link, "SELECT id
2200 FROM ttrss_feeds WHERE cat_id = (SELECT cat_id FROM ttrss_feeds
2201 WHERE id = '$feed') AND id != '$feed'");
2202 }
2203
2204 $cat_siblings = array();
2205
2206 if (db_num_rows($tmp_result) > 0) {
2207 while ($p = db_fetch_assoc($tmp_result)) {
2208 array_push($cat_siblings, "feed_id = " . $p["id"]);
2209 }
2210
2211 $query_strategy_part = sprintf("(feed_id = %d OR %s)",
2212 $feed, implode(" OR ", $cat_siblings));
2213
2214 } else {
2215 $query_strategy_part = "ttrss_entries.id > 0";
2216 }
2217
2218 } else if ($feed >= 0) {
2219
2220 if ($cat_view) {
2221
2222 if ($feed > 0) {
2223 $query_strategy_part = "cat_id = '$feed'";
2224 } else {
2225 $query_strategy_part = "cat_id IS NULL";
2226 }
2227
2228 $vfeed_query_part = "ttrss_feeds.title AS feed_title,";
2229
2230 } else {
2231 $tmp_result = db_query($link, "SELECT id
2232 FROM ttrss_feeds WHERE parent_feed = '$feed'
2233 ORDER BY cat_id,title");
2234
2235 $parent_ids = array();
2236
2237 if (db_num_rows($tmp_result) > 0) {
2238 while ($p = db_fetch_assoc($tmp_result)) {
2239 array_push($parent_ids, "feed_id = " . $p["id"]);
2240 }
2241
2242 $query_strategy_part = sprintf("(feed_id = %d OR %s)",
2243 $feed, implode(" OR ", $parent_ids));
2244
2245 $vfeed_query_part = "ttrss_feeds.title AS feed_title,";
2246 } else {
2247 $query_strategy_part = "feed_id = '$feed'";
2248 }
2249 }
2250 } else if ($feed == -1) { // starred virtual feed
2251 $query_strategy_part = "marked = true";
2252 $vfeed_query_part = "ttrss_feeds.title AS feed_title,";
2253 } else if ($feed <= -10) { // labels
2254 $label_id = -$feed - 11;
2255
2256 $tmp_result = db_query($link, "SELECT sql_exp FROM ttrss_labels
2257 WHERE id = '$label_id'");
2258
2259 $query_strategy_part = db_fetch_result($tmp_result, 0, "sql_exp");
2260
2261 $vfeed_query_part = "ttrss_feeds.title AS feed_title,";
2262 } else {
2263 $query_strategy_part = "id > 0"; // dumb
2264 }
2265
2266 if (get_pref($link, 'REVERSE_HEADLINES')) {
2267 $order_by = "updated";
2268 } else {
2269 $order_by = "updated DESC";
2270 }
2271
2272 if ($override_order) {
2273 $order_by = $override_order;
2274 }
2275
2276 $feed_title = "";
2277
2278 if ($search && $search_mode == "all_feeds") {
2279 $feed_title = "Global search results ($search)";
2280 } else if ($search && preg_match('/^-?[0-9][0-9]*$/', $feed) == false) {
2281 $feed_title = "Tag search results ($search, $feed)";
2282 } else if (preg_match('/^-?[0-9][0-9]*$/', $feed) == false) {
2283 $feed_title = $feed;
2284 } else if (preg_match('/^-?[0-9][0-9]*$/', $feed) != false && $feed >= 0) {
2285
2286 if ($cat_view) {
2287
2288 if ($feed != 0) {
2289 $result = db_query($link, "SELECT title FROM ttrss_feed_categories
2290 WHERE id = '$feed' AND owner_uid = " . $_SESSION["uid"]);
2291 $feed_title = db_fetch_result($result, 0, "title");
2292 } else {
2293 $feed_title = "Uncategorized";
2294 }
2295
2296 if ($search) {
2297 $feed_title = "Category search results ($search, $feed_title)";
2298 }
2299
2300 } else {
2301
2302 $result = db_query($link, "SELECT title,site_url,last_error FROM ttrss_feeds
2303 WHERE id = '$feed' AND owner_uid = " . $_SESSION["uid"]);
2304
2305 $feed_title = db_fetch_result($result, 0, "title");
2306 $feed_site_url = db_fetch_result($result, 0, "site_url");
2307 $last_error = db_fetch_result($result, 0, "last_error");
2308
2309 if ($search) {
2310 $feed_title = "Feed search results ($search, $feed_title)";
2311 }
2312 }
2313
2314 } else if ($feed == -1) {
2315 $feed_title = "Starred articles";
2316 } else if ($feed < -10) {
2317 $label_id = -$feed - 11;
2318 $result = db_query($link, "SELECT description FROM ttrss_labels
2319 WHERE id = '$label_id'");
2320 $feed_title = db_fetch_result($result, 0, "description");
2321
2322 if ($search) {
2323 $feed_title = "Label search results ($search, $feed_title)";
2324 }
2325 } else {
2326 $feed_title = "?";
2327 }
2328
2329 $feed_title = db_unescape_string($feed_title);
2330
2331 if ($feed < -10) error_reporting (0);
2332
2333 if (preg_match("/^-?[0-9][0-9]*$/", $feed) != false) {
2334
2335 if ($feed >= 0) {
2336 $feed_kind = "Feeds";
2337 } else {
2338 $feed_kind = "Labels";
2339 }
2340
2341 $content_query_part = "content as content_preview,";
2342
2343 $query = "SELECT
2344 guid,
2345 ttrss_entries.id,ttrss_entries.title,
2346 SUBSTRING(updated,1,16) as updated,
2347 unread,feed_id,marked,link,last_read,
2348 SUBSTRING(last_read,1,19) as last_read_noms,
2349 $vfeed_query_part
2350 $content_query_part
2351 SUBSTRING(updated,1,19) as updated_noms,
2352 author
2353 FROM
2354 ttrss_entries,ttrss_user_entries,ttrss_feeds
2355 WHERE
2356 ttrss_feeds.hidden = false AND
2357 ttrss_user_entries.feed_id = ttrss_feeds.id AND
2358 ttrss_user_entries.ref_id = ttrss_entries.id AND
2359 ttrss_user_entries.owner_uid = '".$_SESSION["uid"]."' AND
2360 $search_query_part
2361 $view_query_part
2362 $query_strategy_part ORDER BY $order_by
2363 $limit_query_part";
2364
2365 $result = db_query($link, $query);
2366
2367 if ($_GET["debug"]) print $query;
2368
2369 } else {
2370 // browsing by tag
2371
2372 $feed_kind = "Tags";
2373
2374 $result = db_query($link, "SELECT
2375 guid,
2376 ttrss_entries.id as id,title,
2377 SUBSTRING(updated,1,16) as updated,
2378 unread,feed_id,
2379 marked,link,last_read,
2380 SUBSTRING(last_read,1,19) as last_read_noms,
2381 $vfeed_query_part
2382 $content_query_part
2383 SUBSTRING(updated,1,19) as updated_noms
2384 FROM
2385 ttrss_entries,ttrss_user_entries,ttrss_tags
2386 WHERE
2387 ref_id = ttrss_entries.id AND
2388 ttrss_user_entries.owner_uid = '".$_SESSION["uid"]."' AND
2389 post_int_id = int_id AND tag_name = '$feed' AND
2390 $view_query_part
2391 $search_query_part
2392 $query_strategy_part ORDER BY $order_by
2393 $limit_query_part");
2394 }
2395
2396 return array($result, $feed_title, $feed_site_url, $last_error);
2397
2398 }
2399
2400 function generate_syndicated_feed($link, $feed, $is_cat,
2401 $search, $search_mode, $match_on) {
2402
2403 $qfh_ret = queryFeedHeadlines($link, $feed,
2404 30, false, $is_cat, $search, $search_mode, $match_on, "updated DESC");
2405
2406 $result = $qfh_ret[0];
2407 $feed_title = htmlspecialchars($qfh_ret[1]);
2408 $feed_site_url = $qfh_ret[2];
2409 $last_error = $qfh_ret[3];
2410
2411 print "<rss version=\"2.0\">
2412 <channel>
2413 <title>$feed_title</title>
2414 <link>$feed_site_url</link>
2415 <generator>Tiny Tiny RSS v".VERSION."</generator>";
2416
2417 while ($line = db_fetch_assoc($result)) {
2418 print "<item>";
2419 print "<id>" . htmlspecialchars($line["guid"]) . "</id>";
2420 print "<link>" . htmlspecialchars($line["link"]) . "</link>";
2421
2422 $rfc822_date = date('r', strtotime($line["updated"]));
2423
2424 print "<pubDate>$rfc822_date</pubDate>";
2425
2426 print "<title>" .
2427 htmlspecialchars($line["title"]) . "</title>";
2428
2429 print "<description>" .
2430 htmlspecialchars($line["content_preview"]) . "</description>";
2431
2432 print "</item>";
2433 }
2434
2435 print "</channel></rss>";
2436
2437 }
2438
2439 function getCategoryTitle($link, $cat_id) {
2440
2441 $result = db_query($link, "SELECT title FROM ttrss_feed_categories WHERE
2442 id = '$cat_id'");
2443
2444 if (db_num_rows($result) == 1) {
2445 return db_fetch_result($result, 0, "title");
2446 } else {
2447 return "Uncategorized";
2448 }
2449 }
2450
2451 function sanitize_rss($str) {
2452 $res = $str;
2453
2454 $res = preg_replace('/<script.*?>/i',
2455 "<p class=\"scriptWarn\">Disabled script: ", $res);
2456
2457 $res = preg_replace('/<\/script.*?>/i', "</p>", $res);
2458
2459 /* $res = preg_replace('/<embed.*?>/i', "", $res);
2460
2461 $res = preg_replace('/<object.*?>.*?<\/object>/i',
2462 "<p class=\"objectWarn\">(Disabled html object
2463 - flash or other embedded content)</p>", $res); */
2464
2465 return $res;
2466 }
2467
2468 function send_headlines_digests($link, $limit = 100) {
2469
2470 if (!DIGEST_ENABLE) return false;
2471
2472 $user_limit = DIGEST_EMAIL_LIMIT;
2473 $days = 1;
2474
2475 print "Sending digests, batch of max $user_limit users, days = $days, headline limit = $limit\n\n";
2476
2477 if (DB_TYPE == "pgsql") {
2478 $interval_query = "last_digest_sent < NOW() - INTERVAL '$days days'";
2479 } else if (DB_TYPE == "mysql") {
2480 $interval_query = "last_digest_sent < DATE_SUB(NOW(), INTERVAL $days DAY)";
2481 }
2482
2483 $result = db_query($link, "SELECT id,email FROM ttrss_users
2484 WHERE email != '' AND (last_digest_sent IS NULL OR $interval_query)");
2485
2486 while ($line = db_fetch_assoc($result)) {
2487 if (get_pref($link, 'DIGEST_ENABLE', $line['id'], false)) {
2488 print "Sending digest for UID:" . $line['id'] . " - " . $line["email"] . " ... ";
2489
2490 $tuple = prepare_headlines_digest($link, $line["id"], $days, $limit);
2491 $digest = $tuple[0];
2492 $headlines_count = $tuple[1];
2493
2494 if ($headlines_count > 0) {
2495 $rc = mail($line["login"] . " <" . $line["email"] . ">",
2496 "[tt-rss] New headlines for last 24 hours", $digest,
2497 "From: " . MAIL_FROM . "\n".
2498 "Content-Type: text/plain; charset=\"utf-8\"\n".
2499 "Content-Transfer-Encoding: 8bit\n");
2500 print "RC=$rc\n";
2501 db_query($link, "UPDATE ttrss_users SET last_digest_sent = NOW()
2502 WHERE id = " . $line["id"]);
2503 } else {
2504 print "No headlines\n";
2505 }
2506 }
2507 }
2508
2509 // $digest = prepare_headlines_digest($link, $user_id, $days, $limit);
2510
2511 }
2512
2513 function prepare_headlines_digest($link, $user_id, $days = 1, $limit = 100) {
2514 $tmp = "New headlines for last 24 hours, as of " . date("Y/m/d H:m") . "\n";
2515 $tmp .= "=======================================================\n\n";
2516
2517 if (DB_TYPE == "pgsql") {
2518 $interval_query = "ttrss_entries.date_entered > NOW() - INTERVAL '$days days'";
2519 } else if (DB_TYPE == "mysql") {
2520 $interval_query = "ttrss_entries.date_entered > DATE_SUB(NOW(), INTERVAL $days DAY)";
2521 }
2522
2523 $result = db_query($link, "SELECT ttrss_entries.title,
2524 ttrss_feeds.title AS feed_title,
2525 date_entered,
2526 link,
2527 SUBSTRING(last_updated,1,19) AS last_updated
2528 FROM
2529 ttrss_user_entries,ttrss_entries,ttrss_feeds
2530 WHERE
2531 ref_id = ttrss_entries.id AND feed_id = ttrss_feeds.id
2532 AND include_in_digest = true
2533 AND $interval_query
2534 AND ttrss_user_entries.owner_uid = $user_id
2535 AND unread = true ORDER BY ttrss_feeds.title, date_entered DESC
2536 LIMIT $limit");
2537
2538 $cur_feed_title = "";
2539
2540 $headlines_count = db_num_rows($result);
2541
2542 while ($line = db_fetch_assoc($result)) {
2543 $updated = smart_date_time(strtotime($line["last_updated"]));
2544 $feed_title = $line["feed_title"];
2545
2546 if ($cur_feed_title != $feed_title) {
2547 $cur_feed_title = $feed_title;
2548
2549 $tmp .= "$feed_title\n\n";
2550 }
2551
2552 $tmp .= " * " . trim($line["title"]) . " - $updated\n";
2553 $tmp .= " " . trim($line["link"]) . "\n";
2554 $tmp .= "\n";
2555 }
2556
2557 $tmp .= "--- \n";
2558 $tmp .= "You have been sent this email because you have enabled daily digests in Tiny Tiny RSS at " .
2559 DIGEST_HOSTNAME . "\n".
2560 "To unsubscribe, visit your configuration options or contact instance owner.\n";
2561
2562
2563 return array($tmp, $headlines_count);
2564 }
2565
2566 function check_for_update($link) {
2567 $releases_feed = "http://tt-rss.spb.ru/releases.rss";
2568
2569 if (!CHECK_FOR_NEW_VERSION || $_SESSION["access_level"] < 10) {
2570 return;
2571 }
2572
2573 error_reporting(0);
2574 $rss = fetch_rss($releases_feed);
2575 error_reporting (DEFAULT_ERROR_LEVEL);
2576
2577 if ($rss) {
2578
2579 $items = $rss->items;
2580
2581 if (!$items || !is_array($items)) $items = $rss->entries;
2582 if (!$items || !is_array($items)) $items = $rss;
2583
2584 if (!is_array($items) || count($items) == 0) {
2585 return;
2586 }
2587
2588 $latest_item = $items[0];
2589
2590 $latest_version = trim(preg_replace("/(Milestone)|(completed)/", "", $latest_item["title"]));
2591
2592 $release_url = sanitize_rss($latest_item["link"]);
2593 $content = sanitize_rss($latest_item["description"]);
2594
2595 if (version_compare(VERSION, $latest_version) == -1) {
2596 return "<div class=\"notice\"><a href=\"javascript:showBlockElement('milestoneDetails')\">
2597 New version of Tiny-Tiny RSS ($latest_version) is available (click for details)</a>
2598 <div id=\"milestoneDetails\">$content</div></div>";
2599 }
2600 }
2601 }
2602
2603 function markArticlesById($link, $ids, $cmode) {
2604
2605 $tmp_ids = array();
2606
2607 foreach ($ids as $id) {
2608 array_push($tmp_ids, "ref_id = '$id'");
2609 }
2610
2611 $ids_qpart = join(" OR ", $tmp_ids);
2612
2613 if ($cmode == 0) {
2614 db_query($link, "UPDATE ttrss_user_entries SET
2615 marked = false,last_read = NOW()
2616 WHERE ($ids_qpart) AND owner_uid = " . $_SESSION["uid"]);
2617 } else if ($cmode == 1) {
2618 db_query($link, "UPDATE ttrss_user_entries SET
2619 marked = true
2620 WHERE ($ids_qpart) AND owner_uid = " . $_SESSION["uid"]);
2621 } else {
2622 db_query($link, "UPDATE ttrss_user_entries SET
2623 marked = NOT marked,last_read = NOW()
2624 WHERE ($ids_qpart) AND owner_uid = " . $_SESSION["uid"]);
2625 }
2626 }
2627
2628 function catchupArticlesById($link, $ids, $cmode) {
2629
2630 $tmp_ids = array();
2631
2632 foreach ($ids as $id) {
2633 array_push($tmp_ids, "ref_id = '$id'");
2634 }
2635
2636 $ids_qpart = join(" OR ", $tmp_ids);
2637
2638 if ($cmode == 0) {
2639 db_query($link, "UPDATE ttrss_user_entries SET
2640 unread = false,last_read = NOW()
2641 WHERE ($ids_qpart) AND owner_uid = " . $_SESSION["uid"]);
2642 } else if ($cmode == 1) {
2643 db_query($link, "UPDATE ttrss_user_entries SET
2644 unread = true
2645 WHERE ($ids_qpart) AND owner_uid = " . $_SESSION["uid"]);
2646 } else {
2647 db_query($link, "UPDATE ttrss_user_entries SET
2648 unread = NOT unread,last_read = NOW()
2649 WHERE ($ids_qpart) AND owner_uid = " . $_SESSION["uid"]);
2650 }
2651 }
2652
2653 function escape_for_form($s) {
2654 return htmlspecialchars(db_unescape_string($s));
2655 }
2656
2657 function make_guid_from_title($title) {
2658 return preg_replace("/[ \"\',.:;]/", "-",
2659 mb_strtolower(strip_tags($title)));
2660 }
2661
2662 function print_headline_subtoolbar($link, $feed_site_url, $feed_title,
2663 $bottom = false, $rtl_content = false, $feed_id = 0,
2664 $is_cat = false, $search = false, $match_on = false,
2665 $search_mode = false) {
2666
2667 if (!$bottom) {
2668 $class = "headlinesSubToolbar";
2669 $tid = "headlineActionsTop";
2670 } else {
2671 $class = "headlinesSubToolbar";
2672 $tid = "headlineActionsBottom";
2673 }
2674
2675 print "<table class=\"$class\" id=\"$tid\"
2676 width=\"100%\" cellspacing=\"0\" cellpadding=\"0\"><tr>";
2677
2678 if ($rtl_content) {
2679 $rtl_cpart = "RTL";
2680 } else {
2681 $rtl_cpart = "";
2682 }
2683
2684 if (!get_pref($link, 'COMBINED_DISPLAY_MODE')) {
2685
2686 print "<td class=\"headlineActions$rtl_cpart\">
2687 Select:
2688 <a href=\"javascript:selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', true, '', true)\">All</a>,
2689 <a href=\"javascript:selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', true, 'Unread', true)\">Unread</a>,
2690 <a href=\"javascript:selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', false)\">None</a>
2691 &nbsp;&nbsp;
2692 Toggle: <a href=\"javascript:selectionToggleUnread()\">Unread</a>,
2693 <a href=\"javascript:selectionToggleMarked()\">Starred</a>
2694 &nbsp;&nbsp;
2695 Mark as read:
2696 <a href=\"#\" onclick=\"catchupPage()\">Page</a>,
2697 <a href=\"#\" onclick=\"catchupCurrentFeed()\">Feed</a>";
2698 print "</td>";
2699
2700 if ($search && $feed_id >= 0 && get_pref($link, 'ENABLE_LABELS') && GLOBAL_ENABLE_LABELS) {
2701 print "<td class=\"headlineActions$rtl_cpart\">
2702 <a href=\"javascript:labelFromSearch('$search', '$search_mode',
2703 '$match_on', '$feed_id', '$is_cat');\">
2704 Convert this search to label</a></td>";
2705 }
2706
2707 } else {
2708
2709 print "<td class=\"headlineActions$rtl_cpart\">
2710 Select:
2711 <a href=\"javascript:cdmSelectArticles('all')\">All</a>,
2712 <a href=\"javascript:cdmSelectArticles('unread')\">Unread</a>,
2713 <a href=\"javascript:cdmSelectArticles('none')\">None</a>
2714 &nbsp;&nbsp;
2715 Toggle: <a href=\"javascript:selectionToggleUnread(true)\">Unread</a>,
2716 <a href=\"javascript:selectionToggleMarked(true)\">Starred</a>
2717 &nbsp;&nbsp;
2718 Mark as read:
2719 <a href=\"#\" onclick=\"catchupPage()\">Page</a>,
2720 <a href=\"#\" onclick=\"catchupCurrentFeed()\">Feed</a>";
2721
2722 print "</td>";
2723
2724 }
2725
2726 print "<td class=\"headlineTitle$rtl_cpart\">";
2727
2728 if ($feed_site_url) {
2729 if (!$bottom) {
2730 $target = "target=\"_blank\"";
2731 }
2732 print "<a $target href=\"$feed_site_url\">$feed_title</a>";
2733 } else {
2734 print $feed_title;
2735 }
2736
2737 if ($search) {
2738 $search_q = "&q=$search&m=$match_on&smode=$search_mode";
2739 }
2740
2741 if (!$bottom) {
2742 print "&nbsp;
2743 <a target=\"_new\"
2744 href=\"backend.php?op=rss&id=$feed_id&is_cat=$is_cat$search_q\">
2745 <img class=\"noborder\"
2746 alt=\"Generated feed\" src=\"images/feed-icon-12x12.png\">
2747 </a>";
2748 }
2749
2750 print "</td>";
2751 print "</tr></table>";
2752
2753 }
2754
2755 function outputFeedList($link, $tags = false) {
2756
2757 print "<ul class=\"feedList\" id=\"feedList\">\n";
2758
2759 $owner_uid = $_SESSION["uid"];
2760
2761 /* virtual feeds */
2762
2763 if (get_pref($link, 'ENABLE_FEED_CATS')) {
2764 print "<li class=\"feedCat\">Special</li>";
2765 print "<li id=\"feedCatHolder\"><ul class=\"feedCatList\">";
2766 }
2767
2768 $num_starred = getFeedUnread($link, -1);
2769
2770 $class = "virt";
2771
2772 if ($num_starred > 0) $class .= "Unread";
2773
2774 printFeedEntry(-1, $class, "Starred articles", $num_starred,
2775 "images/mark_set.png", $link);
2776
2777 if (get_pref($link, 'ENABLE_FEED_CATS')) {
2778 print "</ul>\n";
2779 }
2780
2781 if (!$tags) {
2782
2783 if (GLOBAL_ENABLE_LABELS && get_pref($link, 'ENABLE_LABELS')) {
2784
2785 $result = db_query($link, "SELECT id,sql_exp,description FROM
2786 ttrss_labels WHERE owner_uid = '$owner_uid' ORDER by description");
2787
2788 if (db_num_rows($result) > 0) {
2789 if (get_pref($link, 'ENABLE_FEED_CATS')) {
2790 print "<li class=\"feedCat\">Labels</li>";
2791 print "<li id=\"feedCatHolder\"><ul class=\"feedCatList\">";
2792 } else {
2793 print "<li><hr></li>";
2794 }
2795 }
2796
2797 while ($line = db_fetch_assoc($result)) {
2798
2799 error_reporting (0);
2800
2801 $label_id = -$line['id'] - 11;
2802 $count = getFeedUnread($link, $label_id);
2803
2804 $class = "label";
2805
2806 if ($count > 0) {
2807 $class .= "Unread";
2808 }
2809
2810 error_reporting (DEFAULT_ERROR_LEVEL);
2811
2812 printFeedEntry($label_id,
2813 $class, db_unescape_string($line["description"]),
2814 $count, "images/label.png", $link);
2815
2816 }
2817
2818 if (db_num_rows($result) > 0) {
2819 if (get_pref($link, 'ENABLE_FEED_CATS')) {
2820 print "</ul>";
2821 }
2822 }
2823
2824 }
2825
2826 if (!get_pref($link, 'ENABLE_FEED_CATS')) {
2827 print "<li><hr></li>";
2828 }
2829
2830 if (get_pref($link, 'ENABLE_FEED_CATS')) {
2831 if (get_pref($link, "FEEDS_SORT_BY_UNREAD")) {
2832 $order_by_qpart = "category,unread DESC,title";
2833 } else {
2834 $order_by_qpart = "category,title";
2835 }
2836 } else {
2837 if (get_pref($link, "FEEDS_SORT_BY_UNREAD")) {
2838 $order_by_qpart = "unread DESC,title";
2839 } else {
2840 $order_by_qpart = "title";
2841 }
2842 }
2843
2844 $result = db_query($link, "SELECT ttrss_feeds.*,
2845 SUBSTRING(last_updated,1,19) AS last_updated_noms,
2846 (SELECT COUNT(id) FROM ttrss_entries,ttrss_user_entries
2847 WHERE feed_id = ttrss_feeds.id AND unread = true
2848 AND ttrss_user_entries.ref_id = ttrss_entries.id
2849 AND owner_uid = '$owner_uid') as unread,
2850 cat_id,last_error,
2851 ttrss_feed_categories.title AS category,
2852 ttrss_feed_categories.collapsed
2853 FROM ttrss_feeds LEFT JOIN ttrss_feed_categories
2854 ON (ttrss_feed_categories.id = cat_id)
2855 WHERE
2856 ttrss_feeds.hidden = false AND
2857 ttrss_feeds.owner_uid = '$owner_uid' AND parent_feed IS NULL
2858 ORDER BY $order_by_qpart");
2859
2860 $actid = $_GET["actid"];
2861
2862 /* real feeds */
2863
2864 $lnum = 0;
2865
2866 $total_unread = 0;
2867
2868 $category = "";
2869
2870 $short_date = get_pref($link, 'SHORT_DATE_FORMAT');
2871
2872 while ($line = db_fetch_assoc($result)) {
2873
2874 $feed = db_unescape_string($line["title"]);
2875 $feed_id = $line["id"];
2876
2877 $subop = $_GET["subop"];
2878
2879 $unread = $line["unread"];
2880
2881 if (get_pref($link, 'HEADLINES_SMART_DATE')) {
2882 $last_updated = smart_date_time(strtotime($line["last_updated_noms"]));
2883 } else {
2884 $last_updated = date($short_date, strtotime($line["last_updated_noms"]));
2885 }
2886
2887 $rtl_content = sql_bool_to_bool($line["rtl_content"]);
2888
2889 if ($rtl_content) {
2890 $rtl_tag = "dir=\"RTL\"";
2891 } else {
2892 $rtl_tag = "";
2893 }
2894
2895 $tmp_result = db_query($link,
2896 "SELECT id,COUNT(unread) AS unread
2897 FROM ttrss_feeds LEFT JOIN ttrss_user_entries
2898 ON (ttrss_feeds.id = ttrss_user_entries.feed_id)
2899 WHERE parent_feed = '$feed_id' AND unread = true
2900 GROUP BY ttrss_feeds.id");
2901
2902 if (db_num_rows($tmp_result) > 0) {
2903 while ($l = db_fetch_assoc($tmp_result)) {
2904 $unread += $l["unread"];
2905 }
2906 }
2907
2908 $cat_id = $line["cat_id"];
2909
2910 $tmp_category = $line["category"];
2911
2912 if (!$tmp_category) {
2913 $tmp_category = "Uncategorized";
2914 }
2915
2916 // $class = ($lnum % 2) ? "even" : "odd";
2917
2918 if ($line["last_error"]) {
2919 $class = "error";
2920 } else {
2921 $class = "feed";
2922 }
2923
2924 if ($unread > 0) $class .= "Unread";
2925
2926 if ($actid == $feed_id) {
2927 $class .= "Selected";
2928 }
2929
2930 $total_unread += $unread;
2931
2932 if ($category != $tmp_category && get_pref($link, 'ENABLE_FEED_CATS')) {
2933
2934 if ($category) {
2935 print "</ul></li>";
2936 }
2937
2938 $category = $tmp_category;
2939
2940 $collapsed = $line["collapsed"];
2941
2942 // workaround for NULL category
2943 if ($category == "Uncategorized") {
2944 if ($_COOKIE["ttrss_vf_uclps"] == 1) {
2945 $collapsed = "t";
2946 }
2947 }
2948
2949 if ($collapsed == "t" || $collapsed == "1") {
2950 $holder_class = "invisible";
2951 $ellipsis = "...";
2952 } else {
2953 $holder_class = "";
2954 $ellipsis = "";
2955 }
2956
2957 $cat_id = sprintf("%d", $cat_id);
2958
2959 $cat_unread = getCategoryUnread($link, $cat_id);
2960
2961 $catctr_class = ($cat_unread > 0) ? "catCtrHasUnread" : "catCtrNoUnread";
2962
2963 print "<li class=\"feedCat\" id=\"FCAT-$cat_id\">
2964 <a id=\"FCATN-$cat_id\" href=\"#\"onclick=\"javascript:toggleCollapseCat($cat_id)\">$tmp_category</a>
2965 <a href=\"#\" onclick=\"javascript:viewCategory($cat_id)\" id=\"FCAP-$cat_id\">
2966 <span id=\"FCATCTR-$cat_id\" title=\"Click to browse category\"
2967 class=\"$catctr_class\">($cat_unread)</span> $ellipsis
2968 </a></li>";
2969
2970 // !!! NO SPACE before <ul...feedCatList - breaks firstChild DOM function
2971 // -> keyboard navigation, etc.
2972 print "<li id=\"feedCatHolder\" class=\"$holder_class\"><ul class=\"feedCatList\" id=\"FCATLIST-$cat_id\">";
2973 }
2974
2975 printFeedEntry($feed_id, $class, $feed, $unread,
2976 "icons/$feed_id.ico", $link, $rtl_content,
2977 $last_updated, $line["last_error"]);
2978
2979 ++$lnum;
2980 }
2981
2982 if (db_num_rows($result) == 0) {
2983 print "<li>No feeds to display.</li>";
2984 }
2985
2986 } else {
2987
2988 // tags
2989
2990 /* $result = db_query($link, "SELECT tag_name,count(ttrss_entries.id) AS count
2991 FROM ttrss_tags,ttrss_entries,ttrss_user_entries WHERE
2992 post_int_id = ttrss_user_entries.int_id AND
2993 unread = true AND ref_id = ttrss_entries.id
2994 AND ttrss_tags.owner_uid = '$owner_uid' GROUP BY tag_name
2995 UNION
2996 select tag_name,0 as count FROM ttrss_tags WHERE owner_uid = '$owner_uid'
2997 ORDER BY tag_name"); */
2998
2999 if (get_pref($link, 'ENABLE_FEED_CATS')) {
3000 print "<li class=\"feedCat\">Tags</li>";
3001 print "<li id=\"feedCatHolder\"><ul class=\"feedCatList\">";
3002 }
3003
3004 $result = db_query($link, "SELECT tag_name,SUM((SELECT COUNT(int_id)
3005 FROM ttrss_user_entries WHERE int_id = post_int_id
3006 AND unread = true)) AS count FROM ttrss_tags
3007 WHERE owner_uid = 2 GROUP BY tag_name ORDER BY tag_name");
3008
3009 $tags = array();
3010
3011 while ($line = db_fetch_assoc($result)) {
3012 $tags[$line["tag_name"]] += $line["count"];
3013 }
3014
3015 foreach (array_keys($tags) as $tag) {
3016
3017 $unread = $tags[$tag];
3018
3019 $class = "tag";
3020
3021 if ($unread > 0) {
3022 $class .= "Unread";
3023 }
3024
3025 printFeedEntry($tag, $class, $tag, $unread, "images/tag.png", $link);
3026
3027 }
3028
3029 if (db_num_rows($result) == 0) {
3030 print "<li>No tags to display.</li>";
3031 }
3032
3033 if (get_pref($link, 'ENABLE_FEED_CATS')) {
3034 print "</ul>\n";
3035 }
3036
3037 }
3038
3039 print "</ul>";
3040
3041 }
3042
3043 function get_article_tags($link, $id) {
3044
3045 $a_id = db_escape_string($id);
3046
3047 $tmp_result = db_query($link, "SELECT DISTINCT tag_name FROM
3048 ttrss_tags WHERE post_int_id = (SELECT int_id FROM ttrss_user_entries WHERE
3049 ref_id = '$a_id' AND owner_uid = '".$_SESSION["uid"]."') ORDER BY tag_name");
3050
3051 $tags = array();
3052
3053 while ($tmp_line = db_fetch_assoc($tmp_result)) {
3054 array_push($tags, $tmp_line["tag_name"]);
3055 }
3056
3057 return $tags;
3058 }
3059
3060 function trim_value(&$value) {
3061 $value = trim($value);
3062 }
3063
3064 function trim_array($array) {
3065 $tmp = $array;
3066 array_walk($tmp, 'trim_value');
3067 return $tmp;
3068 }
3069
3070 ?>