]> git.wh0rd.org - tt-rss.git/blame - classes/pref_feeds.php
disable csrf logging
[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
451 if (SIMPLEPIE_CACHE_IMAGES) {
452 print "<hr/><input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" id=\"cache_images\"
453 name=\"cache_images\"
454 $checked>&nbsp;<label for=\"cache_images\">".
455 __('Cache images locally (SimplePie only)')."</label>";
456 }
457
458 $mark_unread_on_update = sql_bool_to_bool(db_fetch_result($result, 0, "mark_unread_on_update"));
459
460 if ($mark_unread_on_update) {
461 $checked = "checked";
462 } else {
463 $checked = "";
464 }
465
466 print "<hr/><input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" id=\"mark_unread_on_update\"
467 name=\"mark_unread_on_update\"
468 $checked>&nbsp;<label for=\"mark_unread_on_update\">".__('Mark updated articles as unread')."</label>";
469
470 $update_on_checksum_change = sql_bool_to_bool(db_fetch_result($result, 0, "update_on_checksum_change"));
471
472 if ($update_on_checksum_change) {
473 $checked = "checked";
474 } else {
475 $checked = "";
476 }
477
478 print "<hr/><input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" id=\"update_on_checksum_change\"
479 name=\"update_on_checksum_change\"
480 $checked>&nbsp;<label for=\"update_on_checksum_change\">".__('Mark posts as updated on content change')."</label>";
481
482 print "</div>";
483
484 /* Icon */
485
486 print "<div class=\"dlgSec\">".__("Icon")."</div>";
487 print "<div class=\"dlgSecCont\">";
488
489 print "<iframe name=\"icon_upload_iframe\"
490 style=\"width: 400px; height: 100px; display: none;\"></iframe>";
491
492 print "<form style='display : block' target=\"icon_upload_iframe\"
493 enctype=\"multipart/form-data\" method=\"POST\"
494 action=\"backend.php\">
495 <input id=\"icon_file\" size=\"10\" name=\"icon_file\" type=\"file\">
496 <input type=\"hidden\" name=\"op\" value=\"pref-feeds\">
497 <input type=\"hidden\" name=\"feed_id\" value=\"$feed_id\">
498 <input type=\"hidden\" name=\"method\" value=\"uploadicon\">
499 <button dojoType=\"dijit.form.Button\" onclick=\"return uploadFeedIcon();\"
500 type=\"submit\">".__('Replace')."</button>
501 <button dojoType=\"dijit.form.Button\" onclick=\"return removeFeedIcon($feed_id);\"
502 type=\"submit\">".__('Remove')."</button>
503 </form>";
504
505 print "</div>";
506
507 $title = htmlspecialchars($title, ENT_QUOTES);
508
509 print "<div class='dlgButtons'>
510 <div style=\"float : left\">
511 <button dojoType=\"dijit.form.Button\" onclick='return unsubscribeFeed($feed_id, \"$title\")'>".
512 __('Unsubscribe')."</button>";
513
514 if (PUBSUBHUBBUB_ENABLED) {
515 $pubsub_state = db_fetch_result($result, 0, "pubsub_state");
516 $pubsub_btn_disabled = ($pubsub_state == 2) ? "" : "disabled=\"1\"";
517
518 print "<button dojoType=\"dijit.form.Button\" id=\"pubsubReset_Btn\" $pubsub_btn_disabled
519 onclick='return resetPubSub($feed_id, \"$title\")'>".__('Resubscribe to push updates').
520 "</button>";
521 }
522
523 print "</div>";
524
525 print "<div dojoType=\"dijit.Tooltip\" connectId=\"pubsubReset_Btn\" position=\"below\">".
526 __('Resets PubSubHubbub subscription status for push-enabled feeds.')."</div>";
527
528 print "<button dojoType=\"dijit.form.Button\" onclick=\"return dijit.byId('feedEditDlg').execute()\">".__('Save')."</button>
529 <button dojoType=\"dijit.form.Button\" onclick=\"return dijit.byId('feedEditDlg').hide()\">".__('Cancel')."</button>
530 </div>";
531
532 return;
533 }
534
535 function editfeeds() {
536 global $purge_intervals;
537 global $update_intervals;
538 global $update_methods;
46da73c2 539
afcfe6ca
AD
540 $feed_ids = db_escape_string($_REQUEST["ids"]);
541
542 print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"ids\" value=\"$feed_ids\">";
543 print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"op\" value=\"pref-feeds\">";
544 print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"method\" value=\"batchEditSave\">";
545
546 print "<div class=\"dlgSec\">".__("Feed")."</div>";
547 print "<div class=\"dlgSecCont\">";
548
549 /* Title */
550
551 print "<input dojoType=\"dijit.form.ValidationTextBox\"
552 disabled=\"1\" style=\"font-size : 16px; width : 20em;\" required=\"1\"
553 name=\"title\" value=\"$title\">";
554
555 $this->batch_edit_cbox("title");
556
557 /* Feed URL */
558
559 print "<br/>";
560
561 print __('URL:') . " ";
562 print "<input dojoType=\"dijit.form.ValidationTextBox\" disabled=\"1\"
563 required=\"1\" regExp='^(http|https)://.*' style=\"width : 20em\"
564 name=\"feed_url\" value=\"$feed_url\">";
565
566 $this->batch_edit_cbox("feed_url");
567
568 /* Category */
569
570 if (get_pref($this->link, 'ENABLE_FEED_CATS')) {
571
572 print "<br/>";
573
574 print __('Place in category:') . " ";
575
576 print_feed_cat_select($this->link, "cat_id", $cat_id,
577 'disabled="1" dojoType="dijit.form.Select"');
578
579 $this->batch_edit_cbox("cat_id");
580
581 }
582
583 print "</div>";
584
585 print "<div class=\"dlgSec\">".__("Update")."</div>";
586 print "<div class=\"dlgSecCont\">";
587
588 /* Update Interval */
589
590 print_select_hash("update_interval", $update_interval, $update_intervals,
591 'disabled="1" dojoType="dijit.form.Select"');
592
593 $this->batch_edit_cbox("update_interval");
594
595 /* Update method */
596
597 print " " . __('using') . " ";
598 print_select_hash("update_method", $update_method, $update_methods,
599 'disabled="1" dojoType="dijit.form.Select"');
600 $this->batch_edit_cbox("update_method");
601
602 /* Purge intl */
603
604 if (FORCE_ARTICLE_PURGE == 0) {
605
606 print "<br/>";
607
608 print __('Article purging:') . " ";
609
610 print_select_hash("purge_interval", $purge_interval, $purge_intervals,
611 'disabled="1" dojoType="dijit.form.Select"');
612
613 $this->batch_edit_cbox("purge_interval");
614 }
615
616 print "</div>";
617 print "<div class=\"dlgSec\">".__("Authentication")."</div>";
618 print "<div class=\"dlgSecCont\">";
619
620 print "<input dojoType=\"dijit.form.TextBox\"
621 placeHolder=\"".__("Login")."\" disabled=\"1\"
622 name=\"auth_login\" value=\"$auth_login\">";
623
624 $this->batch_edit_cbox("auth_login");
625
626 print "<br/><input dojoType=\"dijit.form.TextBox\" type=\"password\" name=\"auth_pass\"
627 placeHolder=\"".__("Password")."\" disabled=\"1\"
628 value=\"$auth_pass\">";
629
630 $this->batch_edit_cbox("auth_pass");
631
632 print "</div>";
633 print "<div class=\"dlgSec\">".__("Options")."</div>";
634 print "<div class=\"dlgSecCont\">";
635
636 print "<input disabled=\"1\" type=\"checkbox\" name=\"private\" id=\"private\"
637 dojoType=\"dijit.form.CheckBox\">&nbsp;<label id=\"private_l\" class='insensitive' for=\"private\">".__('Hide from Popular feeds')."</label>";
638
639 print "&nbsp;"; $this->batch_edit_cbox("private", "private_l");
640
641 print "<br/><input disabled=\"1\" type=\"checkbox\" id=\"rtl_content\" name=\"rtl_content\"
642 dojoType=\"dijit.form.CheckBox\">&nbsp;<label class='insensitive' id=\"rtl_content_l\" for=\"rtl_content\">".__('Right-to-left content')."</label>";
643
644 print "&nbsp;"; $this->batch_edit_cbox("rtl_content", "rtl_content_l");
645
646 print "<br/><input disabled=\"1\" type=\"checkbox\" id=\"include_in_digest\"
647 name=\"include_in_digest\"
648 dojoType=\"dijit.form.CheckBox\">&nbsp;<label id=\"include_in_digest_l\" class='insensitive' for=\"include_in_digest\">".__('Include in e-mail digest')."</label>";
649
650 print "&nbsp;"; $this->batch_edit_cbox("include_in_digest", "include_in_digest_l");
651
652 print "<br/><input disabled=\"1\" type=\"checkbox\" id=\"always_display_enclosures\"
653 name=\"always_display_enclosures\"
654 dojoType=\"dijit.form.CheckBox\">&nbsp;<label id=\"always_display_enclosures_l\" class='insensitive' for=\"always_display_enclosures\">".__('Always display image attachments')."</label>";
655
656 print "&nbsp;"; $this->batch_edit_cbox("always_display_enclosures", "always_display_enclosures_l");
657
658 if (SIMPLEPIE_CACHE_IMAGES) {
659 print "<br/><input disabled=\"1\" type=\"checkbox\" id=\"cache_images\"
660 name=\"cache_images\"
661 dojoType=\"dijit.form.CheckBox\">&nbsp;<label class='insensitive' id=\"cache_images_l\"
662 for=\"cache_images\">".
663 __('Cache images locally')."</label>";
664
665
666 print "&nbsp;"; $this->batch_edit_cbox("cache_images", "cache_images_l");
667 }
668
669 print "<br/><input disabled=\"1\" type=\"checkbox\" id=\"mark_unread_on_update\"
670 name=\"mark_unread_on_update\"
671 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>";
672
673 print "&nbsp;"; $this->batch_edit_cbox("mark_unread_on_update", "mark_unread_on_update_l");
674
675 print "<br/><input disabled=\"1\" type=\"checkbox\" id=\"update_on_checksum_change\"
676 name=\"update_on_checksum_change\"
677 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>";
678
679 print "&nbsp;"; $this->batch_edit_cbox("update_on_checksum_change", "update_on_checksum_change_l");
680
681 print "</div>";
682
683 print "<div class='dlgButtons'>
684 <button dojoType=\"dijit.form.Button\"
685 onclick=\"return dijit.byId('feedEditDlg').execute()\">".
686 __('Save')."</button>
687 <button dojoType=\"dijit.form.Button\"
688 onclick=\"return dijit.byId('feedEditDlg').hide()\">".
689 __('Cancel')."</button>
690 </div>";
691
692 return;
693 }
694
695 function batchEditSave() {
3a76e2a2 696 return $this->editsaveops(true);
afcfe6ca 697 }
46da73c2 698
afcfe6ca 699 function editSave() {
3a76e2a2 700 return $this->editsaveops(false);
afcfe6ca 701 }
46da73c2
AD
702
703 function editsaveops($batch) {
704
afcfe6ca
AD
705 $feed_title = db_escape_string(trim($_POST["title"]));
706 $feed_link = db_escape_string(trim($_POST["feed_url"]));
707 $upd_intl = (int) db_escape_string($_POST["update_interval"]);
708 $purge_intl = (int) db_escape_string($_POST["purge_interval"]);
709 $feed_id = (int) db_escape_string($_POST["id"]); /* editSave */
710 $feed_ids = db_escape_string($_POST["ids"]); /* batchEditSave */
711 $cat_id = (int) db_escape_string($_POST["cat_id"]);
712 $auth_login = db_escape_string(trim($_POST["auth_login"]));
713 $auth_pass = db_escape_string(trim($_POST["auth_pass"]));
714 $private = checkbox_to_sql_bool(db_escape_string($_POST["private"]));
715 $rtl_content = checkbox_to_sql_bool(db_escape_string($_POST["rtl_content"]));
716 $include_in_digest = checkbox_to_sql_bool(
717 db_escape_string($_POST["include_in_digest"]));
718 $cache_images = checkbox_to_sql_bool(
719 db_escape_string($_POST["cache_images"]));
720 $update_method = (int) db_escape_string($_POST["update_method"]);
721
722 $always_display_enclosures = checkbox_to_sql_bool(
723 db_escape_string($_POST["always_display_enclosures"]));
724
725 $mark_unread_on_update = checkbox_to_sql_bool(
726 db_escape_string($_POST["mark_unread_on_update"]));
727
728 $update_on_checksum_change = checkbox_to_sql_bool(
729 db_escape_string($_POST["update_on_checksum_change"]));
730
731 if (get_pref($this->link, 'ENABLE_FEED_CATS')) {
732 if ($cat_id && $cat_id != 0) {
733 $category_qpart = "cat_id = '$cat_id',";
734 $category_qpart_nocomma = "cat_id = '$cat_id'";
735 } else {
736 $category_qpart = 'cat_id = NULL,';
737 $category_qpart_nocomma = 'cat_id = NULL';
738 }
739 } else {
740 $category_qpart = "";
741 $category_qpart_nocomma = "";
742 }
743
744 if (SIMPLEPIE_CACHE_IMAGES) {
745 $cache_images_qpart = "cache_images = $cache_images,";
746 } else {
747 $cache_images_qpart = "";
748 }
749
3a76e2a2 750 if (!$batch) {
afcfe6ca
AD
751
752 $result = db_query($this->link, "UPDATE ttrss_feeds SET
753 $category_qpart
754 title = '$feed_title', feed_url = '$feed_link',
755 update_interval = '$upd_intl',
756 purge_interval = '$purge_intl',
757 auth_login = '$auth_login',
758 auth_pass = '$auth_pass',
759 private = $private,
760 rtl_content = $rtl_content,
761 $cache_images_qpart
762 include_in_digest = $include_in_digest,
763 always_display_enclosures = $always_display_enclosures,
764 mark_unread_on_update = $mark_unread_on_update,
765 update_on_checksum_change = $update_on_checksum_change,
766 update_method = '$update_method'
767 WHERE id = '$feed_id' AND owner_uid = " . $_SESSION["uid"]);
768
3a76e2a2 769 } else {
afcfe6ca
AD
770 $feed_data = array();
771
772 foreach (array_keys($_POST) as $k) {
773 if ($k != "op" && $k != "method" && $k != "ids") {
774 $feed_data[$k] = $_POST[$k];
775 }
776 }
777
778 db_query($this->link, "BEGIN");
779
780 foreach (array_keys($feed_data) as $k) {
781
782 $qpart = "";
783
784 switch ($k) {
785 case "title":
786 $qpart = "title = '$feed_title'";
787 break;
788
789 case "feed_url":
790 $qpart = "feed_url = '$feed_link'";
791 break;
792
793 case "update_interval":
794 $qpart = "update_interval = '$upd_intl'";
795 break;
796
797 case "purge_interval":
798 $qpart = "purge_interval = '$purge_intl'";
799 break;
800
801 case "auth_login":
802 $qpart = "auth_login = '$auth_login'";
803 break;
804
805 case "auth_pass":
806 $qpart = "auth_pass = '$auth_pass'";
807 break;
808
809 case "private":
810 $qpart = "private = '$private'";
811 break;
812
813 case "include_in_digest":
814 $qpart = "include_in_digest = '$include_in_digest'";
815 break;
816
817 case "always_display_enclosures":
818 $qpart = "always_display_enclosures = '$always_display_enclosures'";
819 break;
820
821 case "mark_unread_on_update":
822 $qpart = "mark_unread_on_update = '$mark_unread_on_update'";
823 break;
824
825 case "update_on_checksum_change":
826 $qpart = "update_on_checksum_change = '$update_on_checksum_change'";
827 break;
828
829 case "cache_images":
830 $qpart = "cache_images = '$cache_images'";
831 break;
832
833 case "rtl_content":
834 $qpart = "rtl_content = '$rtl_content'";
835 break;
836
837 case "update_method":
838 $qpart = "update_method = '$update_method'";
839 break;
840
841 case "cat_id":
842 $qpart = $category_qpart_nocomma;
843 break;
844
845 }
846
847 if ($qpart) {
848 db_query($this->link,
849 "UPDATE ttrss_feeds SET $qpart WHERE id IN ($feed_ids)
850 AND owner_uid = " . $_SESSION["uid"]);
851 print "<br/>";
852 }
853 }
854
855 db_query($this->link, "COMMIT");
856 }
857 return;
858 }
859
860 function resetPubSub() {
861
862 $ids = db_escape_string($_REQUEST["ids"]);
863
864 db_query($this->link, "UPDATE ttrss_feeds SET pubsub_state = 0 WHERE id IN ($ids)
865 AND owner_uid = " . $_SESSION["uid"]);
866
867 return;
868 }
869
870 function remove() {
871
872 $ids = split(",", db_escape_string($_REQUEST["ids"]));
873
874 foreach ($ids as $id) {
875 remove_feed($this->link, $id, $_SESSION["uid"]);
876 }
877
878 return;
879 }
880
881 function clear() {
882 $id = db_escape_string($_REQUEST["id"]);
883 clear_feed_articles($this->link, $id);
884 }
885
886 function rescore() {
887 $ids = split(",", db_escape_string($_REQUEST["ids"]));
888
889 foreach ($ids as $id) {
890
891 $filters = load_filters($this->link, $id, $_SESSION["uid"], 6);
892
893 $result = db_query($this->link, "SELECT
894 title, content, link, ref_id, author,".
895 SUBSTRING_FOR_DATE."(updated, 1, 19) AS updated
896 FROM
897 ttrss_user_entries, ttrss_entries
898 WHERE ref_id = id AND feed_id = '$id' AND
899 owner_uid = " .$_SESSION['uid']."
900 ");
901
902 $scores = array();
903
904 while ($line = db_fetch_assoc($result)) {
905
906 $tags = get_article_tags($this->link, $line["ref_id"]);
907
908 $article_filters = get_article_filters($filters, $line['title'],
909 $line['content'], $line['link'], strtotime($line['updated']),
910 $line['author'], $tags);
911
912 $new_score = calculate_article_score($article_filters);
913
914 if (!$scores[$new_score]) $scores[$new_score] = array();
915
916 array_push($scores[$new_score], $line['ref_id']);
917 }
918
919 foreach (array_keys($scores) as $s) {
920 if ($s > 1000) {
921 db_query($this->link, "UPDATE ttrss_user_entries SET score = '$s',
922 marked = true WHERE
923 ref_id IN (" . join(',', $scores[$s]) . ")");
924 } else if ($s < -500) {
925 db_query($this->link, "UPDATE ttrss_user_entries SET score = '$s',
926 unread = false WHERE
927 ref_id IN (" . join(',', $scores[$s]) . ")");
928 } else {
929 db_query($this->link, "UPDATE ttrss_user_entries SET score = '$s' WHERE
930 ref_id IN (" . join(',', $scores[$s]) . ")");
931 }
932 }
933 }
934
935 print __("All done.");
936
937 }
938
939 function rescoreAll() {
940
941 $result = db_query($this->link,
942 "SELECT id FROM ttrss_feeds WHERE owner_uid = " . $_SESSION['uid']);
943
944 while ($feed_line = db_fetch_assoc($result)) {
945
946 $id = $feed_line["id"];
947
948 $filters = load_filters($this->link, $id, $_SESSION["uid"], 6);
949
950 $tmp_result = db_query($this->link, "SELECT
951 title, content, link, ref_id, author,".
952 SUBSTRING_FOR_DATE."(updated, 1, 19) AS updated
953 FROM
954 ttrss_user_entries, ttrss_entries
955 WHERE ref_id = id AND feed_id = '$id' AND
956 owner_uid = " .$_SESSION['uid']."
957 ");
958
959 $scores = array();
960
961 while ($line = db_fetch_assoc($tmp_result)) {
962
963 $tags = get_article_tags($this->link, $line["ref_id"]);
964
965 $article_filters = get_article_filters($filters, $line['title'],
966 $line['content'], $line['link'], strtotime($line['updated']),
967 $line['author'], $tags);
968
969 $new_score = calculate_article_score($article_filters);
970
971 if (!$scores[$new_score]) $scores[$new_score] = array();
972
973 array_push($scores[$new_score], $line['ref_id']);
974 }
975
976 foreach (array_keys($scores) as $s) {
977 if ($s > 1000) {
978 db_query($this->link, "UPDATE ttrss_user_entries SET score = '$s',
979 marked = true WHERE
980 ref_id IN (" . join(',', $scores[$s]) . ")");
981 } else {
982 db_query($this->link, "UPDATE ttrss_user_entries SET score = '$s' WHERE
983 ref_id IN (" . join(',', $scores[$s]) . ")");
984 }
985 }
986 }
987
988 print __("All done.");
989
990 }
991
992 function add() {
993 $feed_url = db_escape_string(trim($_REQUEST["feed_url"]));
994 $cat_id = db_escape_string($_REQUEST["cat_id"]);
995 $p_from = db_escape_string($_REQUEST["from"]);
996
997 /* only read authentication information from POST */
998
999 $auth_login = db_escape_string(trim($_POST["auth_login"]));
1000 $auth_pass = db_escape_string(trim($_POST["auth_pass"]));
1001
1002 if ($p_from != 'tt-rss') {
1003 header("Content-Type: text/html");
1004 print "<html>
1005 <head>
1006 <title>Tiny Tiny RSS</title>
1007 <link rel=\"stylesheet\" type=\"text/css\" href=\"utility.css\">
1008 </head>
1009 <body>
1010 <img class=\"floatingLogo\" src=\"images/ttrss_logo.png\"
1011 alt=\"Tiny Tiny RSS\"/>
1012 <h1>Subscribe to feed...</h1>";
1013 }
1014
1015 $rc = subscribe_to_feed($this->link, $feed_url, $cat_id, $auth_login, $auth_pass);
1016
1017 switch ($rc) {
1018 case 1:
1019 print_notice(T_sprintf("Subscribed to <b>%s</b>.", $feed_url));
1020 break;
1021 case 2:
1022 print_error(T_sprintf("Could not subscribe to <b>%s</b>.", $feed_url));
1023 break;
1024 case 3:
1025 print_error(T_sprintf("No feeds found in <b>%s</b>.", $feed_url));
1026 break;
1027 case 0:
1028 print_warning(T_sprintf("Already subscribed to <b>%s</b>.", $feed_url));
1029 break;
1030 case 4:
1031 print_notice("Multiple feed URLs found.");
1032
1033 $feed_urls = get_feeds_from_html($feed_url);
1034 break;
1035 case 5:
1036 print_error(T_sprintf("Could not subscribe to <b>%s</b>.<br>Can't download the Feed URL.", $feed_url));
1037 break;
1038 }
1039
1040 if ($p_from != 'tt-rss') {
1041
1042 if ($feed_urls) {
1043
1044 print "<form action=\"backend.php\">";
1045 print "<input type=\"hidden\" name=\"op\" value=\"pref-feeds\">";
1046 print "<input type=\"hidden\" name=\"quiet\" value=\"1\">";
1047 print "<input type=\"hidden\" name=\"method\" value=\"add\">";
1048
1049 print "<select name=\"feed_url\">";
1050
1051 foreach ($feed_urls as $url => $name) {
1052 $url = htmlspecialchars($url);
1053 $name = htmlspecialchars($name);
1054
1055 print "<option value=\"$url\">$name</option>";
1056 }
1057
1058 print "<input type=\"submit\" value=\"".__("Subscribe to selected feed").
1059 "\">";
1060
1061 print "</form>";
1062 }
1063
1064 $tp_uri = get_self_url_prefix() . "/prefs.php";
1065 $tt_uri = get_self_url_prefix();
1066
1067 if ($rc <= 2){
1068 $result = db_query($this->link, "SELECT id FROM ttrss_feeds WHERE
1069 feed_url = '$feed_url' AND owner_uid = " . $_SESSION["uid"]);
1070
1071 $feed_id = db_fetch_result($result, 0, "id");
1072 } else {
1073 $feed_id = 0;
1074 }
1075 print "<p>";
1076
1077 if ($feed_id) {
1078 print "<form method=\"GET\" style='display: inline'
1079 action=\"$tp_uri\">
1080 <input type=\"hidden\" name=\"tab\" value=\"feedConfig\">
1081 <input type=\"hidden\" name=\"method\" value=\"editFeed\">
1082 <input type=\"hidden\" name=\"methodparam\" value=\"$feed_id\">
1083 <input type=\"submit\" value=\"".__("Edit subscription options")."\">
1084 </form>";
1085 }
1086
1087 print "<form style='display: inline' method=\"GET\" action=\"$tt_uri\">
1088 <input type=\"submit\" value=\"".__("Return to Tiny Tiny RSS")."\">
1089 </form></p>";
1090
1091 print "</body></html>";
1092 return;
1093 }
1094 }
1095
1096 function categorize() {
1097 $ids = split(",", db_escape_string($_REQUEST["ids"]));
1098
1099 $cat_id = db_escape_string($_REQUEST["cat_id"]);
1100
1101 if ($cat_id == 0) {
1102 $cat_id_qpart = 'NULL';
1103 } else {
1104 $cat_id_qpart = "'$cat_id'";
1105 }
1106
1107 db_query($this->link, "BEGIN");
1108
1109 foreach ($ids as $id) {
1110
1111 db_query($this->link, "UPDATE ttrss_feeds SET cat_id = $cat_id_qpart
1112 WHERE id = '$id'
1113 AND owner_uid = " . $_SESSION["uid"]);
1114
1115 }
1116
1117 db_query($this->link, "COMMIT");
1118 }
1119
1120 function editCats() {
1121
1122 $action = $_REQUEST["action"];
1123
1124 if ($action == "save") {
1125
1126 $cat_title = db_escape_string(trim($_REQUEST["value"]));
1127 $cat_id = db_escape_string($_REQUEST["cid"]);
1128
1129 db_query($this->link, "BEGIN");
1130
1131 $result = db_query($this->link, "SELECT title FROM ttrss_feed_categories
1132 WHERE id = '$cat_id' AND owner_uid = ".$_SESSION["uid"]);
1133
1134 if (db_num_rows($result) == 1) {
1135
1136 $old_title = db_fetch_result($result, 0, "title");
1137
1138 if ($cat_title != "") {
1139 $result = db_query($this->link, "UPDATE ttrss_feed_categories SET
1140 title = '$cat_title' WHERE id = '$cat_id' AND
1141 owner_uid = ".$_SESSION["uid"]);
1142
1143 print $cat_title;
1144 } else {
1145 print $old_title;
1146 }
1147 } else {
1148 print $_REQUEST["value"];
1149 }
1150
1151 db_query($this->link, "COMMIT");
1152
1153 return;
1154
1155 }
1156
1157 if ($action == "add") {
1158
1159 $feed_cat = db_escape_string(trim($_REQUEST["cat"]));
1160
1161 if (!add_feed_category($this->link, $feed_cat))
1162 print_warning(T_sprintf("Category <b>$%s</b> already exists in the database.", $feed_cat));
1163
1164 }
1165
1166 if ($action == "remove") {
1167
1168 $ids = split(",", db_escape_string($_REQUEST["ids"]));
1169
1170 foreach ($ids as $id) {
1171 remove_feed_category($this->link, $id, $_SESSION["uid"]);
1172 }
1173 }
1174
1175 print "<div dojoType=\"dijit.Toolbar\">
1176 <input dojoType=\"dijit.form.ValidationTextBox\" required=\"1\" name=\"newcat\">
1177 <button dojoType=\"dijit.form.Button\" onclick=\"dijit.byId('feedCatEditDlg').addCategory()\">".
1178 __('Create category')."</button></div>";
1179
1180 $result = db_query($this->link, "SELECT title,id FROM ttrss_feed_categories
1181 WHERE owner_uid = ".$_SESSION["uid"]."
1182 ORDER BY title");
1183
1184 if (db_num_rows($result) != 0) {
1185
1186 print "<div class=\"prefFeedCatHolder\">";
1187
1188 print "<table width=\"100%\" class=\"prefFeedCatList\"
1189 cellspacing=\"0\" id=\"prefFeedCatList\">";
1190
1191 $lnum = 0;
1192
1193 while ($line = db_fetch_assoc($result)) {
1194
1195 $class = ($lnum % 2) ? "even" : "odd";
1196
1197 $cat_id = $line["id"];
1198 $this_row_id = "id=\"FCATR-$cat_id\"";
1199
1200 print "<tr class=\"\" $this_row_id>";
1201
1202 $edit_title = htmlspecialchars($line["title"]);
1203
1204 print "<td width='5%' align='center'><input
1205 onclick='toggleSelectRow2(this);' dojoType=\"dijit.form.CheckBox\"
1206 type=\"checkbox\"></td>";
1207
1208 print "<td>";
1209
1210 print "<span dojoType=\"dijit.InlineEditBox\"
1211 width=\"300px\" autoSave=\"false\"
1212 cat-id=\"$cat_id\">" . $edit_title .
1213 "<script type=\"dojo/method\" event=\"onChange\" args=\"item\">
1214 var elem = this;
1215 dojo.xhrPost({
1216 url: 'backend.php',
1217 content: {op: 'pref-feeds', method: 'editCats',
1218 action: 'save',
1219 value: this.value,
1220 cid: this.srcNodeRef.getAttribute('cat-id')},
1221 load: function(response) {
1222 elem.attr('value', response);
1223 updateFeedList();
1224 }
1225 });
1226 </script>
1227 </span>";
1228
1229 print "</td></tr>";
1230
1231 ++$lnum;
1232 }
1233
1234 print "</table>";
1235 print "</div>";
1236
1237 } else {
1238 print "<p>".__('No feed categories defined.')."</p>";
1239 }
1240
1241 print "<div class='dlgButtons'>
1242 <div style='float : left'>
1243 <button dojoType=\"dijit.form.Button\" onclick=\"dijit.byId('feedCatEditDlg').removeSelected()\">".
1244 __('Remove selected categories')."</button>
1245 </div>";
1246
1247 print "<button dojoType=\"dijit.form.Button\" onclick=\"dijit.byId('feedCatEditDlg').hide()\">".
1248 __('Close this window')."</button></div>";
1249
1250 return;
1251
1252 }
1253
1254 function index() {
1255
1256 print "<div dojoType=\"dijit.layout.AccordionContainer\" region=\"center\">";
1257 print "<div id=\"pref-feeds-feeds\" dojoType=\"dijit.layout.AccordionPane\" title=\"".__('Feeds')."\">";
1258
1259 $result = db_query($this->link, "SELECT COUNT(id) AS num_errors
1260 FROM ttrss_feeds WHERE last_error != '' AND owner_uid = ".$_SESSION["uid"]);
1261
1262 $num_errors = db_fetch_result($result, 0, "num_errors");
1263
1264 if ($num_errors > 0) {
1265
1266 $error_button = "<button dojoType=\"dijit.form.Button\"
1267 onclick=\"showFeedsWithErrors()\" id=\"errorButton\">" .
1268 __("Feeds with errors") . "</button>";
1269 }
1270
1271 if (DB_TYPE == "pgsql") {
1272 $interval_qpart = "NOW() - INTERVAL '3 months'";
1273 } else {
1274 $interval_qpart = "DATE_SUB(NOW(), INTERVAL 3 MONTH)";
1275 }
1276
1277 $result = db_query($this->link, "SELECT COUNT(*) AS num_inactive FROM ttrss_feeds WHERE
1278 (SELECT MAX(updated) FROM ttrss_entries, ttrss_user_entries WHERE
1279 ttrss_entries.id = ref_id AND
1280 ttrss_user_entries.feed_id = ttrss_feeds.id) < $interval_qpart AND
1281 ttrss_feeds.owner_uid = ".$_SESSION["uid"]);
1282
1283 $num_inactive = db_fetch_result($result, 0, "num_inactive");
1284
1285 if ($num_inactive > 0) {
1286 $inactive_button = "<button dojoType=\"dijit.form.Button\"
1287 onclick=\"showInactiveFeeds()\">" .
1288 __("Inactive feeds") . "</button>";
1289 }
1290
1291 $feed_search = db_escape_string($_REQUEST["search"]);
1292
1293 if (array_key_exists("search", $_REQUEST)) {
1294 $_SESSION["prefs_feed_search"] = $feed_search;
1295 } else {
1296 $feed_search = $_SESSION["prefs_feed_search"];
1297 }
1298
1299 print '<div dojoType="dijit.layout.BorderContainer" gutters="false">';
1300
1301 print "<div region='top' dojoType=\"dijit.Toolbar\">"; #toolbar
1302
1303 print "<div style='float : right; padding-right : 4px;'>
1304 <input dojoType=\"dijit.form.TextBox\" id=\"feed_search\" size=\"20\" type=\"search\"
1305 value=\"$feed_search\">
1306 <button dojoType=\"dijit.form.Button\" onclick=\"updateFeedList()\">".
1307 __('Search')."</button>
1308 </div>";
1309
1310 print "<div dojoType=\"dijit.form.DropDownButton\">".
1311 "<span>" . __('Select')."</span>";
1312 print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
1313 print "<div onclick=\"dijit.byId('feedTree').model.setAllChecked(true)\"
1314 dojoType=\"dijit.MenuItem\">".__('All')."</div>";
1315 print "<div onclick=\"dijit.byId('feedTree').model.setAllChecked(false)\"
1316 dojoType=\"dijit.MenuItem\">".__('None')."</div>";
1317 print "</div></div>";
1318
1319 print "<div dojoType=\"dijit.form.DropDownButton\">".
1320 "<span>" . __('Feeds')."</span>";
1321 print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
1322 print "<div onclick=\"quickAddFeed()\"
1323 dojoType=\"dijit.MenuItem\">".__('Subscribe to feed')."</div>";
1324 print "<div onclick=\"editSelectedFeed()\"
1325 dojoType=\"dijit.MenuItem\">".__('Edit selected feeds')."</div>";
1326 print "<div onclick=\"resetFeedOrder()\"
1327 dojoType=\"dijit.MenuItem\">".__('Reset sort order')."</div>";
1328 print "</div></div>";
1329
1330 if (get_pref($this->link, 'ENABLE_FEED_CATS')) {
1331 print "<div dojoType=\"dijit.form.DropDownButton\">".
1332 "<span>" . __('Categories')."</span>";
1333 print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
1334 print "<div onclick=\"editFeedCats()\"
1335 dojoType=\"dijit.MenuItem\">".__('Edit categories')."</div>";
1336 print "<div onclick=\"resetCatOrder()\"
1337 dojoType=\"dijit.MenuItem\">".__('Reset sort order')."</div>";
1338 print "</div></div>";
1339
1340 }
1341
1342 print $error_button;
1343 print $inactive_button;
1344
1345 print "<button dojoType=\"dijit.form.Button\" onclick=\"removeSelectedFeeds()\">"
1346 .__('Unsubscribe')."</button dojoType=\"dijit.form.Button\"> ";
1347
1348 if (defined('_ENABLE_FEED_DEBUGGING')) {
1349
1350 print "<select id=\"feedActionChooser\" onchange=\"feedActionChange()\">
1351 <option value=\"facDefault\" selected>".__('More actions...')."</option>";
1352
1353 if (FORCE_ARTICLE_PURGE == 0) {
1354 print
1355 "<option value=\"facPurge\">".__('Manual purge')."</option>";
1356 }
1357
1358 print "
1359 <option value=\"facClear\">".__('Clear feed data')."</option>
1360 <option value=\"facRescore\">".__('Rescore articles')."</option>";
1361
1362 print "</select>";
1363
1364 }
1365
1366 print "</div>"; # toolbar
1367
1368 //print '</div>';
1369 print '<div dojoType="dijit.layout.ContentPane" region="center">';
1370
1371 print "<div id=\"feedlistLoading\">
1372 <img src='images/indicator_tiny.gif'>".
1373 __("Loading, please wait...")."</div>";
1374
1375 print "<div dojoType=\"fox.PrefFeedStore\" jsId=\"feedStore\"
1376 url=\"backend.php?op=pref-feeds&method=getfeedtree\">
1377 </div>
1378 <div dojoType=\"lib.CheckBoxStoreModel\" jsId=\"feedModel\" store=\"feedStore\"
1379 query=\"{id:'root'}\" rootId=\"root\" rootLabel=\"Feeds\"
1380 childrenAttrs=\"items\" checkboxStrict=\"false\" checkboxAll=\"false\">
1381 </div>
1382 <div dojoType=\"fox.PrefFeedTree\" id=\"feedTree\"
1383 dndController=\"dijit.tree.dndSource\"
1384 betweenThreshold=\"5\"
1385 model=\"feedModel\" openOnClick=\"false\">
1386 <script type=\"dojo/method\" event=\"onClick\" args=\"item\">
1387 var id = String(item.id);
1388 var bare_id = id.substr(id.indexOf(':')+1);
1389
1390 if (id.match('FEED:')) {
1391 editFeed(bare_id);
1392 } else if (id.match('CAT:')) {
1393 editCat(bare_id, item);
1394 }
1395 </script>
1396 <script type=\"dojo/method\" event=\"onLoad\" args=\"item\">
1397 Element.hide(\"feedlistLoading\");
1398 </script>
1399 </div>";
1400
1401 print "<div dojoType=\"dijit.Tooltip\" connectId=\"feedTree\" position=\"below\">
1402 ".__('<b>Hint:</b> you can drag feeds and categories around.')."
1403 </div>";
1404
1405 print '</div>';
1406 print '</div>';
1407
1408 print "</div>"; # feeds pane
1409
1410 print "<div dojoType=\"dijit.layout.AccordionPane\" title=\"".__('OPML')."\">";
1411
1412 print "<p>" . __("Using OPML you can export and import your feeds and Tiny Tiny RSS settings.") . " ";
1413
1414 print "<span class=\"insensitive\">" . __("Note: Only main settings profile can be migrated using OPML.") . "</span>";
1415
1416 print "</p>";
1417
1418 print "<h3>" . __("Import") . "</h3>";
1419
1420 print "<br/><iframe id=\"upload_iframe\"
1421 name=\"upload_iframe\" onload=\"opmlImportComplete(this)\"
1422 style=\"width: 400px; height: 100px; display: none;\"></iframe>";
1423
1424 print "<form name=\"opml_form\" style='display : block' target=\"upload_iframe\"
1425 enctype=\"multipart/form-data\" method=\"POST\"
1426 action=\"backend.php\">
1427 <input id=\"opml_file\" name=\"opml_file\" type=\"file\">&nbsp;
1428 <input type=\"hidden\" name=\"op\" value=\"dlg\">
c4c74732 1429 <input type=\"hidden\" name=\"method\" value=\"importOpml\">
afcfe6ca
AD
1430 <button dojoType=\"dijit.form.Button\" onclick=\"return opmlImport();\" type=\"submit\">" .
1431 __('Import') . "</button>";
1432
1433 print "<h3>" . __("Export") . "</h3>";
1434
1435 print "<p>" . __('Filename:') .
1436 " <input type=\"text\" id=\"filename\" value=\"TinyTinyRSS.opml\" />&nbsp;" .
1437 __('Include settings') . "<input type=\"checkbox\" id=\"settings\" CHECKED />" .
1438
1439 "<button dojoType=\"dijit.form.Button\"
1440 onclick=\"gotoExportOpml(document.opml_form.filename.value, document.opml_form.settings.checked)\" >" .
1441 __('Export') . "</button></p></form>";
1442
1443 print "<h3>" . __("Publish") . "</h3>";
1444
1445 print "<p>".__('Your OPML can be published publicly and can be subscribed by anyone who knows the URL below.') . " ";
1446
1447 print "<span class=\"insensitive\">" . __("Note: Published OPML does not include your Tiny Tiny RSS settings, feeds that require authentication or feeds hidden from Popular feeds.") . "</span>" . "</p>";
1448
1449 print "<button dojoType=\"dijit.form.Button\" onclick=\"return displayDlg('pubOPMLUrl')\">".
1450 __('Display URL')."</button> ";
1451
1452
1453 print "</div>"; # pane
1454
1455 if (strpos($_SERVER['HTTP_USER_AGENT'], "Firefox") !== false) {
1456
1457 print "<div dojoType=\"dijit.layout.AccordionPane\" title=\"".__('Firefox integration')."\">";
1458
1459 print "<p>" . __('This Tiny Tiny RSS site can be used as a Firefox Feed Reader by clicking the link below.') . "</p>";
1460
1461 print "<p>";
1462
1463 print "<button onclick='window.navigator.registerContentHandler(" .
1464 "\"application/vnd.mozilla.maybe.feed\", " .
1465 "\"" . add_feed_url() . "\", " . " \"Tiny Tiny RSS\")'>" .
1466 __('Click here to register this site as a feed reader.') .
1467 "</button>";
1468
1469 print "</p>";
1470
1471 print "</div>"; # pane
1472 }
1473
1474 print "<div dojoType=\"dijit.layout.AccordionPane\" title=\"".__('Subscribing using bookmarklet')."\">";
1475
1476 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>";
1477
1478 $bm_subscribe_url = str_replace('%s', '', add_feed_url());
1479
1480 $confirm_str = __('Subscribe to %s in Tiny Tiny RSS?');
1481
1482 $bm_url = htmlspecialchars("javascript:{if(confirm('$confirm_str'.replace('%s',window.location.href)))window.location.href='$bm_subscribe_url'+window.location.href}");
1483
1484 print "<a href=\"$bm_url\" class='bookmarklet'>" . __('Subscribe in Tiny Tiny RSS'). "</a>";
1485
1486 print "</div>"; #pane
1487
1488 print "<div dojoType=\"dijit.layout.AccordionPane\" title=\"".__('Published & shared articles and generated feeds')."\">";
1489
1490 print "<h3>" . __("Published articles and generated feeds") . "</h3>";
1491
1492 print "<p>".__('Published articles are exported as a public RSS feed and can be subscribed by anyone who knows the URL specified below.')."</p>";
1493
1494 $rss_url = '-2::' . htmlspecialchars(get_self_url_prefix() .
1495 "/public.php?op=rss&id=-2&view-mode=all_articles");;
1496
1497 print "<button dojoType=\"dijit.form.Button\" onclick=\"return displayDlg('generatedFeed', '$rss_url')\">".
1498 __('Display URL')."</button> ";
1499
1500 print "<button dojoType=\"dijit.form.Button\" onclick=\"return clearFeedAccessKeys()\">".
1501 __('Clear all generated URLs')."</button> ";
1502
1503 print "<h3>" . __("Articles shared by URL") . "</h3>";
1504
1505 print "<p>" . __("You can disable all articles shared by unique URLs here.") . "</p>";
1506
1507 print "<button dojoType=\"dijit.form.Button\" onclick=\"return clearArticleAccessKeys()\">".
1508 __('Unshare all articles')."</button> ";
1509
1510 print "</div>"; #pane
1511
1512 if (defined('CONSUMER_KEY') && CONSUMER_KEY != '') {
1513
1514 print "<div id=\"pref-feeds-twitter\" dojoType=\"dijit.layout.AccordionPane\" title=\"".__('Twitter')."\">";
1515
1516 $result = db_query($this->link, "SELECT COUNT(*) AS cid FROM ttrss_users
1517 WHERE twitter_oauth IS NOT NULL AND twitter_oauth != '' AND
1518 id = " . $_SESSION['uid']);
1519
1520 $is_registered = db_fetch_result($result, 0, "cid") != 0;
1521
1522 if (!$is_registered) {
1523 print_notice(__('Before you can update your Twitter feeds, you must register this instance of Tiny Tiny RSS with Twitter.com.'));
1524 } else {
1525 print_notice(__('You have been successfully registered with Twitter.com and should be able to access your Twitter feeds.'));
1526 }
1527
1528 print "<button dojoType=\"dijit.form.Button\" onclick=\"window.location.href = 'twitter.php?op=register'\">".
1529 __("Register with Twitter.com")."</button>";
1530
1531 print " ";
1532
1533 print "<button dojoType=\"dijit.form.Button\"
1534 onclick=\"return clearTwitterCredentials()\">".
1535 __("Clear stored credentials")."</button>";
1536
1537 print "</div>"; # pane
1538
1539 }
1540
1541 print "</div>"; #container
1542
1543 }
1544}
1545?>