]> git.wh0rd.org Git - tt-rss.git/blob - functions.php
optimize purge for mysql
[tt-rss.git] / functions.php
1 <?
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
13         require_once 'magpierss/rss_utils.inc';
14
15         define('MAGPIE_OUTPUT_ENCODING', 'UTF-8');
16
17         function purge_feed($link, $feed_id, $purge_interval, $debug = false) {
18
19                 $rows = -1;
20
21                 if (DB_TYPE == "pgsql") {
22 /*                      $result = db_query($link, "DELETE FROM ttrss_user_entries WHERE
23                                 marked = false AND feed_id = '$feed_id' AND
24                                 (SELECT date_entered FROM ttrss_entries WHERE
25                                         id = ref_id) < NOW() - INTERVAL '$purge_interval days'"); */
26
27                         $result = db_query($link, "DELETE FROM ttrss_user_entries WHERE 
28                                 ttrss_entries.id = ref_id AND 
29                                 marked = false AND 
30                                 feed_id = '$feed_id' AND 
31                                 ttrss_entries.date_entered < NOW() - INTERVAL '$purge_interval days'");
32
33                         $rows = pg_affected_rows($result);
34                         
35                 } else {
36 /*                      $result = db_query($link, "DELETE FROM ttrss_user_entries WHERE
37                                 marked = false AND feed_id = '$feed_id' AND
38                                 (SELECT date_entered FROM ttrss_entries WHERE 
39                                         id = ref_id) < DATE_SUB(NOW(), INTERVAL $purge_interval DAY)"); */
40
41                         $result = db_query($link, "DELETE FROM ttrss_user_entries 
42                                 USING ttrss_user_entries, ttrss_entries 
43                                 WHERE ttrss_entries.id = ref_id AND 
44                                 marked = false AND 
45                                 feed_id = '$feed_id' AND 
46                                 ttrss_entries.date_entered < DATE_SUB(NOW(), INTERVAL $purge_interval DAY)");
47                                         
48                         $rows = mysql_affected_rows($link);
49
50                 }
51
52                 if ($debug) {
53                         print "Purged feed $feed_id ($purge_interval): deleted $rows articles\n";
54                 }
55         }
56
57         function global_purge_old_posts($link, $do_output = false, $limit = false) {
58
59                 if (DB_TYPE == "mysql") {
60                         $random_qpart = "RAND()";
61                 } else {
62                         $random_qpart = "RANDOM()";
63                 }
64
65                 if ($limit) {
66                         $limit_qpart = "LIMIT $limit";
67                 } else {
68                         $limit_qpart = "";
69                 }
70                 
71                 $result = db_query($link, 
72                         "SELECT id,purge_interval,owner_uid FROM ttrss_feeds 
73                                 ORDER BY $random_qpart $limit_qpart");
74
75                 while ($line = db_fetch_assoc($result)) {
76
77                         $feed_id = $line["id"];
78                         $purge_interval = $line["purge_interval"];
79                         $owner_uid = $line["owner_uid"];
80
81                         if ($purge_interval == 0) {
82                         
83                                 $tmp_result = db_query($link, 
84                                         "SELECT value FROM ttrss_user_prefs WHERE
85                                                 pref_name = 'PURGE_OLD_DAYS' AND owner_uid = '$owner_uid'");
86
87                                 if (db_num_rows($tmp_result) != 0) {                    
88                                         $purge_interval = db_fetch_result($tmp_result, 0, "value");
89                                 }
90                         }
91
92                         if ($do_output) {
93 //                              print "Feed $feed_id: purge interval = $purge_interval\n";
94                         }
95
96                         if ($purge_interval > 0) {
97                                 purge_feed($link, $feed_id, $purge_interval, $do_output);
98                         }
99                 }       
100
101                 // purge orphaned posts in main content table
102                 db_query($link, "DELETE FROM ttrss_entries WHERE 
103                         (SELECT COUNT(int_id) FROM ttrss_user_entries WHERE ref_id = id) = 0");
104
105         }
106
107         function purge_old_posts($link) {
108
109                 $user_id = $_SESSION["uid"];
110         
111                 $result = db_query($link, "SELECT id,purge_interval FROM ttrss_feeds 
112                         WHERE owner_uid = '$user_id'");
113
114                 while ($line = db_fetch_assoc($result)) {
115
116                         $feed_id = $line["id"];
117                         $purge_interval = $line["purge_interval"];
118
119                         if ($purge_interval == 0) $purge_interval = get_pref($link, 'PURGE_OLD_DAYS');
120
121                         if ($purge_interval > 0) {
122                                 purge_feed($link, $feed_id, $purge_interval);
123                         }
124                 }       
125
126                 // purge orphaned posts in main content table
127                 db_query($link, "DELETE FROM ttrss_entries WHERE 
128                         (SELECT COUNT(int_id) FROM ttrss_user_entries WHERE ref_id = id) = 0");
129         }
130
131         function update_all_feeds($link, $fetch, $user_id = false, $force_daemon = false) {
132
133                 if (WEB_DEMO_MODE) return;
134
135                 if (!$user_id) {
136                         $user_id = $_SESSION["uid"];
137                         purge_old_posts($link);
138                 }
139
140 //              db_query($link, "BEGIN");
141
142                 if (MAX_UPDATE_TIME > 0) {
143                         if (DB_TYPE == "mysql") {
144                                 $q_order = "RAND()";
145                         } else {
146                                 $q_order = "RANDOM()";
147                         }
148                 } else {
149                         $q_order = "last_updated DESC";
150                 }
151
152                 $result = db_query($link, "SELECT feed_url,id,
153                         SUBSTRING(last_updated,1,19) AS last_updated,
154                         update_interval FROM ttrss_feeds WHERE owner_uid = '$user_id'
155                         ORDER BY $q_order");
156
157                 $upd_start = time();
158
159                 while ($line = db_fetch_assoc($result)) {
160                         $upd_intl = $line["update_interval"];
161
162                         if (!$upd_intl || $upd_intl == 0) {
163                                 $upd_intl = get_pref($link, 'DEFAULT_UPDATE_INTERVAL', $user_id);
164                         }
165
166                         if ($upd_intl < 0) { 
167                                 // Updates for this feed are disabled
168                                 continue; 
169                         }
170
171                         if ($fetch || (!$line["last_updated"] || 
172                                 time() - strtotime($line["last_updated"]) > ($upd_intl * 60))) {
173
174 //                              print "<!-- feed: ".$line["feed_url"]." -->";
175
176                                 update_rss_feed($link, $line["feed_url"], $line["id"], $force_daemon);
177
178                                 $upd_elapsed = time() - $upd_start;
179
180                                 if (MAX_UPDATE_TIME > 0 && $upd_elapsed > MAX_UPDATE_TIME) {
181                                         return;
182                                 }
183                         }
184                 }
185
186 //              db_query($link, "COMMIT");
187
188         }
189
190         function check_feed_favicon($feed_url, $feed, $link) {
191                 $feed_url = str_replace("http://", "", $feed_url);
192                 $feed_url = preg_replace("/\/.*$/", "", $feed_url);
193                 
194                 $icon_url = "http://$feed_url/favicon.ico";
195                 $icon_file = ICONS_DIR . "/$feed.ico";
196
197                 if (!file_exists($icon_file)) {
198                                 
199                         error_reporting(0);
200                         $r = fopen($icon_url, "r");
201                         error_reporting (DEFAULT_ERROR_LEVEL);
202
203                         if ($r) {
204                                 $tmpfname = tempnam(TMP_DIRECTORY, "ttrssicon");
205                         
206                                 $t = fopen($tmpfname, "w");
207                                 
208                                 while (!feof($r)) {
209                                         $buf = fread($r, 16384);
210                                         fwrite($t, $buf);
211                                 }
212                                 
213                                 fclose($r);
214                                 fclose($t);
215
216                                 error_reporting(0);
217                                 if (!rename($tmpfname, $icon_file)) {
218                                         unlink($tmpfname);
219                                 }
220
221                                 chmod($icon_file, 0644);
222                                 
223                                 error_reporting (DEFAULT_ERROR_LEVEL);
224
225                         }       
226                 }
227         }
228
229         function update_rss_feed($link, $feed_url, $feed, $ignore_daemon = false) {
230
231                 if (WEB_DEMO_MODE) return;
232
233                 if (DAEMON_REFRESH_ONLY && !$_GET["daemon"] && !$ignore_daemon) {
234                         return;                 
235                 }
236
237                 $result = db_query($link, "SELECT update_interval,auth_login,auth_pass  
238                         FROM ttrss_feeds WHERE id = '$feed'");
239
240                 $auth_login = db_fetch_result($result, 0, "auth_login");
241                 $auth_pass = db_fetch_result($result, 0, "auth_pass");
242
243                 $update_interval = db_fetch_result($result, 0, "update_interval");
244
245                 if ($update_interval < 0) { return; }
246
247                 $feed = db_escape_string($feed);
248
249                 $fetch_url = $feed_url;
250
251                 if ($auth_login && $auth_pass) {
252                         $url_parts = array();
253                         preg_match("/(^[^:]*):\/\/(.*)/", $fetch_url, $url_parts);
254
255                         if ($url_parts[1] && $url_parts[2]) {
256                                 $fetch_url = $url_parts[1] . "://$auth_login:$auth_pass@" . $url_parts[2];
257                         }
258
259                 }
260                 error_reporting(0);
261                 $rss = fetch_rss($fetch_url);
262
263                 error_reporting (DEFAULT_ERROR_LEVEL);
264
265                 $feed = db_escape_string($feed);
266
267                 if ($rss) {
268
269 //                      db_query($link, "BEGIN");
270
271                         $result = db_query($link, "SELECT title,icon_url,site_url,owner_uid
272                                 FROM ttrss_feeds WHERE id = '$feed'");
273
274                         $registered_title = db_fetch_result($result, 0, "title");
275                         $orig_icon_url = db_fetch_result($result, 0, "icon_url");
276                         $orig_site_url = db_fetch_result($result, 0, "site_url");
277
278                         $owner_uid = db_fetch_result($result, 0, "owner_uid");
279
280                         if (get_pref($link, 'ENABLE_FEED_ICONS', $owner_uid)) { 
281                                 check_feed_favicon($feed_url, $feed, $link);
282                         }
283
284                         if (!$registered_title || $registered_title == "[Unknown]") {
285                                 $feed_title = db_escape_string($rss->channel["title"]);
286                                 db_query($link, "UPDATE ttrss_feeds SET 
287                                         title = '$feed_title' WHERE id = '$feed'");
288                         }
289
290                         $site_url = $rss->channel["link"];
291                         // weird, weird Magpie
292                         if (!$site_url) $site_url = db_escape_string($rss->channel["link_"]);
293
294                         if ($site_url && $orig_site_url != db_escape_string($site_url)) {
295                                 db_query($link, "UPDATE ttrss_feeds SET 
296                                         site_url = '$site_url' WHERE id = '$feed'");
297                         }
298
299 //                      print "I: " . $rss->channel["image"]["url"];
300
301                         $icon_url = $rss->image["url"];
302
303                         if ($icon_url && !$orig_icon_url != db_escape_string($icon_url)) {
304                                 $icon_url = db_escape_string($icon_url);
305                                 db_query($link, "UPDATE ttrss_feeds SET icon_url = '$icon_url' WHERE id = '$feed'");
306                         }
307
308
309                         $filters = array();
310
311                         $result = db_query($link, "SELECT reg_exp,
312                                 ttrss_filter_types.name AS name,
313                                 ttrss_filter_actions.name AS action
314                                 FROM ttrss_filters,ttrss_filter_types,ttrss_filter_actions WHERE                                        
315                                         owner_uid = $owner_uid AND
316                                         ttrss_filter_types.id = filter_type AND
317                                         ttrss_filter_actions.id = action_id AND
318                                 (feed_id IS NULL OR feed_id = '$feed')");
319
320                         while ($line = db_fetch_assoc($result)) {
321                                 if (!$filters[$line["name"]]) $filters[$line["name"]] = array();
322
323                                 $filter["reg_exp"] = $line["reg_exp"];
324                                 $filter["action"] = $line["action"];
325                                 
326                                 array_push($filters[$line["name"]], $filter);
327                         }
328
329                         $iterator = $rss->items;
330
331                         if (!$iterator || !is_array($iterator)) $iterator = $rss->entries;
332                         if (!$iterator || !is_array($iterator)) $iterator = $rss;
333
334                         if (!is_array($iterator)) {
335                                 db_query($link, "UPDATE ttrss_feeds 
336                                         SET last_error = 'CrazyBug 001: Can\'t find iterator :(' 
337                                                 WHERE id = '$feed'");
338                                 return; // WTF?
339                         }
340
341                         foreach ($iterator as $item) {
342         
343                                 $entry_guid = $item["id"];
344         
345                                 if (!$entry_guid) $entry_guid = $item["guid"];
346                                 if (!$entry_guid) $entry_guid = $item["link"];
347
348                                 if (!$entry_guid) continue;
349
350                                 $entry_timestamp = "";
351
352                                 $rss_2_date = $item['pubdate'];
353                                 $rss_1_date = $item['dc']['date'];
354                                 $atom_date = $item['issued'];
355                                 if (!$atom_date) $atom_date = $item['updated'];
356                         
357                                 if ($atom_date != "") $entry_timestamp = parse_w3cdtf($atom_date);
358                                 if ($rss_1_date != "") $entry_timestamp = parse_w3cdtf($rss_1_date);
359                                 if ($rss_2_date != "") $entry_timestamp = strtotime($rss_2_date);
360                                 
361                                 if ($entry_timestamp == "") {
362                                         $entry_timestamp = time();
363                                         $no_orig_date = 'true';
364                                 } else {
365                                         $no_orig_date = 'false';
366                                 }
367
368                                 $entry_timestamp_fmt = strftime("%Y/%m/%d %H:%M:%S", $entry_timestamp);
369
370                                 $entry_title = $item["title"];
371
372                                 // strange Magpie workaround
373                                 $entry_link = $item["link_"];
374                                 if (!$entry_link) $entry_link = $item["link"];
375
376                                 if (!$entry_title) continue;
377                                 if (!$entry_link) continue;
378
379                                 $entry_content = $item["content:escaped"];
380
381                                 if (!$entry_content) $entry_content = $item["content:encoded"];
382                                 if (!$entry_content) $entry_content = $item["content"];
383                                 if (!$entry_content) $entry_content = $item["summary"];
384                                 if (!$entry_content) $entry_content = $item["description"];
385
386 //                              if (!$entry_content) continue;
387
388                                 // WTF
389                                 if (is_array($entry_content)) {
390                                         $entry_content = $entry_content["encoded"];
391                                         if (!$entry_content) $entry_content = $entry_content["escaped"];
392                                 }
393
394 //                              print_r($item);
395 //                              print_r(htmlspecialchars($entry_content));
396 //                              print "<br>";
397
398                                 $entry_content_unescaped = $entry_content;
399                                 $content_hash = "SHA1:" . sha1(strip_tags($entry_content));
400
401                                 $entry_comments = $item["comments"];
402
403                                 $entry_author = db_escape_string($item['dc']['creator']);
404
405                                 $entry_guid = db_escape_string($entry_guid);
406
407                                 $result = db_query($link, "SELECT id FROM       ttrss_entries 
408                                         WHERE guid = '$entry_guid'");
409
410                                 $entry_content = db_escape_string($entry_content);
411                                 $entry_title = db_escape_string($entry_title);
412                                 $entry_link = db_escape_string($entry_link);
413                                 $entry_comments = db_escape_string($entry_comments);
414
415                                 $num_comments = db_escape_string($item["slash"]["comments"]);
416
417                                 if (!$num_comments) $num_comments = 0;
418
419                                 db_query($link, "BEGIN");
420
421                                 if (db_num_rows($result) == 0) {
422
423                                         // base post entry does not exist, create it
424
425                                         $result = db_query($link,
426                                                 "INSERT INTO ttrss_entries 
427                                                         (title,
428                                                         guid,
429                                                         link,
430                                                         updated,
431                                                         content,
432                                                         content_hash,
433                                                         no_orig_date,
434                                                         date_entered,
435                                                         comments,
436                                                         num_comments,
437                                                         author)
438                                                 VALUES
439                                                         ('$entry_title', 
440                                                         '$entry_guid', 
441                                                         '$entry_link',
442                                                         '$entry_timestamp_fmt', 
443                                                         '$entry_content', 
444                                                         '$content_hash',
445                                                         $no_orig_date, 
446                                                         NOW(), 
447                                                         '$entry_comments',
448                                                         '$num_comments',
449                                                         '$entry_author')");
450                                 } else {
451                                         // we keep encountering the entry in feeds, so we need to
452                                         // update date_entered column so that we don't get horrible
453                                         // dupes when the entry gets purged and reinserted again e.g.
454                                         // in the case of SLOW SLOW OMG SLOW updating feeds
455
456                                         $base_entry_id = db_fetch_result($result, 0, "id");
457
458                                         db_query($link, "UPDATE ttrss_entries SET date_entered = NOW()
459                                                 WHERE id = '$base_entry_id'");
460                                 }
461
462                                 // now it should exist, if not - bad luck then
463
464                                 $result = db_query($link, "SELECT 
465                                                 id,content_hash,no_orig_date,title,
466                                                 substring(date_entered,1,19) as date_entered,
467                                                 substring(updated,1,19) as updated,
468                                                 num_comments
469                                         FROM 
470                                                 ttrss_entries 
471                                         WHERE guid = '$entry_guid'");
472
473                                 if (db_num_rows($result) == 1) {
474
475                                         // this will be used below in update handler
476                                         $orig_content_hash = db_fetch_result($result, 0, "content_hash");
477                                         $orig_title = db_fetch_result($result, 0, "title");
478                                         $orig_num_comments = db_fetch_result($result, 0, "num_comments");
479                                         $orig_date_entered = strtotime(db_fetch_result($result, 
480                                                 0, "date_entered"));
481
482                                         $ref_id = db_fetch_result($result, 0, "id");
483
484                                         // check for user post link to main table
485
486                                         // do we allow duplicate posts with same GUID in different feeds?
487                                         if (get_pref($link, "ALLOW_DUPLICATE_POSTS", $owner_uid)) {
488                                                 $dupcheck_qpart = "AND feed_id = '$feed'";
489                                         } else { 
490                                                 $dupcheck_qpart = "";
491                                         }
492
493 //                                      error_reporting(0);
494
495                                         $filter_name = get_filter_name($entry_title, $entry_content, 
496                                                 $entry_link, $filters);
497
498                                         if ($filter_name == "filter") {
499                                                 continue;
500                                         }
501
502 //                                      error_reporting (DEFAULT_ERROR_LEVEL);
503
504                                         $result = db_query($link,
505                                                 "SELECT ref_id FROM ttrss_user_entries WHERE
506                                                         ref_id = '$ref_id' AND owner_uid = '$owner_uid'
507                                                         $dupcheck_qpart");
508                                                         
509                                         // okay it doesn't exist - create user entry
510                                         if (db_num_rows($result) == 0) {
511
512                                                 if ($filter_name != 'catchup') {
513                                                         $unread = 'true';
514                                                         $last_read_qpart = 'NULL';
515                                                 } else {
516                                                         $unread = 'false';
517                                                         $last_read_qpart = 'NOW()';
518                                                 }                                               
519                                                 
520                                                 $result = db_query($link,
521                                                         "INSERT INTO ttrss_user_entries 
522                                                                 (ref_id, owner_uid, feed_id, unread, last_read) 
523                                                         VALUES ('$ref_id', '$owner_uid', '$feed', $unread,
524                                                                 $last_read_qpart)");
525                                         }
526                                         
527                                         $post_needs_update = false;
528
529                                         if (get_pref($link, "UPDATE_POST_ON_CHECKSUM_CHANGE", $owner_uid) &&
530                                                 ($content_hash != $orig_content_hash)) {
531                                                 $post_needs_update = true;
532                                         }
533
534                                         if ($orig_title != $entry_title) {
535                                                 $post_needs_update = true;
536                                         }
537
538                                         if ($orig_num_comments != $num_comments) {
539                                                 $post_needs_update = true;
540                                         }
541
542 //                                      this doesn't seem to be very reliable
543 //
544 //                                      if ($orig_timestamp != $entry_timestamp && !$orig_no_orig_date) {
545 //                                              $post_needs_update = true;
546 //                                      }
547
548                                         // if post needs update, update it and mark all user entries 
549                                         // linking to this post as updated                                      
550                                         if ($post_needs_update) {
551
552 //                                              print "<!-- post $orig_title needs update : $post_needs_update -->";
553
554                                                 db_query($link, "UPDATE ttrss_entries 
555                                                         SET title = '$entry_title', content = '$entry_content',
556                                                                 num_comments = '$num_comments'
557                                                         WHERE id = '$ref_id'");
558
559                                                 db_query($link, "UPDATE ttrss_user_entries 
560                                                         SET last_read = null WHERE ref_id = '$ref_id' AND unread = false");
561
562                                         }
563                                 }
564
565                                 db_query($link, "COMMIT");
566
567                                 /* taaaags */
568                                 // <a href="http://technorati.com/tag/Xorg" rel="tag">Xorg</a>, //
569
570                                 $entry_tags = null;
571
572                                 preg_match_all("/<a.*?href=.http:\/\/.*?technorati.com\/tag\/([^\"\'>]+)/i", 
573                                         $entry_content_unescaped, $entry_tags);
574
575 //                              print "<br>$entry_title : $entry_content_unescaped<br>";
576 //                              print_r($entry_tags);
577 //                              print "<br>";
578
579                                 $entry_tags = $entry_tags[1];
580
581                                 if (count($entry_tags) > 0) {
582                                 
583                                         db_query($link, "BEGIN");
584                         
585                                         $result = db_query($link, "SELECT id,int_id 
586                                                 FROM ttrss_entries,ttrss_user_entries 
587                                                 WHERE guid = '$entry_guid' 
588                                                 AND feed_id = '$feed' AND ref_id = id
589                                                 AND owner_uid = '$owner_uid'");
590
591                                         if (db_num_rows($result) == 1) {
592
593                                                 $entry_id = db_fetch_result($result, 0, "id");
594                                                 $entry_int_id = db_fetch_result($result, 0, "int_id");
595                                                 
596                                                 foreach ($entry_tags as $tag) {
597                                                         $tag = db_escape_string(strtolower($tag));
598
599                                                         $tag = str_replace("+", " ", $tag);     
600                                                         $tag = str_replace("technorati tag: ", "", $tag);
601         
602                                                         $result = db_query($link, "SELECT id FROM ttrss_tags            
603                                                                 WHERE tag_name = '$tag' AND post_int_id = '$entry_int_id' AND 
604                                                                 owner_uid = '$owner_uid' LIMIT 1");
605         
606         //                                              print db_fetch_result($result, 0, "id");
607         
608                                                         if ($result && db_num_rows($result) == 0) {
609                                                                 
610         //                                                      print "tagging $entry_id as $tag<br>";
611         
612                                                                 db_query($link, "INSERT INTO ttrss_tags 
613                                                                         (owner_uid,tag_name,post_int_id)
614                                                                         VALUES ('$owner_uid','$tag', '$entry_int_id')");
615                                                         }                                                       
616                                                 }
617                                         }
618                                         db_query($link, "COMMIT");
619                                 } 
620                         } 
621
622                         db_query($link, "UPDATE ttrss_feeds 
623                                 SET last_updated = NOW(), last_error = '' WHERE id = '$feed'");
624
625 //                      db_query($link, "COMMIT");
626
627                 } else {
628                         $error_msg = db_escape_string(magpie_error());
629                         db_query($link, 
630                                 "UPDATE ttrss_feeds SET last_error = '$error_msg', 
631                                         last_updated = NOW() WHERE id = '$feed'");
632                 }
633
634         }
635
636         function print_select($id, $default, $values, $attributes = "") {
637                 print "<select id=\"$id\" $attributes>";
638                 foreach ($values as $v) {
639                         if ($v == $default)
640                                 $sel = " selected";
641                          else
642                                 $sel = "";
643                         
644                         print "<option$sel>$v</option>";
645                 }
646                 print "</select>";
647         }
648
649         function get_filter_name($title, $content, $link, $filters) {
650
651                 if ($filters["title"]) {
652                         foreach ($filters["title"] as $filter) {
653                                 $reg_exp = $filter["reg_exp"];                  
654                                 if (preg_match("/$reg_exp/i", $title)) {
655                                         return $filter["action"];
656                                 }
657                         }
658                 }
659
660                 if ($filters["content"]) {
661                         foreach ($filters["content"] as $filter) {
662                                 $reg_exp = $filter["reg_exp"];                  
663                                 if (preg_match("/$reg_exp/i", $content)) {
664                                         return $filter["action"];
665                                 }               
666                         }
667                 }
668
669                 if ($filters["both"]) {
670                         foreach ($filters["both"] as $filter) {                 
671                                 $reg_exp = $filter["reg_exp"];          
672                                 if (preg_match("/$reg_exp/i", $title) || 
673                                         preg_match("/$reg_exp/i", $content)) {
674                                         return $filter["action"];
675                                 }
676                         }
677                 }
678
679                 if ($filters["link"]) {
680                         $reg_exp = $filter["reg_exp"];
681                         foreach ($filters["link"] as $filter) {
682                                 $reg_exp = $filter["reg_exp"];
683                                 if (preg_match("/$reg_exp/i", $link)) {
684                                         return $filter["action"];
685                                 }
686                         }
687                 }
688
689                 return false;
690         }
691
692         function printFeedEntry($feed_id, $class, $feed_title, $unread, $icon_file, $link) {
693
694                 if (file_exists($icon_file) && filesize($icon_file) > 0) {
695                                 $feed_icon = "<img id=\"FIMG-$feed_id\" src=\"$icon_file\">";
696                 } else {
697                         $feed_icon = "<img id=\"FIMG-$feed_id\" src=\"images/blank_icon.gif\">";
698                 }
699
700                 $feed = "<a href=\"javascript:viewfeed('$feed_id', 0);\">$feed_title</a>";
701
702                 print "<li id=\"FEEDR-$feed_id\" class=\"$class\">";
703                 if (get_pref($link, 'ENABLE_FEED_ICONS')) {
704                         print "$feed_icon";
705                 }
706
707                 print "<span id=\"FEEDN-$feed_id\">$feed</span>";
708
709                 if ($unread != 0) {
710                         $fctr_class = "";
711                 } else {
712                         $fctr_class = "class=\"invisible\"";
713                 }
714
715                 print "<span $fctr_class id=\"FEEDCTR-$feed_id\">
716                          (<span id=\"FEEDU-$feed_id\">$unread</span>)</span>";
717                 
718                 print "</li>";
719
720         }
721
722         function getmicrotime() {
723                 list($usec, $sec) = explode(" ",microtime());
724                 return ((float)$usec + (float)$sec);
725         }
726
727         function print_radio($id, $default, $values, $attributes = "") {
728                 foreach ($values as $v) {
729                 
730                         if ($v == $default)
731                                 $sel = "checked";
732                          else
733                                 $sel = "";
734
735                         if ($v == "Yes") {
736                                 $sel .= " value=\"1\"";
737                         } else {
738                                 $sel .= " value=\"0\"";
739                         }
740                         
741                         print "<input class=\"noborder\" 
742                                 type=\"radio\" $sel $attributes name=\"$id\">&nbsp;$v&nbsp;";
743
744                 }
745         }
746
747         function initialize_user_prefs($link, $uid) {
748
749                 $uid = db_escape_string($uid);
750
751                 db_query($link, "BEGIN");
752
753                 $result = db_query($link, "SELECT pref_name,def_value FROM ttrss_prefs");
754                 
755                 $u_result = db_query($link, "SELECT pref_name 
756                         FROM ttrss_user_prefs WHERE owner_uid = '$uid'");
757
758                 $active_prefs = array();
759
760                 while ($line = db_fetch_assoc($u_result)) {
761                         array_push($active_prefs, $line["pref_name"]);                  
762                 }
763
764                 while ($line = db_fetch_assoc($result)) {
765                         if (array_search($line["pref_name"], $active_prefs) === FALSE) {
766 //                              print "adding " . $line["pref_name"] . "<br>";
767
768                                 db_query($link, "INSERT INTO ttrss_user_prefs
769                                         (owner_uid,pref_name,value) VALUES 
770                                         ('$uid', '".$line["pref_name"]."','".$line["def_value"]."')");
771
772                         }
773                 }
774
775                 db_query($link, "COMMIT");
776
777         }
778         
779         function authenticate_user($link, $login, $password) {
780
781                 $pwd_hash = 'SHA1:' . sha1($password);
782
783                 $result = db_query($link, "SELECT id,login,access_level FROM ttrss_users WHERE 
784                         login = '$login' AND pwd_hash = '$pwd_hash'");
785
786                 if (db_num_rows($result) == 1) {
787                         $_SESSION["uid"] = db_fetch_result($result, 0, "id");
788                         $_SESSION["name"] = db_fetch_result($result, 0, "login");
789                         $_SESSION["access_level"] = db_fetch_result($result, 0, "access_level");
790
791                         db_query($link, "UPDATE ttrss_users SET last_login = NOW() WHERE id = " . 
792                                 $_SESSION["uid"]);
793
794                         $user_theme = get_user_theme_path($link);
795
796                         $_SESSION["theme"] = $user_theme;
797                         $_SESSION["ip_address"] = $_SERVER["REMOTE_ADDR"];
798
799                         initialize_user_prefs($link, $_SESSION["uid"]);
800
801                         return true;
802                 }
803
804                 return false;
805
806         }
807
808         function make_password($length = 8) {
809
810                 $password = "";
811                 $possible = "0123456789abcdfghjkmnpqrstvwxyzABCDFGHJKMNPQRSTVWXYZ"; 
812                 
813         $i = 0; 
814     
815                 while ($i < $length) { 
816                         $char = substr($possible, mt_rand(0, strlen($possible)-1), 1);
817         
818                         if (!strstr($password, $char)) { 
819                                 $password .= $char;
820                                 $i++;
821                         }
822                 }
823                 return $password;
824         }
825
826         // this is called after user is created to initialize default feeds, labels
827         // or whatever else
828         
829         // user preferences are checked on every login, not here
830
831         function initialize_user($link, $uid) {
832
833                 db_query($link, "insert into ttrss_labels (owner_uid,sql_exp,description) 
834                         values ('$uid','unread = true', 'Unread articles')");
835
836                 db_query($link, "insert into ttrss_labels (owner_uid,sql_exp,description) 
837                         values ('$uid','last_read is null and unread = false', 'Updated articles')");
838                 
839                 db_query($link, "insert into ttrss_feeds (owner_uid,title,feed_url)
840                         values ('$uid', 'Tiny Tiny RSS: New Releases',
841                         'http://tt-rss.spb.ru/releases.rss')");
842
843         }
844
845         function logout_user() {
846                 session_destroy();
847                 if (isset($_COOKIE[session_name()])) {
848                    setcookie(session_name(), '', time()-42000, '/');
849                 }
850         }
851
852         function get_script_urlpath() {
853                 return preg_replace('/\/[^\/]*$/', "", $_SERVER["REQUEST_URI"]);
854         }
855
856         function get_login_redirect() {
857                 $server = $_SERVER["SERVER_NAME"];
858
859                 if (ENABLE_LOGIN_SSL) {
860                         $protocol = "https";
861                 } else {
862                         $protocol = "http";
863                 }               
864
865                 $url_path = get_script_urlpath();
866
867                 $redirect_uri = "$protocol://$server$url_path/login.php";
868
869                 return $redirect_uri;
870         }
871
872         function validate_session($link) {
873                 if (SESSION_CHECK_ADDRESS && !DATABASE_BACKED_SESSIONS && $_SESSION["uid"]) {
874                         if ($_SESSION["ip_address"]) {
875                                 if ($_SESSION["ip_address"] != $_SERVER["REMOTE_ADDR"]) {
876                                         return false;
877                                 }
878                         }
879                 }
880                 return true;
881         }
882
883         function basic_nosid_redirect_check() {
884                 if (!SINGLE_USER_MODE) {
885                         if (!$_COOKIE["ttrss_sid"]) {
886                                 $redirect_uri = get_login_redirect();
887                                 $return_to = preg_replace('/.*?\//', '', $_SERVER["REQUEST_URI"]);
888                                 header("Location: $redirect_uri?rt=$return_to");
889                                 exit;
890                         }
891                 }
892         }
893
894         function login_sequence($link) {
895                 if (!SINGLE_USER_MODE) {
896
897                         if (!validate_session($link)) {
898                                 logout_user();
899                                 $redirect_uri = get_login_redirect();
900                                 $return_to = preg_replace('/.*?\//', '', $_SERVER["REQUEST_URI"]);
901                                 header("Location: $redirect_uri?rt=$return_to");
902                                 exit;
903                         }
904
905                         if (!USE_HTTP_AUTH) {
906                                 if (!$_SESSION["uid"]) {
907                                         $redirect_uri = get_login_redirect();
908                                         $return_to = preg_replace('/.*?\//', '', $_SERVER["REQUEST_URI"]);
909                                         header("Location: $redirect_uri?rt=$return_to");
910                                         exit;
911                                 }
912                         } else {
913                                 if (!$_SESSION["uid"]) {
914                                         if (!$_SERVER["PHP_AUTH_USER"]) {
915
916                                                 header('WWW-Authenticate: Basic realm="Tiny Tiny RSS"');
917                                                 header('HTTP/1.0 401 Unauthorized');
918                                                 exit;
919                                                 
920                                         } else {
921                                                 $auth_result = authenticate_user($link, 
922                                                         $_SERVER["PHP_AUTH_USER"], $_SERVER["PHP_AUTH_PW"]);
923
924                                                 if (!$auth_result) {
925                                                         header('WWW-Authenticate: Basic realm="Tiny Tiny RSS"');
926                                                         header('HTTP/1.0 401 Unauthorized');
927                                                         exit;
928                                                 }
929                                         }
930                                 }                               
931                         }
932                 } else {
933                         $_SESSION["uid"] = 1;
934                         $_SESSION["name"] = "admin";
935                         initialize_user_prefs($link, 1); 
936                 }
937         }
938
939         function truncate_string($str, $max_len) {
940                 if (mb_strlen($str, "utf-8") > $max_len - 3) {
941                         return mb_substr($str, 0, $max_len, "utf-8") . "...";
942                 } else {
943                         return $str;
944                 }
945         }
946
947         function get_user_theme_path($link) {
948                 $result = db_query($link, "SELECT theme_path 
949                         FROM 
950                                 ttrss_themes,ttrss_users
951                         WHERE ttrss_themes.id = theme_id AND ttrss_users.id = " . $_SESSION["uid"]);
952                 if (db_num_rows($result) != 0) {
953                         return db_fetch_result($result, 0, "theme_path");
954                 } else {
955                         return null;
956                 }
957         }
958
959         function smart_date_time($timestamp) {
960                 if (date("Y.m.d", $timestamp) == date("Y.m.d")) {
961                         return date("G:i", $timestamp);
962                 } else if (date("Y", $timestamp) == date("Y")) {
963                         return date("M d, G:i", $timestamp);
964                 } else {
965                         return date("Y/m/d G:i", $timestamp);
966                 }
967         }
968
969         function smart_date($timestamp) {
970                 if (date("Y.m.d", $timestamp) == date("Y.m.d")) {
971                         return "Today";
972                 } else if (date("Y", $timestamp) == date("Y")) {
973                         return date("D m", $timestamp);
974                 } else {
975                         return date("Y/m/d", $timestamp);
976                 }
977         }
978
979         function sql_bool_to_string($s) {
980                 if ($s == "t" || $s == "1") {
981                         return "true";
982                 } else {
983                         return "false";
984                 }
985         }
986
987         function sql_bool_to_bool($s) {
988                 if ($s == "t" || $s == "1") {
989                         return true;
990                 } else {
991                         return false;
992                 }
993         }
994         
995
996         function toggleEvenOdd($a) {
997                 if ($a == "even") 
998                         return "odd";
999                 else
1000                         return "even";
1001         }
1002
1003         function sanity_check($link) {
1004
1005                 $error_code = 0;
1006                 $result = db_query($link, "SELECT schema_version FROM ttrss_version");
1007                 $schema_version = db_fetch_result($result, 0, "schema_version");
1008
1009                 if ($schema_version != SCHEMA_VERSION) {
1010                         $error_code = 5;
1011                 }
1012
1013                 if ($error_code != 0) {
1014                         print "<error error-code='$error_code'/>";
1015                         return false;
1016                 } else {
1017                         return true;
1018                 } 
1019         }
1020
1021         function file_is_locked($filename) {
1022                 error_reporting(0);
1023                 $fp = fopen($filename, "r");
1024                 error_reporting(DEFAULT_ERROR_LEVEL);
1025                 if ($fp) {
1026                         if (flock($fp, LOCK_EX | LOCK_NB)) {
1027                                 flock($fp, LOCK_UN);
1028                                 fclose($fp);
1029                                 return false;
1030                         }
1031                         fclose($fp);
1032                         return true;
1033                 }
1034                 return false;
1035         }
1036
1037         function make_lockfile($filename) {
1038                 $fp = fopen($filename, "w");
1039
1040                 if (flock($fp, LOCK_EX | LOCK_NB)) {            
1041                         return $fp;
1042                 } else {
1043                         return false;
1044                 }
1045         }
1046
1047 ?>