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