]> git.wh0rd.org - tt-rss.git/blame - classes/pref_feeds.php
remove feeds/index()
[tt-rss.git] / classes / pref_feeds.php
CommitLineData
afcfe6ca 1<?php
46da73c2 2class Pref_Feeds extends Protected_Handler {
8484ce22
AD
3
4 function csrf_ignore($method) {
f6cd767b 5 $csrf_ignored = array("index", "getfeedtree", "add", "editcats", "editfeed",
35b9844b 6 "savefeedorder", "uploadicon");
8484ce22
AD
7
8 return array_search($method, $csrf_ignored) !== false;
9 }
10
afcfe6ca
AD
11 function batch_edit_cbox($elem, $label = false) {
12 print "<input type=\"checkbox\" title=\"".__("Check to enable field")."\"
13 onchange=\"dijit.byId('feedEditDlg').toggleField(this, '$elem', '$label')\">";
14 }
15
16 function renamecat() {
17 $title = db_escape_string($_REQUEST['title']);
18 $id = db_escape_string($_REQUEST['id']);
19
20 if ($title) {
21 db_query($this->link, "UPDATE ttrss_feed_categories SET
22 title = '$title' WHERE id = '$id' AND owner_uid = " . $_SESSION["uid"]);
23 }
24 return;
25 }
26
27 function remtwitterinfo() {
28
29 db_query($this->link, "UPDATE ttrss_users SET twitter_oauth = NULL
30 WHERE id = " . $_SESSION['uid']);
31
32 return;
33 }
34
2a060a94
AD
35 private function get_category_items($cat_id) {
36
37 $items = array();
38
2ecd2df5 39 $result = db_query($this->link, "SELECT id, title, collapsed FROM ttrss_feed_categories
2a060a94
AD
40 WHERE owner_uid = " . $_SESSION["uid"] . " AND parent_cat = '$cat_id' ORDER BY order_id, title");
41
42 while ($line = db_fetch_assoc($result)) {
43
44 $cat = array();
45 $cat['id'] = 'CAT:' . $line['id'];
2ecd2df5 46 $cat['bare_id'] = (int)$line['id'];
2a060a94
AD
47 $cat['name'] = $line['title'];
48 $cat['items'] = array();
49 $cat['checkbox'] = false;
2ecd2df5 50 $cat['hidden'] = sql_bool_to_bool($line['collapsed']);
2a060a94 51 $cat['type'] = 'category';
2ecd2df5 52 $cat['unread'] = 0;
2a060a94
AD
53
54 $cat['items'] = $this->get_category_items($line['id']);
55
56 $cat['param'] = T_sprintf('(%d feeds)', count($cat['items']));
57
58 if (count($cat['items']) > 0 || $show_empty_cats)
59 array_push($items, $cat);
60
61 }
62
63 $feed_result = db_query($this->link, "SELECT id, title, last_error,
64 ".SUBSTRING_FOR_DATE."(last_updated,1,19) AS last_updated
65 FROM ttrss_feeds
66 WHERE cat_id = '$cat_id' AND owner_uid = ".$_SESSION["uid"].
67 "$search_qpart ORDER BY order_id, title");
68
69 while ($feed_line = db_fetch_assoc($feed_result)) {
70 $feed = array();
71 $feed['id'] = 'FEED:' . $feed_line['id'];
2ecd2df5 72 $feed['bare_id'] = (int)$feed_line['id'];
2a060a94
AD
73 $feed['name'] = $feed_line['title'];
74 $feed['checkbox'] = false;
2ecd2df5 75 $feed['unread'] = 0;
2a060a94
AD
76 $feed['error'] = $feed_line['last_error'];
77 $feed['icon'] = getFeedIcon($feed_line['id']);
78 $feed['param'] = make_local_datetime($this->link,
79 $feed_line['last_updated'], true);
80
81 array_push($items, $feed);
82 }
83
84 return $items;
85 }
86
afcfe6ca
AD
87 function getfeedtree() {
88
89 $search = $_SESSION["prefs_feed_search"];
90
91 if ($search) $search_qpart = " AND LOWER(title) LIKE LOWER('%$search%')";
92
93 $root = array();
94 $root['id'] = 'root';
95 $root['name'] = __('Feeds');
96 $root['items'] = array();
97 $root['type'] = 'category';
98
2ecd2df5
AD
99 $enable_cats = get_pref($this->link, 'ENABLE_FEED_CATS');
100
101 if ($_REQUEST['mode'] == 2) {
102
103 if ($enable_cats) {
104 $cat_hidden = get_pref($this->link, "_COLLAPSED_SPECIAL");
105 $cat = $this->feedlist_init_cat(-1, $cat_hidden);
106 } else {
107 $cat['items'] = array();
108 }
109
110 foreach (array(-4, -3, -1, -2, 0) as $i) {
111 array_push($cat['items'], $this->feedlist_init_feed($i));
112 }
113
114 if ($enable_cats) {
115 array_push($root['items'], $cat);
116 } else {
117 $root['items'] = array_merge($root['items'], $cat['items']);
118 }
afcfe6ca 119
2ecd2df5
AD
120 $result = db_query($this->link, "SELECT * FROM
121 ttrss_labels2 WHERE owner_uid = ".$_SESSION['uid']." ORDER by caption");
122
123 if (db_num_rows($result) > 0) {
124
125 if (get_pref($this->link, 'ENABLE_FEED_CATS')) {
126 $cat_hidden = get_pref($this->link, "_COLLAPSED_LABELS");
127 $cat = $this->feedlist_init_cat(-2, $cat_hidden);
128 } else {
129 $cat['items'] = array();
130 }
131
132 while ($line = db_fetch_assoc($result)) {
133
134 $label_id = -$line['id'] - 11;
135 $count = getFeedUnread($this->link, $label_id);
136
137 $feed = $this->feedlist_init_feed($label_id, false, $count);
138
139 $feed['fg_color'] = $line['fg_color'];
140 $feed['bg_color'] = $line['bg_color'];
141
142 array_push($cat['items'], $feed);
143 }
144
145 if ($enable_cats) {
146 array_push($root['items'], $cat);
147 } else {
148 $root['items'] = array_merge($root['items'], $cat['items']);
149 }
150 }
151 }
152
153 if ($enable_cats) {
154 $show_empty_cats = $_REQUEST['mode'] != 2 &&
155 get_pref($this->link, '_PREFS_SHOW_EMPTY_CATS');
156
157 $result = db_query($this->link, "SELECT id, title, collapsed FROM ttrss_feed_categories
2a060a94 158 WHERE owner_uid = " . $_SESSION["uid"] . " AND parent_cat IS NULL ORDER BY order_id, title");
afcfe6ca
AD
159
160 while ($line = db_fetch_assoc($result)) {
161 $cat = array();
162 $cat['id'] = 'CAT:' . $line['id'];
2ecd2df5 163 $cat['bare_id'] = (int)$line['id'];
afcfe6ca
AD
164 $cat['name'] = $line['title'];
165 $cat['items'] = array();
166 $cat['checkbox'] = false;
2ecd2df5 167 $cat['hidden'] = sql_bool_to_bool($line['collapsed']);
afcfe6ca 168 $cat['type'] = 'category';
2ecd2df5 169 $cat['unread'] = 0;
afcfe6ca 170
2a060a94 171 $cat['items'] = $this->get_category_items($line['id']);
afcfe6ca
AD
172
173 $cat['param'] = T_sprintf('(%d feeds)', count($cat['items']));
174
5b7bd238 175 if (count($cat['items']) > 0 || $show_empty_cats)
afcfe6ca
AD
176 array_push($root['items'], $cat);
177
178 $root['param'] += count($cat['items']);
179 }
180
181 /* Uncategorized is a special case */
182
183 $cat = array();
184 $cat['id'] = 'CAT:0';
185 $cat['bare_id'] = 0;
186 $cat['name'] = __("Uncategorized");
187 $cat['items'] = array();
2ecd2df5 188 $cat['hidden'] = get_pref($this->link, "_COLLAPSED_UNCAT");
afcfe6ca
AD
189 $cat['type'] = 'category';
190 $cat['checkbox'] = false;
2ecd2df5 191 $cat['unread'] = 0;
afcfe6ca
AD
192
193 $feed_result = db_query($this->link, "SELECT id, title,last_error,
194 ".SUBSTRING_FOR_DATE."(last_updated,1,19) AS last_updated
195 FROM ttrss_feeds
196 WHERE cat_id IS NULL AND owner_uid = ".$_SESSION["uid"].
197 "$search_qpart ORDER BY order_id, title");
198
199 while ($feed_line = db_fetch_assoc($feed_result)) {
200 $feed = array();
201 $feed['id'] = 'FEED:' . $feed_line['id'];
2ecd2df5 202 $feed['bare_id'] = (int)$feed_line['id'];
afcfe6ca
AD
203 $feed['name'] = $feed_line['title'];
204 $feed['checkbox'] = false;
205 $feed['error'] = $feed_line['last_error'];
206 $feed['icon'] = getFeedIcon($feed_line['id']);
207 $feed['param'] = make_local_datetime($this->link,
208 $feed_line['last_updated'], true);
2ecd2df5
AD
209 $feed['unread'] = 0;
210 $feed['type'] = 'feed';
afcfe6ca
AD
211
212 array_push($cat['items'], $feed);
213 }
214
215 $cat['param'] = T_sprintf('(%d feeds)', count($cat['items']));
216
5b7bd238 217 if (count($cat['items']) > 0 || $show_empty_cats)
afcfe6ca
AD
218 array_push($root['items'], $cat);
219
220 $root['param'] += count($cat['items']);
221 $root['param'] = T_sprintf('(%d feeds)', $root['param']);
222
223 } else {
224 $feed_result = db_query($this->link, "SELECT id, title, last_error,
225 ".SUBSTRING_FOR_DATE."(last_updated,1,19) AS last_updated
226 FROM ttrss_feeds
227 WHERE owner_uid = ".$_SESSION["uid"].
228 "$search_qpart ORDER BY order_id, title");
229
230 while ($feed_line = db_fetch_assoc($feed_result)) {
231 $feed = array();
232 $feed['id'] = 'FEED:' . $feed_line['id'];
2ecd2df5 233 $feed['bare_id'] = (int)$feed_line['id'];
afcfe6ca
AD
234 $feed['name'] = $feed_line['title'];
235 $feed['checkbox'] = false;
236 $feed['error'] = $feed_line['last_error'];
237 $feed['icon'] = getFeedIcon($feed_line['id']);
238 $feed['param'] = make_local_datetime($this->link,
239 $feed_line['last_updated'], true);
2ecd2df5
AD
240 $feed['unread'] = 0;
241 $feed['type'] = 'feed';
afcfe6ca
AD
242
243 array_push($root['items'], $feed);
244 }
245
246 $root['param'] = T_sprintf('(%d feeds)', count($root['items']));
afcfe6ca
AD
247 }
248
249 $fl = array();
250 $fl['identifier'] = 'id';
251 $fl['label'] = 'name';
2ecd2df5
AD
252
253 if ($_REQUEST['mode'] != 2) {
254 $fl['items'] = array($root);
255 } else {
256 $fl['items'] =& $root['items'];
257 }
afcfe6ca
AD
258
259 print json_encode($fl);
260 return;
261 }
262
263 function catsortreset() {
264 db_query($this->link, "UPDATE ttrss_feed_categories
265 SET order_id = 0 WHERE owner_uid = " . $_SESSION["uid"]);
266 return;
267 }
268
269 function feedsortreset() {
270 db_query($this->link, "UPDATE ttrss_feeds
271 SET order_id = 0 WHERE owner_uid = " . $_SESSION["uid"]);
272 return;
273 }
274
5b7bd238
AD
275 function togglehiddenfeedcats() {
276 set_pref($this->link, '_PREFS_SHOW_EMPTY_CATS',
277 (get_pref($this->link, '_PREFS_SHOW_EMPTY_CATS') ? 'false' : 'true'));
278 }
279
2a060a94
AD
280 private function process_category_order($data_map, $item_id, $parent_id = false) {
281# print "C: $item_id P: $parent_id\n";
282 $bare_id = substr($item_id, strpos($item_id, ':')+1);
283
284 if ($item_id != 'root') {
285 if ($parent_id && $parent_id != 'root') {
286 $parent_bare_id = substr($parent_id, strpos($parent_id, ':')+1);
287 $parent_qpart = db_escape_string($parent_bare_id);
288 } else {
289 $parent_qpart = 'NULL';
290 }
291
292 db_query($this->link, "UPDATE ttrss_feed_categories
293 SET parent_cat = $parent_qpart WHERE id = '$bare_id' AND
294 owner_uid = " . $_SESSION["uid"]);
295 }
296
297 $order_id = 0;
298
299 $cat = $data_map[$item_id];
300
301 if ($cat && is_array($cat)) {
302 foreach ($cat as $item) {
303 $id = $item['_reference'];
304 $bare_id = substr($id, strpos($id, ':')+1);
305
306# print "[$order_id] $id/$bare_id\n";
307
308 if ($item['_reference']) {
309
310 if (strpos($id, "FEED") === 0) {
311
312 db_query($this->link, "UPDATE ttrss_feeds
313 SET order_id = '$order_id' WHERE id = '$bare_id' AND
314 owner_uid = " . $_SESSION["uid"]);
315
316 } else if (strpos($id, "CAT:") === 0) {
317 $this->process_category_order(&$data_map, $item['_reference'], $item_id);
318
319 if ($item_id != 'root') {
320 $parent_qpart = db_escape_string($bare_id);
321 } else {
322 $parent_qpart = 'NULL';
323 }
324
325 db_query($this->link, "UPDATE ttrss_feed_categories
326 SET order_id = '$order_id' WHERE id = '$bare_id' AND
327 owner_uid = " . $_SESSION["uid"]);
328 }
329 }
330
331 ++$order_id;
332 }
333 }
334 }
335
afcfe6ca
AD
336 function savefeedorder() {
337 $data = json_decode($_POST['payload'], true);
338
2a060a94
AD
339 #file_put_contents("/tmp/saveorder.json", $_POST['payload']);
340 #$data = json_decode(file_get_contents("/tmp/saveorder.json"), true);
341
afcfe6ca
AD
342 if (is_array($data) && is_array($data['items'])) {
343 $cat_order_id = 0;
344
345 $data_map = array();
2a060a94 346 $root_item = false;
afcfe6ca
AD
347
348 foreach ($data['items'] as $item) {
349
2a060a94 350# if ($item['id'] != 'root') {
afcfe6ca
AD
351 if (is_array($item['items'])) {
352 if (isset($item['items']['_reference'])) {
353 $data_map[$item['id']] = array($item['items']);
354 } else {
355 $data_map[$item['id']] =& $item['items'];
356 }
357 }
2a060a94
AD
358 if ($item['id'] == 'root') {
359 $root_item = $item['id'];
afcfe6ca
AD
360 }
361 }
362
2a060a94
AD
363 $this->process_category_order(&$data_map, $root_item);
364
365 /* foreach ($data['items'][0]['items'] as $item) {
afcfe6ca
AD
366 $id = $item['_reference'];
367 $bare_id = substr($id, strpos($id, ':')+1);
368
369 ++$cat_order_id;
370
371 if ($bare_id > 0) {
372 db_query($this->link, "UPDATE ttrss_feed_categories
373 SET order_id = '$cat_order_id' WHERE id = '$bare_id' AND
374 owner_uid = " . $_SESSION["uid"]);
375 }
376
377 $feed_order_id = 0;
378
379 if (is_array($data_map[$id])) {
380 foreach ($data_map[$id] as $feed) {
381 $id = $feed['_reference'];
382 $feed_id = substr($id, strpos($id, ':')+1);
383
384 if ($bare_id != 0)
385 $cat_query = "cat_id = '$bare_id'";
386 else
387 $cat_query = "cat_id = NULL";
388
389 db_query($this->link, "UPDATE ttrss_feeds
390 SET order_id = '$feed_order_id',
391 $cat_query
392 WHERE id = '$feed_id' AND
393 owner_uid = " . $_SESSION["uid"]);
394
395 ++$feed_order_id;
396 }
397 }
2a060a94 398 } */
afcfe6ca
AD
399 }
400
401 return;
402 }
403
404 function removeicon() {
405 $feed_id = db_escape_string($_REQUEST["feed_id"]);
406
407 $result = db_query($this->link, "SELECT id FROM ttrss_feeds
408 WHERE id = '$feed_id' AND owner_uid = ". $_SESSION["uid"]);
409
410 if (db_num_rows($result) != 0) {
411 unlink(ICONS_DIR . "/$feed_id.ico");
412 }
413
414 return;
415 }
416
417 function uploadicon() {
418 $icon_file = $_FILES['icon_file']['tmp_name'];
419 $feed_id = db_escape_string($_REQUEST["feed_id"]);
420
421 if (is_file($icon_file) && $feed_id) {
422 if (filesize($icon_file) < 20000) {
423
424 $result = db_query($this->link, "SELECT id FROM ttrss_feeds
425 WHERE id = '$feed_id' AND owner_uid = ". $_SESSION["uid"]);
426
427 if (db_num_rows($result) != 0) {
428 unlink(ICONS_DIR . "/$feed_id.ico");
429 move_uploaded_file($icon_file, ICONS_DIR . "/$feed_id.ico");
430 $rc = 0;
431 } else {
432 $rc = 2;
433 }
434 } else {
435 $rc = 1;
436 }
437 } else {
438 $rc = 2;
439 }
440
441 print "<script type=\"text/javascript\">";
442 print "parent.uploadIconHandler($rc);";
443 print "</script>";
444 return;
445 }
446
447 function editfeed() {
448 global $purge_intervals;
449 global $update_intervals;
450 global $update_methods;
451
452 $feed_id = db_escape_string($_REQUEST["id"]);
453
454 $result = db_query($this->link,
455 "SELECT * FROM ttrss_feeds WHERE id = '$feed_id' AND
456 owner_uid = " . $_SESSION["uid"]);
457
458 $title = htmlspecialchars(db_fetch_result($result,
459 0, "title"));
460
461 print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"id\" value=\"$feed_id\">";
462 print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"op\" value=\"pref-feeds\">";
463 print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"method\" value=\"editSave\">";
464
465 print "<div class=\"dlgSec\">".__("Feed")."</div>";
466 print "<div class=\"dlgSecCont\">";
467
468 /* Title */
469
470 print "<input dojoType=\"dijit.form.ValidationTextBox\" required=\"1\"
471 placeHolder=\"".__("Feed Title")."\"
472 style=\"font-size : 16px; width: 20em\" name=\"title\" value=\"$title\">";
473
474 /* Feed URL */
475
476 $feed_url = db_fetch_result($result, 0, "feed_url");
477 $feed_url = htmlspecialchars(db_fetch_result($result,
478 0, "feed_url"));
479
480 print "<hr/>";
481
482 print __('URL:') . " ";
483 print "<input dojoType=\"dijit.form.ValidationTextBox\" required=\"1\"
484 placeHolder=\"".__("Feed URL")."\"
485 regExp='^(http|https)://.*' style=\"width : 20em\"
486 name=\"feed_url\" value=\"$feed_url\">";
487
488 $last_error = db_fetch_result($result, 0, "last_error");
489
490 if ($last_error) {
491 print "&nbsp;<span title=\"".htmlspecialchars($last_error)."\"
492 class=\"feed_error\">(error)</span>";
493
494 }
495
496 /* Category */
497
498 if (get_pref($this->link, 'ENABLE_FEED_CATS')) {
499
500 $cat_id = db_fetch_result($result, 0, "cat_id");
501
502 print "<hr/>";
503
504 print __('Place in category:') . " ";
505
506 print_feed_cat_select($this->link, "cat_id", $cat_id,
507 'dojoType="dijit.form.Select"');
508 }
509
510 print "</div>";
511
512 print "<div class=\"dlgSec\">".__("Update")."</div>";
513 print "<div class=\"dlgSecCont\">";
514
515 /* Update Interval */
516
517 $update_interval = db_fetch_result($result, 0, "update_interval");
518
519 print_select_hash("update_interval", $update_interval, $update_intervals,
520 'dojoType="dijit.form.Select"');
521
522 /* Update method */
523
524 $update_method = db_fetch_result($result, 0, "update_method",
525 'dojoType="dijit.form.Select"');
526
527 print " " . __('using') . " ";
528 print_select_hash("update_method", $update_method, $update_methods,
529 'dojoType="dijit.form.Select"');
530
531 $purge_interval = db_fetch_result($result, 0, "purge_interval");
532
533
534 /* Purge intl */
535
536 print "<hr/>";
537 print __('Article purging:') . " ";
538
539 print_select_hash("purge_interval", $purge_interval, $purge_intervals,
540 'dojoType="dijit.form.Select" ' .
541 ((FORCE_ARTICLE_PURGE == 0) ? "" : 'disabled="1"'));
542
543 print "</div>";
544 print "<div class=\"dlgSec\">".__("Authentication")."</div>";
545 print "<div class=\"dlgSecCont\">";
546
547 $auth_login = htmlspecialchars(db_fetch_result($result, 0, "auth_login"));
548
549 print "<input dojoType=\"dijit.form.TextBox\" id=\"feedEditDlg_login\"
550 placeHolder=\"".__("Login")."\"
551 name=\"auth_login\" value=\"$auth_login\"><hr/>";
552
553 $auth_pass = htmlspecialchars(db_fetch_result($result, 0, "auth_pass"));
554
555 print "<input dojoType=\"dijit.form.TextBox\" type=\"password\" name=\"auth_pass\"
556 placeHolder=\"".__("Password")."\"
557 value=\"$auth_pass\">";
558
559 print "<div dojoType=\"dijit.Tooltip\" connectId=\"feedEditDlg_login\" position=\"below\">
560 ".__('<b>Hint:</b> you need to fill in your login information if your feed requires authentication, except for Twitter feeds.')."
561 </div>";
562
563 print "</div>";
564 print "<div class=\"dlgSec\">".__("Options")."</div>";
565 print "<div class=\"dlgSecCont\">";
566
567 $private = sql_bool_to_bool(db_fetch_result($result, 0, "private"));
568
569 if ($private) {
570 $checked = "checked=\"1\"";
571 } else {
572 $checked = "";
573 }
574
575 print "<input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" name=\"private\" id=\"private\"
576 $checked>&nbsp;<label for=\"private\">".__('Hide from Popular feeds')."</label>";
577
578 $rtl_content = sql_bool_to_bool(db_fetch_result($result, 0, "rtl_content"));
579
580 if ($rtl_content) {
581 $checked = "checked=\"1\"";
582 } else {
583 $checked = "";
584 }
585
586 print "<hr/><input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" id=\"rtl_content\" name=\"rtl_content\"
587 $checked>&nbsp;<label for=\"rtl_content\">".__('Right-to-left content')."</label>";
588
589 $include_in_digest = sql_bool_to_bool(db_fetch_result($result, 0, "include_in_digest"));
590
591 if ($include_in_digest) {
592 $checked = "checked=\"1\"";
593 } else {
594 $checked = "";
595 }
596
597 print "<hr/><input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" id=\"include_in_digest\"
598 name=\"include_in_digest\"
599 $checked>&nbsp;<label for=\"include_in_digest\">".__('Include in e-mail digest')."</label>";
600
601
602 $always_display_enclosures = sql_bool_to_bool(db_fetch_result($result, 0, "always_display_enclosures"));
603
604 if ($always_display_enclosures) {
605 $checked = "checked";
606 } else {
607 $checked = "";
608 }
609
610 print "<hr/><input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" id=\"always_display_enclosures\"
611 name=\"always_display_enclosures\"
612 $checked>&nbsp;<label for=\"always_display_enclosures\">".__('Always display image attachments')."</label>";
613
614
615 $cache_images = sql_bool_to_bool(db_fetch_result($result, 0, "cache_images"));
616
617 if ($cache_images) {
618 $checked = "checked=\"1\"";
619 } else {
620 $checked = "";
621 }
622
3c696512
AD
623 print "<hr/><input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" id=\"cache_images\"
624 name=\"cache_images\"
afcfe6ca 625 $checked>&nbsp;<label for=\"cache_images\">".
3c696512 626 __('Cache images locally')."</label>";
afcfe6ca
AD
627
628 $mark_unread_on_update = sql_bool_to_bool(db_fetch_result($result, 0, "mark_unread_on_update"));
629
630 if ($mark_unread_on_update) {
631 $checked = "checked";
632 } else {
633 $checked = "";
634 }
635
636 print "<hr/><input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" id=\"mark_unread_on_update\"
637 name=\"mark_unread_on_update\"
638 $checked>&nbsp;<label for=\"mark_unread_on_update\">".__('Mark updated articles as unread')."</label>";
639
640 $update_on_checksum_change = sql_bool_to_bool(db_fetch_result($result, 0, "update_on_checksum_change"));
641
642 if ($update_on_checksum_change) {
643 $checked = "checked";
644 } else {
645 $checked = "";
646 }
647
648 print "<hr/><input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" id=\"update_on_checksum_change\"
649 name=\"update_on_checksum_change\"
650 $checked>&nbsp;<label for=\"update_on_checksum_change\">".__('Mark posts as updated on content change')."</label>";
651
652 print "</div>";
653
654 /* Icon */
655
656 print "<div class=\"dlgSec\">".__("Icon")."</div>";
657 print "<div class=\"dlgSecCont\">";
658
659 print "<iframe name=\"icon_upload_iframe\"
660 style=\"width: 400px; height: 100px; display: none;\"></iframe>";
661
662 print "<form style='display : block' target=\"icon_upload_iframe\"
663 enctype=\"multipart/form-data\" method=\"POST\"
664 action=\"backend.php\">
665 <input id=\"icon_file\" size=\"10\" name=\"icon_file\" type=\"file\">
666 <input type=\"hidden\" name=\"op\" value=\"pref-feeds\">
667 <input type=\"hidden\" name=\"feed_id\" value=\"$feed_id\">
668 <input type=\"hidden\" name=\"method\" value=\"uploadicon\">
669 <button dojoType=\"dijit.form.Button\" onclick=\"return uploadFeedIcon();\"
670 type=\"submit\">".__('Replace')."</button>
671 <button dojoType=\"dijit.form.Button\" onclick=\"return removeFeedIcon($feed_id);\"
672 type=\"submit\">".__('Remove')."</button>
673 </form>";
674
675 print "</div>";
676
677 $title = htmlspecialchars($title, ENT_QUOTES);
678
679 print "<div class='dlgButtons'>
680 <div style=\"float : left\">
681 <button dojoType=\"dijit.form.Button\" onclick='return unsubscribeFeed($feed_id, \"$title\")'>".
682 __('Unsubscribe')."</button>";
683
684 if (PUBSUBHUBBUB_ENABLED) {
685 $pubsub_state = db_fetch_result($result, 0, "pubsub_state");
686 $pubsub_btn_disabled = ($pubsub_state == 2) ? "" : "disabled=\"1\"";
687
688 print "<button dojoType=\"dijit.form.Button\" id=\"pubsubReset_Btn\" $pubsub_btn_disabled
689 onclick='return resetPubSub($feed_id, \"$title\")'>".__('Resubscribe to push updates').
690 "</button>";
691 }
692
693 print "</div>";
694
695 print "<div dojoType=\"dijit.Tooltip\" connectId=\"pubsubReset_Btn\" position=\"below\">".
696 __('Resets PubSubHubbub subscription status for push-enabled feeds.')."</div>";
697
698 print "<button dojoType=\"dijit.form.Button\" onclick=\"return dijit.byId('feedEditDlg').execute()\">".__('Save')."</button>
699 <button dojoType=\"dijit.form.Button\" onclick=\"return dijit.byId('feedEditDlg').hide()\">".__('Cancel')."</button>
700 </div>";
701
702 return;
703 }
704
705 function editfeeds() {
706 global $purge_intervals;
707 global $update_intervals;
708 global $update_methods;
46da73c2 709
afcfe6ca
AD
710 $feed_ids = db_escape_string($_REQUEST["ids"]);
711
ca6a0741
AD
712 print "<div class=\"dialogNotice\">" . __("Enable the options you wish to apply using checkboxes on the right:") . "</div>";
713
afcfe6ca
AD
714 print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"ids\" value=\"$feed_ids\">";
715 print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"op\" value=\"pref-feeds\">";
716 print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"method\" value=\"batchEditSave\">";
717
718 print "<div class=\"dlgSec\">".__("Feed")."</div>";
719 print "<div class=\"dlgSecCont\">";
720
721 /* Title */
722
723 print "<input dojoType=\"dijit.form.ValidationTextBox\"
724 disabled=\"1\" style=\"font-size : 16px; width : 20em;\" required=\"1\"
725 name=\"title\" value=\"$title\">";
726
727 $this->batch_edit_cbox("title");
728
729 /* Feed URL */
730
731 print "<br/>";
732
733 print __('URL:') . " ";
734 print "<input dojoType=\"dijit.form.ValidationTextBox\" disabled=\"1\"
735 required=\"1\" regExp='^(http|https)://.*' style=\"width : 20em\"
736 name=\"feed_url\" value=\"$feed_url\">";
737
738 $this->batch_edit_cbox("feed_url");
739
740 /* Category */
741
742 if (get_pref($this->link, 'ENABLE_FEED_CATS')) {
743
744 print "<br/>";
745
746 print __('Place in category:') . " ";
747
748 print_feed_cat_select($this->link, "cat_id", $cat_id,
749 'disabled="1" dojoType="dijit.form.Select"');
750
751 $this->batch_edit_cbox("cat_id");
752
753 }
754
755 print "</div>";
756
757 print "<div class=\"dlgSec\">".__("Update")."</div>";
758 print "<div class=\"dlgSecCont\">";
759
760 /* Update Interval */
761
762 print_select_hash("update_interval", $update_interval, $update_intervals,
763 'disabled="1" dojoType="dijit.form.Select"');
764
765 $this->batch_edit_cbox("update_interval");
766
767 /* Update method */
768
769 print " " . __('using') . " ";
770 print_select_hash("update_method", $update_method, $update_methods,
771 'disabled="1" dojoType="dijit.form.Select"');
772 $this->batch_edit_cbox("update_method");
773
774 /* Purge intl */
775
776 if (FORCE_ARTICLE_PURGE == 0) {
777
778 print "<br/>";
779
780 print __('Article purging:') . " ";
781
782 print_select_hash("purge_interval", $purge_interval, $purge_intervals,
783 'disabled="1" dojoType="dijit.form.Select"');
784
785 $this->batch_edit_cbox("purge_interval");
786 }
787
788 print "</div>";
789 print "<div class=\"dlgSec\">".__("Authentication")."</div>";
790 print "<div class=\"dlgSecCont\">";
791
792 print "<input dojoType=\"dijit.form.TextBox\"
793 placeHolder=\"".__("Login")."\" disabled=\"1\"
794 name=\"auth_login\" value=\"$auth_login\">";
795
796 $this->batch_edit_cbox("auth_login");
797
798 print "<br/><input dojoType=\"dijit.form.TextBox\" type=\"password\" name=\"auth_pass\"
799 placeHolder=\"".__("Password")."\" disabled=\"1\"
800 value=\"$auth_pass\">";
801
802 $this->batch_edit_cbox("auth_pass");
803
804 print "</div>";
805 print "<div class=\"dlgSec\">".__("Options")."</div>";
806 print "<div class=\"dlgSecCont\">";
807
808 print "<input disabled=\"1\" type=\"checkbox\" name=\"private\" id=\"private\"
809 dojoType=\"dijit.form.CheckBox\">&nbsp;<label id=\"private_l\" class='insensitive' for=\"private\">".__('Hide from Popular feeds')."</label>";
810
811 print "&nbsp;"; $this->batch_edit_cbox("private", "private_l");
812
813 print "<br/><input disabled=\"1\" type=\"checkbox\" id=\"rtl_content\" name=\"rtl_content\"
814 dojoType=\"dijit.form.CheckBox\">&nbsp;<label class='insensitive' id=\"rtl_content_l\" for=\"rtl_content\">".__('Right-to-left content')."</label>";
815
816 print "&nbsp;"; $this->batch_edit_cbox("rtl_content", "rtl_content_l");
817
818 print "<br/><input disabled=\"1\" type=\"checkbox\" id=\"include_in_digest\"
819 name=\"include_in_digest\"
820 dojoType=\"dijit.form.CheckBox\">&nbsp;<label id=\"include_in_digest_l\" class='insensitive' for=\"include_in_digest\">".__('Include in e-mail digest')."</label>";
821
822 print "&nbsp;"; $this->batch_edit_cbox("include_in_digest", "include_in_digest_l");
823
824 print "<br/><input disabled=\"1\" type=\"checkbox\" id=\"always_display_enclosures\"
825 name=\"always_display_enclosures\"
826 dojoType=\"dijit.form.CheckBox\">&nbsp;<label id=\"always_display_enclosures_l\" class='insensitive' for=\"always_display_enclosures\">".__('Always display image attachments')."</label>";
827
828 print "&nbsp;"; $this->batch_edit_cbox("always_display_enclosures", "always_display_enclosures_l");
829
3c696512
AD
830 print "<br/><input disabled=\"1\" type=\"checkbox\" id=\"cache_images\"
831 name=\"cache_images\"
832 dojoType=\"dijit.form.CheckBox\">&nbsp;<label class='insensitive' id=\"cache_images_l\"
833 for=\"cache_images\">".
834 __('Cache images locally')."</label>";
afcfe6ca 835
3c696512 836 print "&nbsp;"; $this->batch_edit_cbox("cache_images", "cache_images_l");
afcfe6ca
AD
837
838 print "<br/><input disabled=\"1\" type=\"checkbox\" id=\"mark_unread_on_update\"
839 name=\"mark_unread_on_update\"
840 dojoType=\"dijit.form.CheckBox\">&nbsp;<label id=\"mark_unread_on_update_l\" class='insensitive' for=\"mark_unread_on_update\">".__('Mark updated articles as unread')."</label>";
841
842 print "&nbsp;"; $this->batch_edit_cbox("mark_unread_on_update", "mark_unread_on_update_l");
843
844 print "<br/><input disabled=\"1\" type=\"checkbox\" id=\"update_on_checksum_change\"
845 name=\"update_on_checksum_change\"
846 dojoType=\"dijit.form.CheckBox\">&nbsp;<label id=\"update_on_checksum_change_l\" class='insensitive' for=\"update_on_checksum_change\">".__('Mark posts as updated on content change')."</label>";
847
848 print "&nbsp;"; $this->batch_edit_cbox("update_on_checksum_change", "update_on_checksum_change_l");
849
850 print "</div>";
851
852 print "<div class='dlgButtons'>
853 <button dojoType=\"dijit.form.Button\"
854 onclick=\"return dijit.byId('feedEditDlg').execute()\">".
855 __('Save')."</button>
856 <button dojoType=\"dijit.form.Button\"
857 onclick=\"return dijit.byId('feedEditDlg').hide()\">".
858 __('Cancel')."</button>
859 </div>";
860
861 return;
862 }
863
864 function batchEditSave() {
3a76e2a2 865 return $this->editsaveops(true);
afcfe6ca 866 }
46da73c2 867
afcfe6ca 868 function editSave() {
3a76e2a2 869 return $this->editsaveops(false);
afcfe6ca 870 }
46da73c2
AD
871
872 function editsaveops($batch) {
873
afcfe6ca
AD
874 $feed_title = db_escape_string(trim($_POST["title"]));
875 $feed_link = db_escape_string(trim($_POST["feed_url"]));
876 $upd_intl = (int) db_escape_string($_POST["update_interval"]);
877 $purge_intl = (int) db_escape_string($_POST["purge_interval"]);
878 $feed_id = (int) db_escape_string($_POST["id"]); /* editSave */
879 $feed_ids = db_escape_string($_POST["ids"]); /* batchEditSave */
880 $cat_id = (int) db_escape_string($_POST["cat_id"]);
881 $auth_login = db_escape_string(trim($_POST["auth_login"]));
882 $auth_pass = db_escape_string(trim($_POST["auth_pass"]));
883 $private = checkbox_to_sql_bool(db_escape_string($_POST["private"]));
884 $rtl_content = checkbox_to_sql_bool(db_escape_string($_POST["rtl_content"]));
885 $include_in_digest = checkbox_to_sql_bool(
886 db_escape_string($_POST["include_in_digest"]));
887 $cache_images = checkbox_to_sql_bool(
888 db_escape_string($_POST["cache_images"]));
889 $update_method = (int) db_escape_string($_POST["update_method"]);
890
891 $always_display_enclosures = checkbox_to_sql_bool(
892 db_escape_string($_POST["always_display_enclosures"]));
893
894 $mark_unread_on_update = checkbox_to_sql_bool(
895 db_escape_string($_POST["mark_unread_on_update"]));
896
897 $update_on_checksum_change = checkbox_to_sql_bool(
898 db_escape_string($_POST["update_on_checksum_change"]));
899
900 if (get_pref($this->link, 'ENABLE_FEED_CATS')) {
901 if ($cat_id && $cat_id != 0) {
902 $category_qpart = "cat_id = '$cat_id',";
903 $category_qpart_nocomma = "cat_id = '$cat_id'";
904 } else {
905 $category_qpart = 'cat_id = NULL,';
906 $category_qpart_nocomma = 'cat_id = NULL';
907 }
908 } else {
909 $category_qpart = "";
910 $category_qpart_nocomma = "";
911 }
912
3c696512 913 $cache_images_qpart = "cache_images = $cache_images,";
afcfe6ca 914
3a76e2a2 915 if (!$batch) {
afcfe6ca
AD
916
917 $result = db_query($this->link, "UPDATE ttrss_feeds SET
918 $category_qpart
919 title = '$feed_title', feed_url = '$feed_link',
920 update_interval = '$upd_intl',
921 purge_interval = '$purge_intl',
922 auth_login = '$auth_login',
923 auth_pass = '$auth_pass',
924 private = $private,
925 rtl_content = $rtl_content,
926 $cache_images_qpart
927 include_in_digest = $include_in_digest,
928 always_display_enclosures = $always_display_enclosures,
929 mark_unread_on_update = $mark_unread_on_update,
930 update_on_checksum_change = $update_on_checksum_change,
931 update_method = '$update_method'
932 WHERE id = '$feed_id' AND owner_uid = " . $_SESSION["uid"]);
933
3a76e2a2 934 } else {
afcfe6ca
AD
935 $feed_data = array();
936
937 foreach (array_keys($_POST) as $k) {
938 if ($k != "op" && $k != "method" && $k != "ids") {
939 $feed_data[$k] = $_POST[$k];
940 }
941 }
942
943 db_query($this->link, "BEGIN");
944
945 foreach (array_keys($feed_data) as $k) {
946
947 $qpart = "";
948
949 switch ($k) {
950 case "title":
951 $qpart = "title = '$feed_title'";
952 break;
953
954 case "feed_url":
955 $qpart = "feed_url = '$feed_link'";
956 break;
957
958 case "update_interval":
959 $qpart = "update_interval = '$upd_intl'";
960 break;
961
962 case "purge_interval":
963 $qpart = "purge_interval = '$purge_intl'";
964 break;
965
966 case "auth_login":
967 $qpart = "auth_login = '$auth_login'";
968 break;
969
970 case "auth_pass":
971 $qpart = "auth_pass = '$auth_pass'";
972 break;
973
974 case "private":
a498d18b 975 $qpart = "private = $private";
afcfe6ca
AD
976 break;
977
978 case "include_in_digest":
a498d18b 979 $qpart = "include_in_digest = $include_in_digest";
afcfe6ca
AD
980 break;
981
982 case "always_display_enclosures":
a498d18b 983 $qpart = "always_display_enclosures = $always_display_enclosures";
afcfe6ca
AD
984 break;
985
986 case "mark_unread_on_update":
a498d18b 987 $qpart = "mark_unread_on_update = $mark_unread_on_update";
afcfe6ca
AD
988 break;
989
990 case "update_on_checksum_change":
a498d18b 991 $qpart = "update_on_checksum_change = $update_on_checksum_change";
afcfe6ca
AD
992 break;
993
994 case "cache_images":
a498d18b 995 $qpart = "cache_images = $cache_images";
afcfe6ca
AD
996 break;
997
998 case "rtl_content":
a498d18b 999 $qpart = "rtl_content = $rtl_content";
afcfe6ca
AD
1000 break;
1001
1002 case "update_method":
1003 $qpart = "update_method = '$update_method'";
1004 break;
1005
1006 case "cat_id":
1007 $qpart = $category_qpart_nocomma;
1008 break;
1009
1010 }
1011
1012 if ($qpart) {
1013 db_query($this->link,
1014 "UPDATE ttrss_feeds SET $qpart WHERE id IN ($feed_ids)
1015 AND owner_uid = " . $_SESSION["uid"]);
1016 print "<br/>";
1017 }
1018 }
1019
1020 db_query($this->link, "COMMIT");
1021 }
1022 return;
1023 }
1024
1025 function resetPubSub() {
1026
1027 $ids = db_escape_string($_REQUEST["ids"]);
1028
1029 db_query($this->link, "UPDATE ttrss_feeds SET pubsub_state = 0 WHERE id IN ($ids)
1030 AND owner_uid = " . $_SESSION["uid"]);
1031
1032 return;
1033 }
1034
1035 function remove() {
1036
1037 $ids = split(",", db_escape_string($_REQUEST["ids"]));
1038
1039 foreach ($ids as $id) {
1040 remove_feed($this->link, $id, $_SESSION["uid"]);
1041 }
1042
1043 return;
1044 }
1045
1046 function clear() {
1047 $id = db_escape_string($_REQUEST["id"]);
1048 clear_feed_articles($this->link, $id);
1049 }
1050
1051 function rescore() {
1052 $ids = split(",", db_escape_string($_REQUEST["ids"]));
1053
1054 foreach ($ids as $id) {
1055
1056 $filters = load_filters($this->link, $id, $_SESSION["uid"], 6);
1057
1058 $result = db_query($this->link, "SELECT
1059 title, content, link, ref_id, author,".
1060 SUBSTRING_FOR_DATE."(updated, 1, 19) AS updated
1061 FROM
1062 ttrss_user_entries, ttrss_entries
1063 WHERE ref_id = id AND feed_id = '$id' AND
1064 owner_uid = " .$_SESSION['uid']."
1065 ");
1066
1067 $scores = array();
1068
1069 while ($line = db_fetch_assoc($result)) {
1070
1071 $tags = get_article_tags($this->link, $line["ref_id"]);
1072
1073 $article_filters = get_article_filters($filters, $line['title'],
1074 $line['content'], $line['link'], strtotime($line['updated']),
1075 $line['author'], $tags);
1076
1077 $new_score = calculate_article_score($article_filters);
1078
1079 if (!$scores[$new_score]) $scores[$new_score] = array();
1080
1081 array_push($scores[$new_score], $line['ref_id']);
1082 }
1083
1084 foreach (array_keys($scores) as $s) {
1085 if ($s > 1000) {
1086 db_query($this->link, "UPDATE ttrss_user_entries SET score = '$s',
1087 marked = true WHERE
1088 ref_id IN (" . join(',', $scores[$s]) . ")");
1089 } else if ($s < -500) {
1090 db_query($this->link, "UPDATE ttrss_user_entries SET score = '$s',
1091 unread = false WHERE
1092 ref_id IN (" . join(',', $scores[$s]) . ")");
1093 } else {
1094 db_query($this->link, "UPDATE ttrss_user_entries SET score = '$s' WHERE
1095 ref_id IN (" . join(',', $scores[$s]) . ")");
1096 }
1097 }
1098 }
1099
1100 print __("All done.");
1101
1102 }
1103
1104 function rescoreAll() {
1105
1106 $result = db_query($this->link,
1107 "SELECT id FROM ttrss_feeds WHERE owner_uid = " . $_SESSION['uid']);
1108
1109 while ($feed_line = db_fetch_assoc($result)) {
1110
1111 $id = $feed_line["id"];
1112
1113 $filters = load_filters($this->link, $id, $_SESSION["uid"], 6);
1114
1115 $tmp_result = db_query($this->link, "SELECT
1116 title, content, link, ref_id, author,".
1117 SUBSTRING_FOR_DATE."(updated, 1, 19) AS updated
1118 FROM
1119 ttrss_user_entries, ttrss_entries
1120 WHERE ref_id = id AND feed_id = '$id' AND
1121 owner_uid = " .$_SESSION['uid']."
1122 ");
1123
1124 $scores = array();
1125
1126 while ($line = db_fetch_assoc($tmp_result)) {
1127
1128 $tags = get_article_tags($this->link, $line["ref_id"]);
1129
1130 $article_filters = get_article_filters($filters, $line['title'],
1131 $line['content'], $line['link'], strtotime($line['updated']),
1132 $line['author'], $tags);
1133
1134 $new_score = calculate_article_score($article_filters);
1135
1136 if (!$scores[$new_score]) $scores[$new_score] = array();
1137
1138 array_push($scores[$new_score], $line['ref_id']);
1139 }
1140
1141 foreach (array_keys($scores) as $s) {
1142 if ($s > 1000) {
1143 db_query($this->link, "UPDATE ttrss_user_entries SET score = '$s',
1144 marked = true WHERE
1145 ref_id IN (" . join(',', $scores[$s]) . ")");
1146 } else {
1147 db_query($this->link, "UPDATE ttrss_user_entries SET score = '$s' WHERE
1148 ref_id IN (" . join(',', $scores[$s]) . ")");
1149 }
1150 }
1151 }
1152
1153 print __("All done.");
1154
1155 }
1156
1157 function add() {
1158 $feed_url = db_escape_string(trim($_REQUEST["feed_url"]));
1159 $cat_id = db_escape_string($_REQUEST["cat_id"]);
1160 $p_from = db_escape_string($_REQUEST["from"]);
1161
1162 /* only read authentication information from POST */
1163
1164 $auth_login = db_escape_string(trim($_POST["auth_login"]));
1165 $auth_pass = db_escape_string(trim($_POST["auth_pass"]));
1166
1167 if ($p_from != 'tt-rss') {
f4ce1d64 1168 header('Content-Type: text/html; charset=utf-8');
afcfe6ca
AD
1169 print "<html>
1170 <head>
1171 <title>Tiny Tiny RSS</title>
1172 <link rel=\"stylesheet\" type=\"text/css\" href=\"utility.css\">
f4ce1d64 1173 <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>
afcfe6ca
AD
1174 </head>
1175 <body>
093fae5e 1176 <img class=\"floatingLogo\" src=\"images/logo_wide.png\"
afcfe6ca
AD
1177 alt=\"Tiny Tiny RSS\"/>
1178 <h1>Subscribe to feed...</h1>";
1179 }
1180
1181 $rc = subscribe_to_feed($this->link, $feed_url, $cat_id, $auth_login, $auth_pass);
1182
1183 switch ($rc) {
1184 case 1:
1185 print_notice(T_sprintf("Subscribed to <b>%s</b>.", $feed_url));
1186 break;
1187 case 2:
1188 print_error(T_sprintf("Could not subscribe to <b>%s</b>.", $feed_url));
1189 break;
1190 case 3:
1191 print_error(T_sprintf("No feeds found in <b>%s</b>.", $feed_url));
1192 break;
1193 case 0:
1194 print_warning(T_sprintf("Already subscribed to <b>%s</b>.", $feed_url));
1195 break;
1196 case 4:
d50edb08 1197 print_notice(__("Multiple feed URLs found."));
afcfe6ca
AD
1198
1199 $feed_urls = get_feeds_from_html($feed_url);
1200 break;
1201 case 5:
1202 print_error(T_sprintf("Could not subscribe to <b>%s</b>.<br>Can't download the Feed URL.", $feed_url));
1203 break;
1204 }
1205
1206 if ($p_from != 'tt-rss') {
1207
1208 if ($feed_urls) {
1209
1210 print "<form action=\"backend.php\">";
1211 print "<input type=\"hidden\" name=\"op\" value=\"pref-feeds\">";
1212 print "<input type=\"hidden\" name=\"quiet\" value=\"1\">";
1213 print "<input type=\"hidden\" name=\"method\" value=\"add\">";
1214
1215 print "<select name=\"feed_url\">";
1216
1217 foreach ($feed_urls as $url => $name) {
1218 $url = htmlspecialchars($url);
1219 $name = htmlspecialchars($name);
1220
1221 print "<option value=\"$url\">$name</option>";
1222 }
1223
1224 print "<input type=\"submit\" value=\"".__("Subscribe to selected feed").
1225 "\">";
1226
1227 print "</form>";
1228 }
1229
1230 $tp_uri = get_self_url_prefix() . "/prefs.php";
1231 $tt_uri = get_self_url_prefix();
1232
1233 if ($rc <= 2){
1234 $result = db_query($this->link, "SELECT id FROM ttrss_feeds WHERE
1235 feed_url = '$feed_url' AND owner_uid = " . $_SESSION["uid"]);
1236
1237 $feed_id = db_fetch_result($result, 0, "id");
1238 } else {
1239 $feed_id = 0;
1240 }
1241 print "<p>";
1242
1243 if ($feed_id) {
1244 print "<form method=\"GET\" style='display: inline'
1245 action=\"$tp_uri\">
1246 <input type=\"hidden\" name=\"tab\" value=\"feedConfig\">
1247 <input type=\"hidden\" name=\"method\" value=\"editFeed\">
1248 <input type=\"hidden\" name=\"methodparam\" value=\"$feed_id\">
1249 <input type=\"submit\" value=\"".__("Edit subscription options")."\">
1250 </form>";
1251 }
1252
1253 print "<form style='display: inline' method=\"GET\" action=\"$tt_uri\">
1254 <input type=\"submit\" value=\"".__("Return to Tiny Tiny RSS")."\">
1255 </form></p>";
1256
1257 print "</body></html>";
1258 return;
1259 }
1260 }
1261
1262 function categorize() {
1263 $ids = split(",", db_escape_string($_REQUEST["ids"]));
1264
1265 $cat_id = db_escape_string($_REQUEST["cat_id"]);
1266
1267 if ($cat_id == 0) {
1268 $cat_id_qpart = 'NULL';
1269 } else {
1270 $cat_id_qpart = "'$cat_id'";
1271 }
1272
1273 db_query($this->link, "BEGIN");
1274
1275 foreach ($ids as $id) {
1276
1277 db_query($this->link, "UPDATE ttrss_feeds SET cat_id = $cat_id_qpart
1278 WHERE id = '$id'
1279 AND owner_uid = " . $_SESSION["uid"]);
1280
1281 }
1282
1283 db_query($this->link, "COMMIT");
1284 }
1285
1286 function editCats() {
1287
1288 $action = $_REQUEST["action"];
1289
1290 if ($action == "save") {
1291
1292 $cat_title = db_escape_string(trim($_REQUEST["value"]));
1293 $cat_id = db_escape_string($_REQUEST["cid"]);
1294
1295 db_query($this->link, "BEGIN");
1296
1297 $result = db_query($this->link, "SELECT title FROM ttrss_feed_categories
1298 WHERE id = '$cat_id' AND owner_uid = ".$_SESSION["uid"]);
1299
1300 if (db_num_rows($result) == 1) {
1301
1302 $old_title = db_fetch_result($result, 0, "title");
1303
1304 if ($cat_title != "") {
1305 $result = db_query($this->link, "UPDATE ttrss_feed_categories SET
1306 title = '$cat_title' WHERE id = '$cat_id' AND
1307 owner_uid = ".$_SESSION["uid"]);
1308
1309 print $cat_title;
1310 } else {
1311 print $old_title;
1312 }
1313 } else {
1314 print $_REQUEST["value"];
1315 }
1316
1317 db_query($this->link, "COMMIT");
1318
1319 return;
1320
1321 }
1322
1323 if ($action == "add") {
1324
1325 $feed_cat = db_escape_string(trim($_REQUEST["cat"]));
1326
1327 if (!add_feed_category($this->link, $feed_cat))
1328 print_warning(T_sprintf("Category <b>$%s</b> already exists in the database.", $feed_cat));
1329
1330 }
1331
1332 if ($action == "remove") {
1333
1334 $ids = split(",", db_escape_string($_REQUEST["ids"]));
1335
1336 foreach ($ids as $id) {
1337 remove_feed_category($this->link, $id, $_SESSION["uid"]);
1338 }
1339 }
1340
ddb575c7
AD
1341 print "<div dojoType=\"dijit.Toolbar\">";
1342
1343 print "<div dojoType=\"dijit.form.DropDownButton\">".
1344 "<span>" . __('Select')."</span>";
1345 print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
1346 print "<div onclick=\"selectTableRows('prefFeedCatList', 'all')\"
1347 dojoType=\"dijit.MenuItem\">".__('All')."</div>";
1348 print "<div onclick=\"selectTableRows('prefFeedCatList', 'none')\"
1349 dojoType=\"dijit.MenuItem\">".__('None')."</div>";
1350 print "</div></div>";
1351
1352 print "<div style='float : right'>";
1353
1354 print "<input dojoType=\"dijit.form.ValidationTextBox\" required=\"1\" name=\"newcat\">
afcfe6ca
AD
1355 <button dojoType=\"dijit.form.Button\" onclick=\"dijit.byId('feedCatEditDlg').addCategory()\">".
1356 __('Create category')."</button></div>";
1357
ddb575c7
AD
1358 print "</div>";
1359
7e454e81 1360 $result = db_query($this->link, "SELECT c.title, c.id,COUNT(f.id) AS count
a62812a6
AD
1361 FROM ttrss_feed_categories AS c LEFT JOIN ttrss_feeds AS f ON
1362 (f.cat_id = c.id)
1363 WHERE c.owner_uid = ".$_SESSION["uid"]."
1364 GROUP BY c.title, c.id ORDER BY title");
afcfe6ca
AD
1365
1366 if (db_num_rows($result) != 0) {
1367
1368 print "<div class=\"prefFeedCatHolder\">";
1369
1370 print "<table width=\"100%\" class=\"prefFeedCatList\"
1371 cellspacing=\"0\" id=\"prefFeedCatList\">";
1372
1373 $lnum = 0;
1374
1375 while ($line = db_fetch_assoc($result)) {
1376
1377 $class = ($lnum % 2) ? "even" : "odd";
1378
1379 $cat_id = $line["id"];
1380 $this_row_id = "id=\"FCATR-$cat_id\"";
1381
ddb575c7 1382 print "<tr class=\"placeholder\" $this_row_id>";
afcfe6ca
AD
1383
1384 $edit_title = htmlspecialchars($line["title"]);
1385
ddb575c7 1386 print "<td width='5%' align='center'><input id=\"FCATC-$cat_id\"
afcfe6ca
AD
1387 onclick='toggleSelectRow2(this);' dojoType=\"dijit.form.CheckBox\"
1388 type=\"checkbox\"></td>";
1389
1390 print "<td>";
1391
917c12ee
AD
1392 if ($line['count'] == 0) print '<em>';
1393
afcfe6ca
AD
1394 print "<span dojoType=\"dijit.InlineEditBox\"
1395 width=\"300px\" autoSave=\"false\"
1396 cat-id=\"$cat_id\">" . $edit_title .
1397 "<script type=\"dojo/method\" event=\"onChange\" args=\"item\">
1398 var elem = this;
1399 dojo.xhrPost({
1400 url: 'backend.php',
1401 content: {op: 'pref-feeds', method: 'editCats',
1402 action: 'save',
1403 value: this.value,
1404 cid: this.srcNodeRef.getAttribute('cat-id')},
1405 load: function(response) {
1406 elem.attr('value', response);
1407 updateFeedList();
1408 }
1409 });
1410 </script>
1411 </span>";
1412
917c12ee
AD
1413 if ($line['count'] == 0) print '</em>';
1414
1415 print "</td>";
1416
a62812a6
AD
1417 print "<td align='right' class='insensitive'>";
1418 echo T_sprintf("%d feeds", $line['count']);
afcfe6ca
AD
1419 print "</td></tr>";
1420
1421 ++$lnum;
1422 }
1423
1424 print "</table>";
1425 print "</div>";
1426
1427 } else {
1428 print "<p>".__('No feed categories defined.')."</p>";
1429 }
1430
1431 print "<div class='dlgButtons'>
1432 <div style='float : left'>
1433 <button dojoType=\"dijit.form.Button\" onclick=\"dijit.byId('feedCatEditDlg').removeSelected()\">".
1434 __('Remove selected categories')."</button>
1435 </div>";
1436
1437 print "<button dojoType=\"dijit.form.Button\" onclick=\"dijit.byId('feedCatEditDlg').hide()\">".
1438 __('Close this window')."</button></div>";
1439
1440 return;
1441
1442 }
1443
1444 function index() {
1445
1446 print "<div dojoType=\"dijit.layout.AccordionContainer\" region=\"center\">";
1447 print "<div id=\"pref-feeds-feeds\" dojoType=\"dijit.layout.AccordionPane\" title=\"".__('Feeds')."\">";
1448
1449 $result = db_query($this->link, "SELECT COUNT(id) AS num_errors
1450 FROM ttrss_feeds WHERE last_error != '' AND owner_uid = ".$_SESSION["uid"]);
1451
1452 $num_errors = db_fetch_result($result, 0, "num_errors");
1453
1454 if ($num_errors > 0) {
1455
1456 $error_button = "<button dojoType=\"dijit.form.Button\"
1457 onclick=\"showFeedsWithErrors()\" id=\"errorButton\">" .
1458 __("Feeds with errors") . "</button>";
1459 }
1460
1461 if (DB_TYPE == "pgsql") {
1462 $interval_qpart = "NOW() - INTERVAL '3 months'";
1463 } else {
1464 $interval_qpart = "DATE_SUB(NOW(), INTERVAL 3 MONTH)";
1465 }
1466
1467 $result = db_query($this->link, "SELECT COUNT(*) AS num_inactive FROM ttrss_feeds WHERE
1468 (SELECT MAX(updated) FROM ttrss_entries, ttrss_user_entries WHERE
1469 ttrss_entries.id = ref_id AND
1470 ttrss_user_entries.feed_id = ttrss_feeds.id) < $interval_qpart AND
1471 ttrss_feeds.owner_uid = ".$_SESSION["uid"]);
1472
1473 $num_inactive = db_fetch_result($result, 0, "num_inactive");
1474
1475 if ($num_inactive > 0) {
1476 $inactive_button = "<button dojoType=\"dijit.form.Button\"
1477 onclick=\"showInactiveFeeds()\">" .
1478 __("Inactive feeds") . "</button>";
1479 }
1480
1481 $feed_search = db_escape_string($_REQUEST["search"]);
1482
1483 if (array_key_exists("search", $_REQUEST)) {
1484 $_SESSION["prefs_feed_search"] = $feed_search;
1485 } else {
1486 $feed_search = $_SESSION["prefs_feed_search"];
1487 }
1488
1489 print '<div dojoType="dijit.layout.BorderContainer" gutters="false">';
1490
1491 print "<div region='top' dojoType=\"dijit.Toolbar\">"; #toolbar
1492
1493 print "<div style='float : right; padding-right : 4px;'>
1494 <input dojoType=\"dijit.form.TextBox\" id=\"feed_search\" size=\"20\" type=\"search\"
1495 value=\"$feed_search\">
1496 <button dojoType=\"dijit.form.Button\" onclick=\"updateFeedList()\">".
1497 __('Search')."</button>
1498 </div>";
1499
1500 print "<div dojoType=\"dijit.form.DropDownButton\">".
1501 "<span>" . __('Select')."</span>";
1502 print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
1503 print "<div onclick=\"dijit.byId('feedTree').model.setAllChecked(true)\"
1504 dojoType=\"dijit.MenuItem\">".__('All')."</div>";
1505 print "<div onclick=\"dijit.byId('feedTree').model.setAllChecked(false)\"
1506 dojoType=\"dijit.MenuItem\">".__('None')."</div>";
1507 print "</div></div>";
1508
1509 print "<div dojoType=\"dijit.form.DropDownButton\">".
1510 "<span>" . __('Feeds')."</span>";
1511 print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
1512 print "<div onclick=\"quickAddFeed()\"
1513 dojoType=\"dijit.MenuItem\">".__('Subscribe to feed')."</div>";
1514 print "<div onclick=\"editSelectedFeed()\"
1515 dojoType=\"dijit.MenuItem\">".__('Edit selected feeds')."</div>";
1516 print "<div onclick=\"resetFeedOrder()\"
1517 dojoType=\"dijit.MenuItem\">".__('Reset sort order')."</div>";
33f0fdd0
AD
1518 print "<div onclick=\"batchSubscribe()\"
1519 dojoType=\"dijit.MenuItem\">".__('Batch subscribe')."</div>";
afcfe6ca
AD
1520 print "</div></div>";
1521
1522 if (get_pref($this->link, 'ENABLE_FEED_CATS')) {
1523 print "<div dojoType=\"dijit.form.DropDownButton\">".
1524 "<span>" . __('Categories')."</span>";
1525 print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
1526 print "<div onclick=\"editFeedCats()\"
1527 dojoType=\"dijit.MenuItem\">".__('Edit categories')."</div>";
5b7bd238
AD
1528 print "<div onclick=\"toggleHiddenFeedCats()\"
1529 dojoType=\"dijit.MenuItem\">".__('(Un)hide empty categories')."</div>";
afcfe6ca
AD
1530 print "<div onclick=\"resetCatOrder()\"
1531 dojoType=\"dijit.MenuItem\">".__('Reset sort order')."</div>";
1532 print "</div></div>";
1533
1534 }
1535
1536 print $error_button;
1537 print $inactive_button;
1538
1539 print "<button dojoType=\"dijit.form.Button\" onclick=\"removeSelectedFeeds()\">"
1540 .__('Unsubscribe')."</button dojoType=\"dijit.form.Button\"> ";
1541
1542 if (defined('_ENABLE_FEED_DEBUGGING')) {
1543
1544 print "<select id=\"feedActionChooser\" onchange=\"feedActionChange()\">
1545 <option value=\"facDefault\" selected>".__('More actions...')."</option>";
1546
1547 if (FORCE_ARTICLE_PURGE == 0) {
1548 print
1549 "<option value=\"facPurge\">".__('Manual purge')."</option>";
1550 }
1551
1552 print "
1553 <option value=\"facClear\">".__('Clear feed data')."</option>
1554 <option value=\"facRescore\">".__('Rescore articles')."</option>";
1555
1556 print "</select>";
1557
1558 }
1559
1560 print "</div>"; # toolbar
1561
1562 //print '</div>';
1563 print '<div dojoType="dijit.layout.ContentPane" region="center">';
1564
1565 print "<div id=\"feedlistLoading\">
1566 <img src='images/indicator_tiny.gif'>".
1567 __("Loading, please wait...")."</div>";
1568
1569 print "<div dojoType=\"fox.PrefFeedStore\" jsId=\"feedStore\"
1570 url=\"backend.php?op=pref-feeds&method=getfeedtree\">
1571 </div>
1572 <div dojoType=\"lib.CheckBoxStoreModel\" jsId=\"feedModel\" store=\"feedStore\"
1573 query=\"{id:'root'}\" rootId=\"root\" rootLabel=\"Feeds\"
1574 childrenAttrs=\"items\" checkboxStrict=\"false\" checkboxAll=\"false\">
1575 </div>
1576 <div dojoType=\"fox.PrefFeedTree\" id=\"feedTree\"
1577 dndController=\"dijit.tree.dndSource\"
1578 betweenThreshold=\"5\"
1579 model=\"feedModel\" openOnClick=\"false\">
1580 <script type=\"dojo/method\" event=\"onClick\" args=\"item\">
1581 var id = String(item.id);
1582 var bare_id = id.substr(id.indexOf(':')+1);
1583
1584 if (id.match('FEED:')) {
1585 editFeed(bare_id);
1586 } else if (id.match('CAT:')) {
1587 editCat(bare_id, item);
1588 }
1589 </script>
1590 <script type=\"dojo/method\" event=\"onLoad\" args=\"item\">
1591 Element.hide(\"feedlistLoading\");
1592 </script>
1593 </div>";
1594
1595 print "<div dojoType=\"dijit.Tooltip\" connectId=\"feedTree\" position=\"below\">
1596 ".__('<b>Hint:</b> you can drag feeds and categories around.')."
1597 </div>";
1598
1599 print '</div>';
1600 print '</div>';
1601
1602 print "</div>"; # feeds pane
1603
566faa14 1604 print "<div dojoType=\"dijit.layout.AccordionPane\" title=\"".__('Import and export')."\">";
afcfe6ca 1605
a1159c01 1606 print "<h3>" . __("OPML") . "</h3>";
afcfe6ca 1607
566faa14 1608 print "<p>" . __("Using OPML you can export and import your feeds, filters, labels and Tiny Tiny RSS settings.") . " ";
afcfe6ca 1609
566faa14 1610 print __("Only main settings profile can be migrated using OPML.") . "</p>";
afcfe6ca 1611
55f34b81 1612 print "<iframe id=\"upload_iframe\"
afcfe6ca
AD
1613 name=\"upload_iframe\" onload=\"opmlImportComplete(this)\"
1614 style=\"width: 400px; height: 100px; display: none;\"></iframe>";
1615
1616 print "<form name=\"opml_form\" style='display : block' target=\"upload_iframe\"
1617 enctype=\"multipart/form-data\" method=\"POST\"
55f34b81 1618 action=\"backend.php\">
afcfe6ca
AD
1619 <input id=\"opml_file\" name=\"opml_file\" type=\"file\">&nbsp;
1620 <input type=\"hidden\" name=\"op\" value=\"dlg\">
c4c74732 1621 <input type=\"hidden\" name=\"method\" value=\"importOpml\">
afcfe6ca 1622 <button dojoType=\"dijit.form.Button\" onclick=\"return opmlImport();\" type=\"submit\">" .
a1159c01 1623 __('Import my OPML') . "</button>";
afcfe6ca 1624
a1159c01 1625 print "<hr>";
afcfe6ca
AD
1626
1627 print "<p>" . __('Filename:') .
1628 " <input type=\"text\" id=\"filename\" value=\"TinyTinyRSS.opml\" />&nbsp;" .
a1159c01 1629 __('Include settings') . "<input type=\"checkbox\" id=\"settings\" checked=\"1\"/>";
afcfe6ca 1630
a1159c01 1631 print "</p><button dojoType=\"dijit.form.Button\"
afcfe6ca 1632 onclick=\"gotoExportOpml(document.opml_form.filename.value, document.opml_form.settings.checked)\" >" .
a1159c01 1633 __('Export OPML') . "</button></p></form>";
afcfe6ca 1634
a1159c01 1635 print "<hr>";
afcfe6ca
AD
1636
1637 print "<p>".__('Your OPML can be published publicly and can be subscribed by anyone who knows the URL below.') . " ";
1638
566faa14 1639 print __("Published OPML does not include your Tiny Tiny RSS settings, feeds that require authentication or feeds hidden from Popular feeds.") . "</p>";
afcfe6ca
AD
1640
1641 print "<button dojoType=\"dijit.form.Button\" onclick=\"return displayDlg('pubOPMLUrl')\">".
a1159c01 1642 __('Display published OPML URL')."</button> ";
afcfe6ca 1643
55f34b81 1644
a1159c01 1645 print "<h3>" . __("Article archive") . "</h3>";
566faa14 1646
a1159c01 1647 print "<p>" . __("You can export and import your Starred and Archived articles for safekeeping or when migrating between tt-rss instances.") . "</p>";
566faa14
AD
1648
1649 print "<button dojoType=\"dijit.form.Button\" onclick=\"return exportData()\">".
1650 __('Export my data')."</button> ";
1651
a1159c01 1652 print "<hr>";
55f34b81
AD
1653
1654 print "<iframe id=\"data_upload_iframe\"
1655 name=\"data_upload_iframe\" onload=\"dataImportComplete(this)\"
1656 style=\"width: 400px; height: 100px; display: none;\"></iframe>";
1657
41f68571 1658 print "<form name=\"import_form\" style='display : block' target=\"data_upload_iframe\"
55f34b81
AD
1659 enctype=\"multipart/form-data\" method=\"POST\"
1660 action=\"backend.php\">
1661 <input id=\"export_file\" name=\"export_file\" type=\"file\">&nbsp;
1662 <input type=\"hidden\" name=\"op\" value=\"dlg\">
1663 <input type=\"hidden\" name=\"method\" value=\"dataimport\">
1664 <button dojoType=\"dijit.form.Button\" onclick=\"return importData();\" type=\"submit\">" .
1665 __('Import') . "</button>";
1666
1667
afcfe6ca
AD
1668 print "</div>"; # pane
1669
1670 if (strpos($_SERVER['HTTP_USER_AGENT'], "Firefox") !== false) {
1671
1672 print "<div dojoType=\"dijit.layout.AccordionPane\" title=\"".__('Firefox integration')."\">";
1673
1674 print "<p>" . __('This Tiny Tiny RSS site can be used as a Firefox Feed Reader by clicking the link below.') . "</p>";
1675
1676 print "<p>";
1677
1678 print "<button onclick='window.navigator.registerContentHandler(" .
1679 "\"application/vnd.mozilla.maybe.feed\", " .
1680 "\"" . add_feed_url() . "\", " . " \"Tiny Tiny RSS\")'>" .
1681 __('Click here to register this site as a feed reader.') .
1682 "</button>";
1683
1684 print "</p>";
1685
1686 print "</div>"; # pane
1687 }
1688
1689 print "<div dojoType=\"dijit.layout.AccordionPane\" title=\"".__('Subscribing using bookmarklet')."\">";
1690
1691 print "<p>" . __("Drag the link below to your browser toolbar, open the feed you're interested in in your browser and click on the link to subscribe to it.") . "</p>";
1692
1693 $bm_subscribe_url = str_replace('%s', '', add_feed_url());
1694
b1e592d3 1695 $confirm_str = str_replace("'", "\'", __('Subscribe to %s in Tiny Tiny RSS?'));
afcfe6ca
AD
1696
1697 $bm_url = htmlspecialchars("javascript:{if(confirm('$confirm_str'.replace('%s',window.location.href)))window.location.href='$bm_subscribe_url'+window.location.href}");
1698
1699 print "<a href=\"$bm_url\" class='bookmarklet'>" . __('Subscribe in Tiny Tiny RSS'). "</a>";
1700
1701 print "</div>"; #pane
1702
e95e7819 1703 print "<div dojoType=\"dijit.layout.AccordionPane\" title=\"".__('Published & shared articles / Generated feeds')."\">";
afcfe6ca
AD
1704
1705 print "<h3>" . __("Published articles and generated feeds") . "</h3>";
1706
1707 print "<p>".__('Published articles are exported as a public RSS feed and can be subscribed by anyone who knows the URL specified below.')."</p>";
1708
1709 $rss_url = '-2::' . htmlspecialchars(get_self_url_prefix() .
1710 "/public.php?op=rss&id=-2&view-mode=all_articles");;
1711
1712 print "<button dojoType=\"dijit.form.Button\" onclick=\"return displayDlg('generatedFeed', '$rss_url')\">".
1713 __('Display URL')."</button> ";
1714
1715 print "<button dojoType=\"dijit.form.Button\" onclick=\"return clearFeedAccessKeys()\">".
1716 __('Clear all generated URLs')."</button> ";
1717
1718 print "<h3>" . __("Articles shared by URL") . "</h3>";
1719
1720 print "<p>" . __("You can disable all articles shared by unique URLs here.") . "</p>";
1721
1722 print "<button dojoType=\"dijit.form.Button\" onclick=\"return clearArticleAccessKeys()\">".
1723 __('Unshare all articles')."</button> ";
1724
1725 print "</div>"; #pane
1726
1727 if (defined('CONSUMER_KEY') && CONSUMER_KEY != '') {
1728
1729 print "<div id=\"pref-feeds-twitter\" dojoType=\"dijit.layout.AccordionPane\" title=\"".__('Twitter')."\">";
1730
1731 $result = db_query($this->link, "SELECT COUNT(*) AS cid FROM ttrss_users
1732 WHERE twitter_oauth IS NOT NULL AND twitter_oauth != '' AND
1733 id = " . $_SESSION['uid']);
1734
1735 $is_registered = db_fetch_result($result, 0, "cid") != 0;
1736
1737 if (!$is_registered) {
1738 print_notice(__('Before you can update your Twitter feeds, you must register this instance of Tiny Tiny RSS with Twitter.com.'));
1739 } else {
1740 print_notice(__('You have been successfully registered with Twitter.com and should be able to access your Twitter feeds.'));
1741 }
1742
1743 print "<button dojoType=\"dijit.form.Button\" onclick=\"window.location.href = 'twitter.php?op=register'\">".
1744 __("Register with Twitter.com")."</button>";
1745
1746 print " ";
1747
1748 print "<button dojoType=\"dijit.form.Button\"
1749 onclick=\"return clearTwitterCredentials()\">".
1750 __("Clear stored credentials")."</button>";
1751
1752 print "</div>"; # pane
1753
1754 }
1755
1756 print "</div>"; #container
1757
1758 }
2ecd2df5
AD
1759
1760 private function feedlist_init_cat($cat_id, $hidden = false) {
1761 $obj = array();
1762 $cat_id = (int) $cat_id;
1763
1764 if ($cat_id > 0) {
1765 $cat_unread = ccache_find($this->link, $cat_id, $_SESSION["uid"], true);
1766 } else if ($cat_id == 0 || $cat_id == -2) {
1767 $cat_unread = getCategoryUnread($this->link, $cat_id);
1768 }
1769
1770 $obj['id'] = 'CAT:' . $cat_id;
1771 $obj['items'] = array();
1772 $obj['name'] = getCategoryTitle($this->link, $cat_id);
1773 $obj['type'] = 'category';
1774 $obj['unread'] = (int) $cat_unread;
1775 $obj['hidden'] = $hidden;
1776 $obj['bare_id'] = $cat_id;
1777
1778 return $obj;
1779 }
1780
1781 private function feedlist_init_feed($feed_id, $title = false, $unread = false, $error = '', $updated = '') {
1782 $obj = array();
1783 $feed_id = (int) $feed_id;
1784
1785 if (!$title)
1786 $title = getFeedTitle($this->link, $feed_id, false);
1787
1788 if ($unread === false)
1789 $unread = getFeedUnread($this->link, $feed_id, false);
1790
1791 $obj['id'] = 'FEED:' . $feed_id;
1792 $obj['name'] = $title;
1793 $obj['unread'] = (int) $unread;
1794 $obj['type'] = 'feed';
1795 $obj['error'] = $error;
1796 $obj['updated'] = $updated;
1797 $obj['icon'] = getFeedIcon($feed_id);
1798 $obj['bare_id'] = $feed_id;
1799
1800 return $obj;
1801 }
1802
afcfe6ca
AD
1803}
1804?>