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