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