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