1 | <?php |
||||||||
2 | class Pref_Feeds extends Handler_Protected { |
||||||||
3 | public function csrf_ignore($method) { |
||||||||
4 | $csrf_ignored = array("index", "getfeedtree", "add", "editcats", "editfeed", |
||||||||
5 | "savefeedorder", "uploadicon", "feedswitherrors", "inactivefeeds", |
||||||||
6 | "batchsubscribe"); |
||||||||
7 | |||||||||
8 | return array_search($method, $csrf_ignored) !== false; |
||||||||
9 | } |
||||||||
10 | |||||||||
11 | public static function get_ts_languages() { |
||||||||
12 | $rv = []; |
||||||||
13 | |||||||||
14 | if (DB_TYPE == "pgsql") { |
||||||||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||||||
15 | $dbh = Db::pdo(); |
||||||||
16 | |||||||||
17 | $res = $dbh->query("SELECT cfgname FROM pg_ts_config"); |
||||||||
18 | |||||||||
19 | while ($row = $res->fetch()) { |
||||||||
20 | array_push($rv, ucfirst($row['cfgname'])); |
||||||||
21 | } |
||||||||
22 | } |
||||||||
23 | |||||||||
24 | return $rv; |
||||||||
25 | } |
||||||||
26 | |||||||||
27 | public function batch_edit_cbox($elem, $label = false) { |
||||||||
28 | print "<input type=\"checkbox\" title=\"".__("Check to enable field")."\" |
||||||||
29 | onchange=\"dijit.byId('feedEditDlg').toggleField(this, '$elem', '$label')\">"; |
||||||||
30 | } |
||||||||
31 | |||||||||
32 | public function renamecat() { |
||||||||
33 | $title = clean($_REQUEST['title']); |
||||||||
34 | $id = clean($_REQUEST['id']); |
||||||||
35 | |||||||||
36 | if ($title) { |
||||||||
37 | $sth = $this->pdo->prepare("UPDATE ttrss_feed_categories SET |
||||||||
38 | title = ? WHERE id = ? AND owner_uid = ?"); |
||||||||
39 | $sth->execute([$title, $id, $_SESSION['uid']]); |
||||||||
40 | } |
||||||||
41 | } |
||||||||
42 | |||||||||
43 | private function get_category_items($cat_id) { |
||||||||
44 | |||||||||
45 | if (clean($_REQUEST['mode']) != 2) { |
||||||||
46 | $search = $_SESSION["prefs_feed_search"]; |
||||||||
47 | } else { |
||||||||
48 | $search = ""; |
||||||||
49 | } |
||||||||
50 | |||||||||
51 | // first one is set by API |
||||||||
52 | $show_empty_cats = clean($_REQUEST['force_show_empty']) || |
||||||||
53 | (clean($_REQUEST['mode']) != 2 && !$search); |
||||||||
54 | |||||||||
55 | $items = array(); |
||||||||
56 | |||||||||
57 | $sth = $this->pdo->prepare("SELECT id, title FROM ttrss_feed_categories |
||||||||
58 | WHERE owner_uid = ? AND parent_cat = ? ORDER BY order_id, title"); |
||||||||
59 | $sth->execute([$_SESSION['uid'], $cat_id]); |
||||||||
60 | |||||||||
61 | while ($line = $sth->fetch()) { |
||||||||
62 | |||||||||
63 | $cat = array(); |
||||||||
64 | $cat['id'] = 'CAT:'.$line['id']; |
||||||||
65 | $cat['bare_id'] = (int) $line['id']; |
||||||||
66 | $cat['name'] = $line['title']; |
||||||||
67 | $cat['items'] = array(); |
||||||||
68 | $cat['checkbox'] = false; |
||||||||
69 | $cat['type'] = 'category'; |
||||||||
70 | $cat['unread'] = -1; |
||||||||
71 | $cat['child_unread'] = -1; |
||||||||
72 | $cat['auxcounter'] = -1; |
||||||||
73 | $cat['parent_id'] = $cat_id; |
||||||||
74 | |||||||||
75 | $cat['items'] = $this->get_category_items($line['id']); |
||||||||
76 | |||||||||
77 | $num_children = $this->calculate_children_count($cat); |
||||||||
78 | $cat['param'] = vsprintf(_ngettext('(%d feed)', '(%d feeds)', (int) $num_children), $num_children); |
||||||||
0 ignored issues
–
show
$num_children of type integer is incompatible with the type array expected by parameter $args of vsprintf() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
79 | |||||||||
80 | if ($num_children > 0 || $show_empty_cats) { |
||||||||
81 | array_push($items, $cat); |
||||||||
82 | } |
||||||||
83 | |||||||||
84 | } |
||||||||
85 | |||||||||
86 | $fsth = $this->pdo->prepare("SELECT id, title, last_error, |
||||||||
87 | ".SUBSTRING_FOR_DATE."(last_updated,1,19) AS last_updated, update_interval |
||||||||
88 | FROM ttrss_feeds |
||||||||
89 | WHERE cat_id = :cat AND |
||||||||
90 | owner_uid = :uid AND |
||||||||
91 | (:search = '' OR (LOWER(title) LIKE :search OR LOWER(feed_url) LIKE :search)) |
||||||||
92 | ORDER BY order_id, title"); |
||||||||
93 | |||||||||
94 | $fsth->execute([":cat" => $cat_id, ":uid" => $_SESSION['uid'], ":search" => $search ? "%$search%" : ""]); |
||||||||
95 | |||||||||
96 | while ($feed_line = $fsth->fetch()) { |
||||||||
97 | $feed = array(); |
||||||||
98 | $feed['id'] = 'FEED:'.$feed_line['id']; |
||||||||
99 | $feed['bare_id'] = (int) $feed_line['id']; |
||||||||
100 | $feed['auxcounter'] = -1; |
||||||||
101 | $feed['name'] = $feed_line['title']; |
||||||||
102 | $feed['checkbox'] = false; |
||||||||
103 | $feed['unread'] = -1; |
||||||||
104 | $feed['error'] = $feed_line['last_error']; |
||||||||
105 | $feed['icon'] = Feeds::getFeedIcon($feed_line['id']); |
||||||||
106 | $feed['param'] = make_local_datetime( |
||||||||
107 | $feed_line['last_updated'], true); |
||||||||
108 | $feed['updates_disabled'] = (int) ($feed_line['update_interval'] < 0); |
||||||||
109 | |||||||||
110 | array_push($items, $feed); |
||||||||
111 | } |
||||||||
112 | |||||||||
113 | return $items; |
||||||||
114 | } |
||||||||
115 | |||||||||
116 | public function getfeedtree() { |
||||||||
117 | print json_encode($this->makefeedtree()); |
||||||||
118 | } |
||||||||
119 | |||||||||
120 | public function makefeedtree() { |
||||||||
121 | |||||||||
122 | if (clean($_REQUEST['mode']) != 2) { |
||||||||
123 | $search = $_SESSION["prefs_feed_search"]; |
||||||||
124 | } else { |
||||||||
125 | $search = ""; |
||||||||
126 | } |
||||||||
127 | |||||||||
128 | $root = array(); |
||||||||
129 | $root['id'] = 'root'; |
||||||||
130 | $root['name'] = __('Feeds'); |
||||||||
131 | $root['items'] = array(); |
||||||||
132 | $root['type'] = 'category'; |
||||||||
133 | |||||||||
134 | $enable_cats = get_pref('ENABLE_FEED_CATS'); |
||||||||
135 | |||||||||
136 | if (clean($_REQUEST['mode']) == 2) { |
||||||||
137 | |||||||||
138 | if ($enable_cats) { |
||||||||
139 | $cat = $this->feedlist_init_cat(-1); |
||||||||
140 | } else { |
||||||||
141 | $cat['items'] = array(); |
||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||||||
142 | } |
||||||||
143 | |||||||||
144 | foreach (array(-4, -3, -1, -2, 0, -6) as $i) { |
||||||||
145 | array_push($cat['items'], $this->feedlist_init_feed($i)); |
||||||||
146 | } |
||||||||
147 | |||||||||
148 | /* Plugin feeds for -1 */ |
||||||||
149 | |||||||||
150 | $feeds = PluginHost::getInstance()->get_feeds(-1); |
||||||||
151 | |||||||||
152 | if ($feeds) { |
||||||||
153 | foreach ($feeds as $feed) { |
||||||||
154 | $feed_id = PluginHost::pfeed_to_feed_id($feed['id']); |
||||||||
155 | |||||||||
156 | $item = array(); |
||||||||
157 | $item['id'] = 'FEED:'.$feed_id; |
||||||||
158 | $item['bare_id'] = (int) $feed_id; |
||||||||
159 | $item['auxcounter'] = -1; |
||||||||
160 | $item['name'] = $feed['title']; |
||||||||
161 | $item['checkbox'] = false; |
||||||||
162 | $item['error'] = ''; |
||||||||
163 | $item['icon'] = $feed['icon']; |
||||||||
164 | |||||||||
165 | $item['param'] = ''; |
||||||||
166 | $item['unread'] = -1; |
||||||||
167 | $item['type'] = 'feed'; |
||||||||
168 | |||||||||
169 | array_push($cat['items'], $item); |
||||||||
170 | } |
||||||||
171 | } |
||||||||
172 | |||||||||
173 | if ($enable_cats) { |
||||||||
174 | array_push($root['items'], $cat); |
||||||||
175 | } else { |
||||||||
176 | $root['items'] = array_merge($root['items'], $cat['items']); |
||||||||
177 | } |
||||||||
178 | |||||||||
179 | $sth = $this->pdo->prepare("SELECT * FROM |
||||||||
180 | ttrss_labels2 WHERE owner_uid = ? ORDER by caption"); |
||||||||
181 | $sth->execute([$_SESSION['uid']]); |
||||||||
182 | |||||||||
183 | if (get_pref('ENABLE_FEED_CATS')) { |
||||||||
184 | $cat = $this->feedlist_init_cat(-2); |
||||||||
185 | } else { |
||||||||
186 | $cat['items'] = array(); |
||||||||
187 | } |
||||||||
188 | |||||||||
189 | $num_labels = 0; |
||||||||
190 | while ($line = $sth->fetch()) { |
||||||||
191 | ++$num_labels; |
||||||||
192 | |||||||||
193 | $label_id = Labels::label_to_feed_id($line['id']); |
||||||||
194 | |||||||||
195 | $feed = $this->feedlist_init_feed($label_id, false, 0); |
||||||||
196 | |||||||||
197 | $feed['fg_color'] = $line['fg_color']; |
||||||||
198 | $feed['bg_color'] = $line['bg_color']; |
||||||||
199 | |||||||||
200 | array_push($cat['items'], $feed); |
||||||||
201 | } |
||||||||
202 | |||||||||
203 | if ($num_labels) { |
||||||||
204 | if ($enable_cats) { |
||||||||
205 | array_push($root['items'], $cat); |
||||||||
206 | } else { |
||||||||
207 | $root['items'] = array_merge($root['items'], $cat['items']); |
||||||||
208 | } |
||||||||
209 | } |
||||||||
210 | } |
||||||||
211 | |||||||||
212 | if ($enable_cats) { |
||||||||
213 | $show_empty_cats = clean($_REQUEST['force_show_empty']) || |
||||||||
214 | (clean($_REQUEST['mode']) != 2 && !$search); |
||||||||
215 | |||||||||
216 | $sth = $this->pdo->prepare("SELECT id, title FROM ttrss_feed_categories |
||||||||
217 | WHERE owner_uid = ? AND parent_cat IS NULL ORDER BY order_id, title"); |
||||||||
218 | $sth->execute([$_SESSION['uid']]); |
||||||||
219 | |||||||||
220 | while ($line = $sth->fetch()) { |
||||||||
221 | $cat = array(); |
||||||||
222 | $cat['id'] = 'CAT:'.$line['id']; |
||||||||
223 | $cat['bare_id'] = (int) $line['id']; |
||||||||
224 | $cat['auxcounter'] = -1; |
||||||||
225 | $cat['name'] = $line['title']; |
||||||||
226 | $cat['items'] = array(); |
||||||||
227 | $cat['checkbox'] = false; |
||||||||
228 | $cat['type'] = 'category'; |
||||||||
229 | $cat['unread'] = -1; |
||||||||
230 | $cat['child_unread'] = -1; |
||||||||
231 | |||||||||
232 | $cat['items'] = $this->get_category_items($line['id']); |
||||||||
233 | |||||||||
234 | $num_children = $this->calculate_children_count($cat); |
||||||||
235 | $cat['param'] = vsprintf(_ngettext('(%d feed)', '(%d feeds)', (int) $num_children), $num_children); |
||||||||
0 ignored issues
–
show
$num_children of type integer is incompatible with the type array expected by parameter $args of vsprintf() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
236 | |||||||||
237 | if ($num_children > 0 || $show_empty_cats) { |
||||||||
238 | array_push($root['items'], $cat); |
||||||||
239 | } |
||||||||
240 | |||||||||
241 | $root['param'] += count($cat['items']); |
||||||||
242 | } |
||||||||
243 | |||||||||
244 | /* Uncategorized is a special case */ |
||||||||
245 | |||||||||
246 | $cat = array(); |
||||||||
247 | $cat['id'] = 'CAT:0'; |
||||||||
248 | $cat['bare_id'] = 0; |
||||||||
249 | $cat['auxcounter'] = -1; |
||||||||
250 | $cat['name'] = __("Uncategorized"); |
||||||||
251 | $cat['items'] = array(); |
||||||||
252 | $cat['type'] = 'category'; |
||||||||
253 | $cat['checkbox'] = false; |
||||||||
254 | $cat['unread'] = -1; |
||||||||
255 | $cat['child_unread'] = -1; |
||||||||
256 | |||||||||
257 | $fsth = $this->pdo->prepare("SELECT id, title,last_error, |
||||||||
258 | ".SUBSTRING_FOR_DATE."(last_updated,1,19) AS last_updated, update_interval |
||||||||
259 | FROM ttrss_feeds |
||||||||
260 | WHERE cat_id IS NULL AND |
||||||||
261 | owner_uid = :uid AND |
||||||||
262 | (:search = '' OR (LOWER(title) LIKE :search OR LOWER(feed_url) LIKE :search)) |
||||||||
263 | ORDER BY order_id, title"); |
||||||||
264 | $fsth->execute([":uid" => $_SESSION['uid'], ":search" => $search ? "%$search%" : ""]); |
||||||||
265 | |||||||||
266 | while ($feed_line = $fsth->fetch()) { |
||||||||
267 | $feed = array(); |
||||||||
268 | $feed['id'] = 'FEED:'.$feed_line['id']; |
||||||||
269 | $feed['bare_id'] = (int) $feed_line['id']; |
||||||||
270 | $feed['auxcounter'] = -1; |
||||||||
271 | $feed['name'] = $feed_line['title']; |
||||||||
272 | $feed['checkbox'] = false; |
||||||||
273 | $feed['error'] = $feed_line['last_error']; |
||||||||
274 | $feed['icon'] = Feeds::getFeedIcon($feed_line['id']); |
||||||||
275 | $feed['param'] = make_local_datetime( |
||||||||
276 | $feed_line['last_updated'], true); |
||||||||
277 | $feed['unread'] = -1; |
||||||||
278 | $feed['type'] = 'feed'; |
||||||||
279 | $feed['updates_disabled'] = (int) ($feed_line['update_interval'] < 0); |
||||||||
280 | |||||||||
281 | array_push($cat['items'], $feed); |
||||||||
282 | } |
||||||||
283 | |||||||||
284 | $cat['param'] = vsprintf(_ngettext('(%d feed)', '(%d feeds)', count($cat['items'])), count($cat['items'])); |
||||||||
285 | |||||||||
286 | if (count($cat['items']) > 0 || $show_empty_cats) { |
||||||||
287 | array_push($root['items'], $cat); |
||||||||
288 | } |
||||||||
289 | |||||||||
290 | $num_children = $this->calculate_children_count($root); |
||||||||
291 | $root['param'] = vsprintf(_ngettext('(%d feed)', '(%d feeds)', (int) $num_children), $num_children); |
||||||||
292 | |||||||||
293 | } else { |
||||||||
294 | $fsth = $this->pdo->prepare("SELECT id, title, last_error, |
||||||||
295 | ".SUBSTRING_FOR_DATE."(last_updated,1,19) AS last_updated, update_interval |
||||||||
296 | FROM ttrss_feeds |
||||||||
297 | WHERE owner_uid = :uid AND |
||||||||
298 | (:search = '' OR (LOWER(title) LIKE :search OR LOWER(feed_url) LIKE :search)) |
||||||||
299 | ORDER BY order_id, title"); |
||||||||
300 | $fsth->execute([":uid" => $_SESSION['uid'], ":search" => $search ? "%$search%" : ""]); |
||||||||
301 | |||||||||
302 | while ($feed_line = $fsth->fetch()) { |
||||||||
303 | $feed = array(); |
||||||||
304 | $feed['id'] = 'FEED:'.$feed_line['id']; |
||||||||
305 | $feed['bare_id'] = (int) $feed_line['id']; |
||||||||
306 | $feed['auxcounter'] = -1; |
||||||||
307 | $feed['name'] = $feed_line['title']; |
||||||||
308 | $feed['checkbox'] = false; |
||||||||
309 | $feed['error'] = $feed_line['last_error']; |
||||||||
310 | $feed['icon'] = Feeds::getFeedIcon($feed_line['id']); |
||||||||
311 | $feed['param'] = make_local_datetime( |
||||||||
312 | $feed_line['last_updated'], true); |
||||||||
313 | $feed['unread'] = -1; |
||||||||
314 | $feed['type'] = 'feed'; |
||||||||
315 | $feed['updates_disabled'] = (int) ($feed_line['update_interval'] < 0); |
||||||||
316 | |||||||||
317 | array_push($root['items'], $feed); |
||||||||
318 | } |
||||||||
319 | |||||||||
320 | $root['param'] = vsprintf(_ngettext('(%d feed)', '(%d feeds)', count($root['items'])), count($root['items'])); |
||||||||
321 | } |
||||||||
322 | |||||||||
323 | $fl = array(); |
||||||||
324 | $fl['identifier'] = 'id'; |
||||||||
325 | $fl['label'] = 'name'; |
||||||||
326 | |||||||||
327 | if (clean($_REQUEST['mode']) != 2) { |
||||||||
328 | $fl['items'] = array($root); |
||||||||
329 | } else { |
||||||||
330 | $fl['items'] = $root['items']; |
||||||||
331 | } |
||||||||
332 | |||||||||
333 | return $fl; |
||||||||
334 | } |
||||||||
335 | |||||||||
336 | public function catsortreset() { |
||||||||
337 | $sth = $this->pdo->prepare("UPDATE ttrss_feed_categories |
||||||||
338 | SET order_id = 0 WHERE owner_uid = ?"); |
||||||||
339 | $sth->execute([$_SESSION['uid']]); |
||||||||
340 | } |
||||||||
341 | |||||||||
342 | public function feedsortreset() { |
||||||||
343 | $sth = $this->pdo->prepare("UPDATE ttrss_feeds |
||||||||
344 | SET order_id = 0 WHERE owner_uid = ?"); |
||||||||
345 | $sth->execute([$_SESSION['uid']]); |
||||||||
346 | } |
||||||||
347 | |||||||||
348 | private function process_category_order(&$data_map, $item_id, $parent_id = false, $nest_level = 0) { |
||||||||
349 | |||||||||
350 | $prefix = ""; |
||||||||
351 | for ($i = 0; $i < $nest_level; $i++) { |
||||||||
352 | $prefix .= " "; |
||||||||
353 | } |
||||||||
354 | |||||||||
355 | Debug::log("$prefix C: $item_id P: $parent_id"); |
||||||||
356 | |||||||||
357 | $bare_item_id = substr($item_id, strpos($item_id, ':') + 1); |
||||||||
358 | |||||||||
359 | if ($item_id != 'root') { |
||||||||
360 | if ($parent_id && $parent_id != 'root') { |
||||||||
361 | $parent_bare_id = substr($parent_id, strpos($parent_id, ':') + 1); |
||||||||
362 | $parent_qpart = $parent_bare_id; |
||||||||
363 | } else { |
||||||||
364 | $parent_qpart = null; |
||||||||
365 | } |
||||||||
366 | |||||||||
367 | $sth = $this->pdo->prepare("UPDATE ttrss_feed_categories |
||||||||
368 | SET parent_cat = ? WHERE id = ? AND |
||||||||
369 | owner_uid = ?"); |
||||||||
370 | $sth->execute([$parent_qpart, $bare_item_id, $_SESSION['uid']]); |
||||||||
371 | } |
||||||||
372 | |||||||||
373 | $order_id = 1; |
||||||||
374 | |||||||||
375 | $cat = $data_map[$item_id]; |
||||||||
376 | |||||||||
377 | if ($cat && is_array($cat)) { |
||||||||
378 | foreach ($cat as $item) { |
||||||||
379 | $id = $item['_reference']; |
||||||||
380 | $bare_id = substr($id, strpos($id, ':') + 1); |
||||||||
381 | |||||||||
382 | Debug::log("$prefix [$order_id] $id/$bare_id"); |
||||||||
383 | |||||||||
384 | if ($item['_reference']) { |
||||||||
385 | |||||||||
386 | if (strpos($id, "FEED") === 0) { |
||||||||
387 | |||||||||
388 | $cat_id = ($item_id != "root") ? $bare_item_id : null; |
||||||||
389 | |||||||||
390 | $sth = $this->pdo->prepare("UPDATE ttrss_feeds |
||||||||
391 | SET order_id = ?, cat_id = ? |
||||||||
392 | WHERE id = ? AND owner_uid = ?"); |
||||||||
393 | |||||||||
394 | $sth->execute([$order_id, $cat_id ? $cat_id : null, $bare_id, $_SESSION['uid']]); |
||||||||
395 | |||||||||
396 | } else if (strpos($id, "CAT:") === 0) { |
||||||||
397 | $this->process_category_order($data_map, $item['_reference'], $item_id, |
||||||||
398 | $nest_level + 1); |
||||||||
399 | |||||||||
400 | $sth = $this->pdo->prepare("UPDATE ttrss_feed_categories |
||||||||
401 | SET order_id = ? WHERE id = ? AND |
||||||||
402 | owner_uid = ?"); |
||||||||
403 | $sth->execute([$order_id, $bare_id, $_SESSION['uid']]); |
||||||||
404 | } |
||||||||
405 | } |
||||||||
406 | |||||||||
407 | ++$order_id; |
||||||||
408 | } |
||||||||
409 | } |
||||||||
410 | } |
||||||||
411 | |||||||||
412 | public function savefeedorder() { |
||||||||
413 | $data = json_decode($_POST['payload'], true); |
||||||||
414 | |||||||||
415 | #file_put_contents("/tmp/saveorder.json", clean($_POST['payload'])); |
||||||||
416 | #$data = json_decode(file_get_contents("/tmp/saveorder.json"), true); |
||||||||
417 | |||||||||
418 | if (!is_array($data['items'])) { |
||||||||
419 | $data['items'] = json_decode($data['items'], true); |
||||||||
420 | } |
||||||||
421 | |||||||||
422 | # print_r($data['items']); |
||||||||
423 | |||||||||
424 | if (is_array($data) && is_array($data['items'])) { |
||||||||
425 | # $cat_order_id = 0; |
||||||||
426 | |||||||||
427 | $data_map = array(); |
||||||||
428 | $root_item = false; |
||||||||
429 | |||||||||
430 | foreach ($data['items'] as $item) { |
||||||||
431 | |||||||||
432 | # if ($item['id'] != 'root') { |
||||||||
433 | if (is_array($item['items'])) { |
||||||||
434 | if (isset($item['items']['_reference'])) { |
||||||||
435 | $data_map[$item['id']] = array($item['items']); |
||||||||
436 | } else { |
||||||||
437 | $data_map[$item['id']] = $item['items']; |
||||||||
438 | } |
||||||||
439 | } |
||||||||
440 | if ($item['id'] == 'root') { |
||||||||
441 | $root_item = $item['id']; |
||||||||
442 | } |
||||||||
443 | } |
||||||||
444 | |||||||||
445 | $this->process_category_order($data_map, $root_item); |
||||||||
446 | } |
||||||||
447 | } |
||||||||
448 | |||||||||
449 | public function removeicon() { |
||||||||
450 | $feed_id = clean($_REQUEST["feed_id"]); |
||||||||
451 | |||||||||
452 | $sth = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE id = ? AND owner_uid = ?"); |
||||||||
453 | $sth->execute([$feed_id, $_SESSION['uid']]); |
||||||||
454 | |||||||||
455 | if ($sth->fetch()) { |
||||||||
456 | @unlink(ICONS_DIR."/$feed_id.ico"); |
||||||||
0 ignored issues
–
show
It seems like you do not handle an error condition for
unlink() . This can introduce security issues, and is generally not recommended.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
|||||||||
457 | |||||||||
458 | $sth = $this->pdo->prepare("UPDATE ttrss_feeds SET favicon_avg_color = NULL where id = ?"); |
||||||||
459 | $sth->execute([$feed_id]); |
||||||||
460 | } |
||||||||
461 | } |
||||||||
462 | |||||||||
463 | public function uploadicon() { |
||||||||
464 | header("Content-type: text/html"); |
||||||||
465 | |||||||||
466 | if (is_uploaded_file($_FILES['icon_file']['tmp_name'])) { |
||||||||
467 | $tmp_file = tempnam(CACHE_DIR.'/upload', 'icon'); |
||||||||
0 ignored issues
–
show
|
|||||||||
468 | |||||||||
469 | $result = move_uploaded_file($_FILES['icon_file']['tmp_name'], |
||||||||
470 | $tmp_file); |
||||||||
471 | |||||||||
472 | if (!$result) { |
||||||||
473 | return; |
||||||||
474 | } |
||||||||
475 | } else { |
||||||||
476 | return; |
||||||||
477 | } |
||||||||
478 | |||||||||
479 | $icon_file = $tmp_file; |
||||||||
480 | $feed_id = clean($_REQUEST["feed_id"]); |
||||||||
481 | $rc = 2; // failed |
||||||||
482 | |||||||||
483 | if (is_file($icon_file) && $feed_id) { |
||||||||
484 | if (filesize($icon_file) < 65535) { |
||||||||
485 | |||||||||
486 | $sth = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE id = ? AND owner_uid = ?"); |
||||||||
487 | $sth->execute([$feed_id, $_SESSION['uid']]); |
||||||||
488 | |||||||||
489 | if ($sth->fetch()) { |
||||||||
490 | @unlink(ICONS_DIR."/$feed_id.ico"); |
||||||||
0 ignored issues
–
show
It seems like you do not handle an error condition for
unlink() . This can introduce security issues, and is generally not recommended.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
|||||||||
491 | if (rename($icon_file, ICONS_DIR."/$feed_id.ico")) { |
||||||||
492 | |||||||||
493 | $sth = $this->pdo->prepare("UPDATE ttrss_feeds SET favicon_avg_color = '' WHERE id = ?"); |
||||||||
494 | $sth->execute([$feed_id]); |
||||||||
495 | |||||||||
496 | $rc = 0; |
||||||||
497 | } |
||||||||
498 | } |
||||||||
499 | } else { |
||||||||
500 | $rc = 1; |
||||||||
501 | } |
||||||||
502 | } |
||||||||
503 | |||||||||
504 | if (is_file($icon_file)) { |
||||||||
505 | @unlink($icon_file); |
||||||||
506 | } |
||||||||
507 | |||||||||
508 | print $rc; |
||||||||
509 | return; |
||||||||
510 | } |
||||||||
511 | |||||||||
512 | public function editfeed() { |
||||||||
513 | global $purge_intervals; |
||||||||
514 | global $update_intervals; |
||||||||
515 | |||||||||
516 | |||||||||
517 | $feed_id = clean($_REQUEST["id"]); |
||||||||
518 | |||||||||
519 | $sth = $this->pdo->prepare("SELECT * FROM ttrss_feeds WHERE id = ? AND |
||||||||
520 | owner_uid = ?"); |
||||||||
521 | $sth->execute([$feed_id, $_SESSION['uid']]); |
||||||||
522 | |||||||||
523 | if ($row = $sth->fetch()) { |
||||||||
524 | print '<div dojoType="dijit.layout.TabContainer" style="height : 450px"> |
||||||||
525 | <div dojoType="dijit.layout.ContentPane" title="'.__('General').'">'; |
||||||||
526 | |||||||||
527 | $title = htmlspecialchars($row["title"]); |
||||||||
528 | |||||||||
529 | print_hidden("id", "$feed_id"); |
||||||||
530 | print_hidden("op", "pref-feeds"); |
||||||||
531 | print_hidden("method", "editSave"); |
||||||||
532 | |||||||||
533 | print "<header>".__("Feed")."</header>"; |
||||||||
534 | print "<section>"; |
||||||||
535 | |||||||||
536 | /* Title */ |
||||||||
537 | |||||||||
538 | print "<fieldset>"; |
||||||||
539 | |||||||||
540 | print "<input dojoType='dijit.form.ValidationTextBox' required='1' |
||||||||
541 | placeHolder=\"".__("Feed Title")."\" |
||||||||
542 | style='font-size : 16px; width: 500px' name='title' value=\"$title\">"; |
||||||||
543 | |||||||||
544 | print "</fieldset>"; |
||||||||
545 | |||||||||
546 | /* Feed URL */ |
||||||||
547 | |||||||||
548 | $feed_url = htmlspecialchars($row["feed_url"]); |
||||||||
549 | |||||||||
550 | print "<fieldset>"; |
||||||||
551 | |||||||||
552 | print "<label>".__('URL:')."</label> "; |
||||||||
553 | print "<input dojoType='dijit.form.ValidationTextBox' required='1' |
||||||||
554 | placeHolder=\"".__("Feed URL")."\" |
||||||||
555 | regExp='^(http|https)://.*' style='width : 300px' |
||||||||
556 | name='feed_url' value=\"$feed_url\">"; |
||||||||
557 | |||||||||
558 | $last_error = $row["last_error"]; |
||||||||
559 | |||||||||
560 | if ($last_error) { |
||||||||
561 | print " <i class=\"material-icons\" |
||||||||
562 | title=\"".htmlspecialchars($last_error)."\">error</i>"; |
||||||||
563 | } |
||||||||
564 | |||||||||
565 | print "</fieldset>"; |
||||||||
566 | |||||||||
567 | /* Category */ |
||||||||
568 | |||||||||
569 | if (get_pref('ENABLE_FEED_CATS')) { |
||||||||
570 | |||||||||
571 | $cat_id = $row["cat_id"]; |
||||||||
572 | |||||||||
573 | print "<fieldset>"; |
||||||||
574 | |||||||||
575 | print "<label>".__('Place in category:')."</label> "; |
||||||||
576 | |||||||||
577 | print_feed_cat_select("cat_id", $cat_id, |
||||||||
578 | 'dojoType="fox.form.Select"'); |
||||||||
579 | |||||||||
580 | print "</fieldset>"; |
||||||||
581 | } |
||||||||
582 | |||||||||
583 | /* Site URL */ |
||||||||
584 | |||||||||
585 | $site_url = htmlspecialchars($row["site_url"]); |
||||||||
586 | |||||||||
587 | print "<fieldset>"; |
||||||||
588 | |||||||||
589 | print "<label>".__('Site URL:')."</label> "; |
||||||||
590 | print "<input dojoType='dijit.form.ValidationTextBox' required='1' |
||||||||
591 | placeHolder=\"".__("Site URL")."\" |
||||||||
592 | regExp='^(http|https)://.*' style='width : 300px' |
||||||||
593 | name='site_url' value=\"$site_url\">"; |
||||||||
594 | |||||||||
595 | print "</fieldset>"; |
||||||||
596 | |||||||||
597 | /* FTS Stemming Language */ |
||||||||
598 | |||||||||
599 | if (DB_TYPE == "pgsql") { |
||||||||
0 ignored issues
–
show
|
|||||||||
600 | $feed_language = $row["feed_language"]; |
||||||||
601 | |||||||||
602 | if (!$feed_language) { |
||||||||
603 | $feed_language = get_pref('DEFAULT_SEARCH_LANGUAGE'); |
||||||||
604 | } |
||||||||
605 | |||||||||
606 | print "<fieldset>"; |
||||||||
607 | |||||||||
608 | print "<label>".__('Language:')."</label> "; |
||||||||
609 | print_select("feed_language", $feed_language, $this::get_ts_languages(), |
||||||||
610 | 'dojoType="fox.form.Select"'); |
||||||||
611 | |||||||||
612 | print "</fieldset>"; |
||||||||
613 | } |
||||||||
614 | |||||||||
615 | print "</section>"; |
||||||||
616 | |||||||||
617 | print "<header>".__("Update")."</header>"; |
||||||||
618 | print "<section>"; |
||||||||
619 | |||||||||
620 | /* Update Interval */ |
||||||||
621 | |||||||||
622 | $update_interval = $row["update_interval"]; |
||||||||
623 | |||||||||
624 | print "<fieldset>"; |
||||||||
625 | |||||||||
626 | print "<label>".__("Interval:")."</label> "; |
||||||||
627 | |||||||||
628 | print_select_hash("update_interval", $update_interval, $update_intervals, |
||||||||
629 | 'dojoType="fox.form.Select"'); |
||||||||
630 | |||||||||
631 | print "</fieldset>"; |
||||||||
632 | |||||||||
633 | /* Purge intl */ |
||||||||
634 | |||||||||
635 | $purge_interval = $row["purge_interval"]; |
||||||||
636 | |||||||||
637 | print "<fieldset>"; |
||||||||
638 | |||||||||
639 | print "<label>".__('Article purging:')."</label> "; |
||||||||
640 | |||||||||
641 | print_select_hash("purge_interval", $purge_interval, $purge_intervals, |
||||||||
642 | 'dojoType="fox.form.Select" '. |
||||||||
643 | ((FORCE_ARTICLE_PURGE == 0) ? "" : 'disabled="1"')); |
||||||||
0 ignored issues
–
show
|
|||||||||
644 | |||||||||
645 | print "</fieldset>"; |
||||||||
646 | |||||||||
647 | print "</section>"; |
||||||||
648 | |||||||||
649 | $auth_login = htmlspecialchars($row["auth_login"]); |
||||||||
650 | $auth_pass = htmlspecialchars($row["auth_pass"]); |
||||||||
651 | |||||||||
652 | $auth_enabled = $auth_login !== '' || $auth_pass !== ''; |
||||||||
653 | |||||||||
654 | $auth_style = $auth_enabled ? '' : 'display: none'; |
||||||||
655 | print "<div id='feedEditDlg_loginContainer' style='$auth_style'>"; |
||||||||
656 | print "<header>".__("Authentication")."</header>"; |
||||||||
657 | print "<section>"; |
||||||||
658 | |||||||||
659 | print "<fieldset>"; |
||||||||
660 | |||||||||
661 | print "<input dojoType='dijit.form.TextBox' id='feedEditDlg_login' |
||||||||
662 | placeHolder='".__("Login")."' |
||||||||
663 | autocomplete='new-password' |
||||||||
664 | name='auth_login' value=\"$auth_login\">"; |
||||||||
665 | |||||||||
666 | print "</fieldset><fieldset>"; |
||||||||
667 | |||||||||
668 | print "<input dojoType='dijit.form.TextBox' type='password' name='auth_pass' |
||||||||
669 | autocomplete='new-password' |
||||||||
670 | placeHolder='".__("Password")."' |
||||||||
671 | value=\"$auth_pass\">"; |
||||||||
672 | |||||||||
673 | print "<div dojoType='dijit.Tooltip' connectId='feedEditDlg_login' position='below'> |
||||||||
674 | ".__('<b>Hint:</b> you need to fill in your login information if your feed requires authentication, except for Twitter feeds.')." |
||||||||
675 | </div>"; |
||||||||
676 | |||||||||
677 | print "</fieldset>"; |
||||||||
678 | |||||||||
679 | print "</section></div>"; |
||||||||
680 | |||||||||
681 | $auth_checked = $auth_enabled ? 'checked' : ''; |
||||||||
682 | print "<label class='checkbox'> |
||||||||
683 | <input type='checkbox' $auth_checked name='need_auth' dojoType='dijit.form.CheckBox' id='feedEditDlg_loginCheck' |
||||||||
684 | onclick='displayIfChecked(this, \"feedEditDlg_loginContainer\")'> |
||||||||
685 | ".__('This feed requires authentication.')."</label>"; |
||||||||
686 | |||||||||
687 | print '</div><div dojoType="dijit.layout.ContentPane" title="'.__('Options').'">'; |
||||||||
688 | |||||||||
689 | print "<section class='narrow'>"; |
||||||||
690 | |||||||||
691 | $include_in_digest = $row["include_in_digest"]; |
||||||||
692 | |||||||||
693 | if ($include_in_digest) { |
||||||||
694 | $checked = "checked=\"1\""; |
||||||||
695 | } else { |
||||||||
696 | $checked = ""; |
||||||||
697 | } |
||||||||
698 | |||||||||
699 | print "<fieldset class='narrow'>"; |
||||||||
700 | |||||||||
701 | print "<label class='checkbox'><input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" id=\"include_in_digest\" |
||||||||
702 | name=\"include_in_digest\" |
||||||||
703 | $checked> ".__('Include in e-mail digest')."</label>"; |
||||||||
704 | |||||||||
705 | print "</fieldset>"; |
||||||||
706 | |||||||||
707 | $always_display_enclosures = $row["always_display_enclosures"]; |
||||||||
708 | |||||||||
709 | if ($always_display_enclosures) { |
||||||||
710 | $checked = "checked"; |
||||||||
711 | } else { |
||||||||
712 | $checked = ""; |
||||||||
713 | } |
||||||||
714 | |||||||||
715 | print "<fieldset class='narrow'>"; |
||||||||
716 | |||||||||
717 | print "<label class='checkbox'><input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" id=\"always_display_enclosures\" |
||||||||
718 | name=\"always_display_enclosures\" |
||||||||
719 | $checked> ".__('Always display image attachments')."</label>"; |
||||||||
720 | |||||||||
721 | print "</fieldset>"; |
||||||||
722 | |||||||||
723 | $hide_images = $row["hide_images"]; |
||||||||
724 | |||||||||
725 | if ($hide_images) { |
||||||||
726 | $checked = "checked=\"1\""; |
||||||||
727 | } else { |
||||||||
728 | $checked = ""; |
||||||||
729 | } |
||||||||
730 | |||||||||
731 | print "<fieldset class='narrow'>"; |
||||||||
732 | |||||||||
733 | print "<label class='checkbox'><input dojoType='dijit.form.CheckBox' type='checkbox' id='hide_images' |
||||||||
734 | name='hide_images' $checked> ".__('Do not embed media')."</label>"; |
||||||||
735 | |||||||||
736 | print "</fieldset>"; |
||||||||
737 | |||||||||
738 | $cache_images = $row["cache_images"]; |
||||||||
739 | |||||||||
740 | if ($cache_images) { |
||||||||
741 | $checked = "checked=\"1\""; |
||||||||
742 | } else { |
||||||||
743 | $checked = ""; |
||||||||
744 | } |
||||||||
745 | |||||||||
746 | print "<fieldset class='narrow'>"; |
||||||||
747 | |||||||||
748 | print "<label class='checkbox'><input dojoType='dijit.form.CheckBox' type='checkbox' id='cache_images' |
||||||||
749 | name='cache_images' $checked> ".__('Cache media')."</label>"; |
||||||||
750 | |||||||||
751 | print "</fieldset>"; |
||||||||
752 | |||||||||
753 | $mark_unread_on_update = $row["mark_unread_on_update"]; |
||||||||
754 | |||||||||
755 | if ($mark_unread_on_update) { |
||||||||
756 | $checked = "checked"; |
||||||||
757 | } else { |
||||||||
758 | $checked = ""; |
||||||||
759 | } |
||||||||
760 | |||||||||
761 | print "<fieldset class='narrow'>"; |
||||||||
762 | |||||||||
763 | print "<label class='checkbox'><input dojoType='dijit.form.CheckBox' type='checkbox' id='mark_unread_on_update' |
||||||||
764 | name='mark_unread_on_update' $checked> ".__('Mark updated articles as unread')."</label>"; |
||||||||
765 | |||||||||
766 | print "</fieldset>"; |
||||||||
767 | |||||||||
768 | print '</div><div dojoType="dijit.layout.ContentPane" title="'.__('Icon').'">'; |
||||||||
769 | |||||||||
770 | /* Icon */ |
||||||||
771 | |||||||||
772 | print "<img class='feedIcon feed-editor-icon' src=\"".Feeds::getFeedIcon($feed_id)."\">"; |
||||||||
0 ignored issues
–
show
Are you sure
Feeds::getFeedIcon($feed_id) of type false|string can be used in concatenation ?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
773 | |||||||||
774 | print "<form onsubmit='return false;' id='feed_icon_upload_form' |
||||||||
775 | enctype='multipart/form-data' method='POST'> |
||||||||
776 | <label class='dijitButton'>".__("Choose file...")." |
||||||||
777 | <input style='display: none' id='icon_file' size='10' name='icon_file' type='file'> |
||||||||
778 | </label> |
||||||||
779 | <input type='hidden' name='op' value='pref-feeds'> |
||||||||
780 | <input type='hidden' name='feed_id' value='$feed_id'> |
||||||||
781 | <input type='hidden' name='method' value='uploadicon'> |
||||||||
782 | <button dojoType='dijit.form.Button' onclick=\"return CommonDialogs.uploadFeedIcon();\" |
||||||||
783 | type='submit'>".__('Replace')."</button> |
||||||||
784 | <button class='alt-danger' dojoType='dijit.form.Button' onclick=\"return CommonDialogs.removeFeedIcon($feed_id);\" |
||||||||
785 | type='submit'>".__('Remove')."</button> |
||||||||
786 | </form>"; |
||||||||
787 | |||||||||
788 | print "</section>"; |
||||||||
789 | |||||||||
790 | print '</div><div dojoType="dijit.layout.ContentPane" title="'.__('Plugins').'">'; |
||||||||
791 | |||||||||
792 | PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_EDIT_FEED, |
||||||||
793 | "hook_prefs_edit_feed", $feed_id); |
||||||||
794 | |||||||||
795 | print "</div></div>"; |
||||||||
796 | |||||||||
797 | $title = htmlspecialchars($title, ENT_QUOTES); |
||||||||
798 | |||||||||
799 | print "<footer> |
||||||||
800 | <button style='float : left' class='alt-danger' dojoType='dijit.form.Button' onclick='return CommonDialogs.unsubscribeFeed($feed_id, \"$title\")'>". |
||||||||
801 | __('Unsubscribe')."</button> |
||||||||
802 | <button dojoType='dijit.form.Button' class='alt-primary' onclick=\"return dijit.byId('feedEditDlg').execute()\">".__('Save')."</button> |
||||||||
803 | <button dojoType='dijit.form.Button' onclick=\"return dijit.byId('feedEditDlg').hide()\">".__('Cancel')."</button> |
||||||||
804 | </footer>"; |
||||||||
805 | } |
||||||||
806 | } |
||||||||
807 | |||||||||
808 | public function editfeeds() { |
||||||||
809 | global $purge_intervals; |
||||||||
810 | global $update_intervals; |
||||||||
811 | |||||||||
812 | $feed_ids = clean($_REQUEST["ids"]); |
||||||||
813 | |||||||||
814 | print_notice("Enable the options you wish to apply using checkboxes on the right:"); |
||||||||
0 ignored issues
–
show
The function
print_notice() has been deprecated: Use twig function noticeMessage
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This function has been deprecated. The supplier of the function has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead. ![]() The call to
print_notice() has too many arguments starting with 'Enable the options you ...eckboxes on the right:' .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above. ![]() |
|||||||||
815 | |||||||||
816 | print "<p>"; |
||||||||
817 | |||||||||
818 | print_hidden("ids", "$feed_ids"); |
||||||||
819 | print_hidden("op", "pref-feeds"); |
||||||||
820 | print_hidden("method", "batchEditSave"); |
||||||||
821 | |||||||||
822 | print "<header>".__("Feed")."</header>"; |
||||||||
823 | print "<section>"; |
||||||||
824 | |||||||||
825 | /* Category */ |
||||||||
826 | |||||||||
827 | if (get_pref('ENABLE_FEED_CATS')) { |
||||||||
828 | |||||||||
829 | print "<fieldset>"; |
||||||||
830 | |||||||||
831 | print "<label>".__('Place in category:')."</label> "; |
||||||||
832 | |||||||||
833 | print_feed_cat_select("cat_id", false, |
||||||||
834 | 'disabled="1" dojoType="fox.form.Select"'); |
||||||||
835 | |||||||||
836 | $this->batch_edit_cbox("cat_id"); |
||||||||
837 | |||||||||
838 | print "</fieldset>"; |
||||||||
839 | } |
||||||||
840 | |||||||||
841 | /* FTS Stemming Language */ |
||||||||
842 | |||||||||
843 | if (DB_TYPE == "pgsql") { |
||||||||
0 ignored issues
–
show
|
|||||||||
844 | print "<fieldset>"; |
||||||||
845 | |||||||||
846 | print "<label>".__('Language:')."</label> "; |
||||||||
847 | print_select("feed_language", "", $this::get_ts_languages(), |
||||||||
848 | 'disabled="1" dojoType="fox.form.Select"'); |
||||||||
849 | |||||||||
850 | $this->batch_edit_cbox("feed_language"); |
||||||||
851 | |||||||||
852 | print "</fieldset>"; |
||||||||
853 | } |
||||||||
854 | |||||||||
855 | print "</section>"; |
||||||||
856 | |||||||||
857 | print "<header>".__("Update")."</header>"; |
||||||||
858 | print "<section>"; |
||||||||
859 | |||||||||
860 | /* Update Interval */ |
||||||||
861 | |||||||||
862 | print "<fieldset>"; |
||||||||
863 | |||||||||
864 | print "<label>".__("Interval:")."</label> "; |
||||||||
865 | |||||||||
866 | print_select_hash("update_interval", "", $update_intervals, |
||||||||
867 | 'disabled="1" dojoType="fox.form.Select"'); |
||||||||
868 | |||||||||
869 | $this->batch_edit_cbox("update_interval"); |
||||||||
870 | |||||||||
871 | print "</fieldset>"; |
||||||||
872 | |||||||||
873 | /* Purge intl */ |
||||||||
874 | |||||||||
875 | if (FORCE_ARTICLE_PURGE == 0) { |
||||||||
0 ignored issues
–
show
|
|||||||||
876 | |||||||||
877 | print "<fieldset>"; |
||||||||
878 | |||||||||
879 | print "<label>".__('Article purging:')."</label> "; |
||||||||
880 | |||||||||
881 | print_select_hash("purge_interval", "", $purge_intervals, |
||||||||
882 | 'disabled="1" dojoType="fox.form.Select"'); |
||||||||
883 | |||||||||
884 | $this->batch_edit_cbox("purge_interval"); |
||||||||
885 | |||||||||
886 | print "</fieldset>"; |
||||||||
887 | } |
||||||||
888 | |||||||||
889 | print "</section>"; |
||||||||
890 | print "<header>".__("Authentication")."</header>"; |
||||||||
891 | print "<section>"; |
||||||||
892 | |||||||||
893 | print "<fieldset>"; |
||||||||
894 | |||||||||
895 | print "<input dojoType='dijit.form.TextBox' |
||||||||
896 | placeHolder=\"".__("Login")."\" disabled='1' |
||||||||
897 | autocomplete='new-password' |
||||||||
898 | name='auth_login' value=''>"; |
||||||||
899 | |||||||||
900 | $this->batch_edit_cbox("auth_login"); |
||||||||
901 | |||||||||
902 | print "<input dojoType='dijit.form.TextBox' type='password' name='auth_pass' |
||||||||
903 | autocomplete='new-password' |
||||||||
904 | placeHolder=\"".__("Password")."\" disabled='1' |
||||||||
905 | value=''>"; |
||||||||
906 | |||||||||
907 | $this->batch_edit_cbox("auth_pass"); |
||||||||
908 | |||||||||
909 | print "</fieldset>"; |
||||||||
910 | |||||||||
911 | print "</section>"; |
||||||||
912 | print "<header>".__("Options")."</header>"; |
||||||||
913 | print "<section>"; |
||||||||
914 | |||||||||
915 | print "<fieldset class='narrow'>"; |
||||||||
916 | print "<label class='checkbox'><input disabled='1' type='checkbox' id='include_in_digest' |
||||||||
917 | name='include_in_digest' dojoType='dijit.form.CheckBox'> ".__('Include in e-mail digest')."</label>"; |
||||||||
918 | |||||||||
919 | print " "; $this->batch_edit_cbox("include_in_digest", "include_in_digest_l"); |
||||||||
920 | |||||||||
921 | print "</fieldset><fieldset class='narrow'>"; |
||||||||
922 | |||||||||
923 | print "<label class='checkbox'><input disabled='1' type='checkbox' id='always_display_enclosures' |
||||||||
924 | name='always_display_enclosures' dojoType='dijit.form.CheckBox'> ".__('Always display image attachments')."</label>"; |
||||||||
925 | |||||||||
926 | print " "; $this->batch_edit_cbox("always_display_enclosures", "always_display_enclosures_l"); |
||||||||
927 | |||||||||
928 | print "</fieldset><fieldset class='narrow'>"; |
||||||||
929 | |||||||||
930 | print "<label class='checkbox'><input disabled='1' type='checkbox' id='hide_images' |
||||||||
931 | name='hide_images' dojoType='dijit.form.CheckBox'> ". __('Do not embed media')."</label>"; |
||||||||
932 | |||||||||
933 | print " "; $this->batch_edit_cbox("hide_images", "hide_images_l"); |
||||||||
934 | |||||||||
935 | print "</fieldset><fieldset class='narrow'>"; |
||||||||
936 | |||||||||
937 | print "<label class='checkbox'><input disabled='1' type='checkbox' id='cache_images' |
||||||||
938 | name='cache_images' dojoType='dijit.form.CheckBox'> ".__('Cache media')."</label>"; |
||||||||
939 | |||||||||
940 | print " "; $this->batch_edit_cbox("cache_images", "cache_images_l"); |
||||||||
941 | |||||||||
942 | print "</fieldset><fieldset class='narrow'>"; |
||||||||
943 | |||||||||
944 | print "<label class='checkbox'><input disabled='1' type='checkbox' id='mark_unread_on_update' |
||||||||
945 | name='mark_unread_on_update' dojoType='dijit.form.CheckBox'> ".__('Mark updated articles as unread')."</label>"; |
||||||||
946 | |||||||||
947 | print " "; $this->batch_edit_cbox("mark_unread_on_update", "mark_unread_on_update_l"); |
||||||||
948 | |||||||||
949 | print "</fieldset>"; |
||||||||
950 | |||||||||
951 | print "</section>"; |
||||||||
952 | |||||||||
953 | print "<footer> |
||||||||
954 | <button dojoType='dijit.form.Button' type='submit' class='alt-primary' |
||||||||
955 | onclick=\"return dijit.byId('feedEditDlg').execute()\">". |
||||||||
956 | __('Save')."</button> |
||||||||
957 | <button dojoType='dijit.form.Button' |
||||||||
958 | onclick=\"return dijit.byId('feedEditDlg').hide()\">". |
||||||||
959 | __('Cancel')."</button> |
||||||||
960 | </footer>"; |
||||||||
961 | |||||||||
962 | return; |
||||||||
963 | } |
||||||||
964 | |||||||||
965 | public function batchEditSave() { |
||||||||
966 | return $this->editsaveops(true); |
||||||||
0 ignored issues
–
show
Are you sure the usage of
$this->editsaveops(true) targeting Pref_Feeds::editsaveops() seems to always return null.
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() |
|||||||||
967 | } |
||||||||
968 | |||||||||
969 | public function editSave() { |
||||||||
970 | return $this->editsaveops(false); |
||||||||
0 ignored issues
–
show
Are you sure the usage of
$this->editsaveops(false) targeting Pref_Feeds::editsaveops() seems to always return null.
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() |
|||||||||
971 | } |
||||||||
972 | |||||||||
973 | public function editsaveops($batch) { |
||||||||
974 | |||||||||
975 | $feed_title = trim(clean($_POST["title"])); |
||||||||
0 ignored issues
–
show
It seems like
clean($_POST['title']) can also be of type array ; however, parameter $str of trim() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
976 | $feed_url = trim(clean($_POST["feed_url"])); |
||||||||
977 | $site_url = trim(clean($_POST["site_url"])); |
||||||||
978 | $upd_intl = (int) clean($_POST["update_interval"]); |
||||||||
979 | $purge_intl = (int) clean($_POST["purge_interval"]); |
||||||||
980 | $feed_id = (int) clean($_POST["id"]); /* editSave */ |
||||||||
981 | $feed_ids = explode(",", clean($_POST["ids"])); /* batchEditSave */ |
||||||||
0 ignored issues
–
show
It seems like
clean($_POST['ids']) can also be of type array ; however, parameter $string of explode() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
982 | $cat_id = (int) clean($_POST["cat_id"]); |
||||||||
983 | $auth_login = trim(clean($_POST["auth_login"])); |
||||||||
984 | $auth_pass = trim(clean($_POST["auth_pass"])); |
||||||||
985 | $private = checkbox_to_sql_bool(clean($_POST["private"])); |
||||||||
986 | $include_in_digest = checkbox_to_sql_bool( |
||||||||
987 | clean($_POST["include_in_digest"])); |
||||||||
988 | $cache_images = checkbox_to_sql_bool( |
||||||||
989 | clean($_POST["cache_images"])); |
||||||||
990 | $hide_images = checkbox_to_sql_bool( |
||||||||
991 | clean($_POST["hide_images"])); |
||||||||
992 | $always_display_enclosures = checkbox_to_sql_bool( |
||||||||
993 | clean($_POST["always_display_enclosures"])); |
||||||||
994 | |||||||||
995 | $mark_unread_on_update = checkbox_to_sql_bool( |
||||||||
996 | clean($_POST["mark_unread_on_update"])); |
||||||||
997 | |||||||||
998 | $feed_language = trim(clean($_POST["feed_language"])); |
||||||||
999 | |||||||||
1000 | if (!$batch) { |
||||||||
1001 | if (clean($_POST["need_auth"]) !== 'on') { |
||||||||
1002 | $auth_login = ''; |
||||||||
1003 | $auth_pass = ''; |
||||||||
1004 | } |
||||||||
1005 | |||||||||
1006 | /* $sth = $this->pdo->prepare("SELECT feed_url FROM ttrss_feeds WHERE id = ?"); |
||||||||
1007 | $sth->execute([$feed_id]); |
||||||||
1008 | $row = $sth->fetch();$orig_feed_url = $row["feed_url"]; |
||||||||
1009 | |||||||||
1010 | $reset_basic_info = $orig_feed_url != $feed_url; */ |
||||||||
1011 | |||||||||
1012 | $sth = $this->pdo->prepare("UPDATE ttrss_feeds SET |
||||||||
1013 | cat_id = :cat_id, |
||||||||
1014 | title = :title, |
||||||||
1015 | feed_url = :feed_url, |
||||||||
1016 | site_url = :site_url, |
||||||||
1017 | update_interval = :upd_intl, |
||||||||
1018 | purge_interval = :purge_intl, |
||||||||
1019 | auth_login = :auth_login, |
||||||||
1020 | auth_pass = :auth_pass, |
||||||||
1021 | auth_pass_encrypted = false, |
||||||||
1022 | private = :private, |
||||||||
1023 | cache_images = :cache_images, |
||||||||
1024 | hide_images = :hide_images, |
||||||||
1025 | include_in_digest = :include_in_digest, |
||||||||
1026 | always_display_enclosures = :always_display_enclosures, |
||||||||
1027 | mark_unread_on_update = :mark_unread_on_update, |
||||||||
1028 | feed_language = :feed_language |
||||||||
1029 | WHERE id = :id AND owner_uid = :uid"); |
||||||||
1030 | |||||||||
1031 | $sth->execute([":title" => $feed_title, |
||||||||
1032 | ":cat_id" => $cat_id ? $cat_id : null, |
||||||||
1033 | ":feed_url" => $feed_url, |
||||||||
1034 | ":site_url" => $site_url, |
||||||||
1035 | ":upd_intl" => $upd_intl, |
||||||||
1036 | ":purge_intl" => $purge_intl, |
||||||||
1037 | ":auth_login" => $auth_login, |
||||||||
1038 | ":auth_pass" => $auth_pass, |
||||||||
1039 | ":private" => (int) $private, |
||||||||
1040 | ":cache_images" => (int) $cache_images, |
||||||||
1041 | ":hide_images" => (int) $hide_images, |
||||||||
1042 | ":include_in_digest" => (int) $include_in_digest, |
||||||||
1043 | ":always_display_enclosures" => (int) $always_display_enclosures, |
||||||||
1044 | ":mark_unread_on_update" => (int) $mark_unread_on_update, |
||||||||
1045 | ":feed_language" => $feed_language, |
||||||||
1046 | ":id" => $feed_id, |
||||||||
1047 | ":uid" => $_SESSION['uid']]); |
||||||||
1048 | |||||||||
1049 | /* if ($reset_basic_info) { |
||||||||
1050 | RSSUtils::set_basic_feed_info($feed_id); |
||||||||
1051 | } */ |
||||||||
1052 | |||||||||
1053 | PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_SAVE_FEED, |
||||||||
1054 | "hook_prefs_save_feed", $feed_id); |
||||||||
1055 | |||||||||
1056 | } else { |
||||||||
1057 | $feed_data = array(); |
||||||||
1058 | |||||||||
1059 | foreach (array_keys($_POST) as $k) { |
||||||||
1060 | if ($k != "op" && $k != "method" && $k != "ids") { |
||||||||
1061 | $feed_data[$k] = clean($_POST[$k]); |
||||||||
1062 | } |
||||||||
1063 | } |
||||||||
1064 | |||||||||
1065 | $this->pdo->beginTransaction(); |
||||||||
1066 | |||||||||
1067 | $feed_ids_qmarks = arr_qmarks($feed_ids); |
||||||||
1068 | |||||||||
1069 | foreach (array_keys($feed_data) as $k) { |
||||||||
1070 | |||||||||
1071 | $qpart = ""; |
||||||||
1072 | |||||||||
1073 | switch ($k) { |
||||||||
1074 | case "title": |
||||||||
1075 | $qpart = "title = ".$this->pdo->quote($feed_title); |
||||||||
1076 | break; |
||||||||
1077 | |||||||||
1078 | case "feed_url": |
||||||||
1079 | $qpart = "feed_url = ".$this->pdo->quote($feed_url); |
||||||||
1080 | break; |
||||||||
1081 | |||||||||
1082 | case "update_interval": |
||||||||
1083 | $qpart = "update_interval = ".$this->pdo->quote($upd_intl); |
||||||||
1084 | break; |
||||||||
1085 | |||||||||
1086 | case "purge_interval": |
||||||||
1087 | $qpart = "purge_interval =".$this->pdo->quote($purge_intl); |
||||||||
1088 | break; |
||||||||
1089 | |||||||||
1090 | case "auth_login": |
||||||||
1091 | $qpart = "auth_login = ".$this->pdo->quote($auth_login); |
||||||||
1092 | break; |
||||||||
1093 | |||||||||
1094 | case "auth_pass": |
||||||||
1095 | $qpart = "auth_pass =".$this->pdo->quote($auth_pass).", auth_pass_encrypted = false"; |
||||||||
1096 | break; |
||||||||
1097 | |||||||||
1098 | case "private": |
||||||||
1099 | $qpart = "private = ".$this->pdo->quote($private); |
||||||||
1100 | break; |
||||||||
1101 | |||||||||
1102 | case "include_in_digest": |
||||||||
1103 | $qpart = "include_in_digest = ".$this->pdo->quote($include_in_digest); |
||||||||
1104 | break; |
||||||||
1105 | |||||||||
1106 | case "always_display_enclosures": |
||||||||
1107 | $qpart = "always_display_enclosures = ".$this->pdo->quote($always_display_enclosures); |
||||||||
1108 | break; |
||||||||
1109 | |||||||||
1110 | case "mark_unread_on_update": |
||||||||
1111 | $qpart = "mark_unread_on_update = ".$this->pdo->quote($mark_unread_on_update); |
||||||||
1112 | break; |
||||||||
1113 | |||||||||
1114 | case "cache_images": |
||||||||
1115 | $qpart = "cache_images = ".$this->pdo->quote($cache_images); |
||||||||
1116 | break; |
||||||||
1117 | |||||||||
1118 | case "hide_images": |
||||||||
1119 | $qpart = "hide_images = ".$this->pdo->quote($hide_images); |
||||||||
1120 | break; |
||||||||
1121 | |||||||||
1122 | case "cat_id": |
||||||||
1123 | if (get_pref('ENABLE_FEED_CATS')) { |
||||||||
1124 | if ($cat_id) { |
||||||||
1125 | $qpart = "cat_id = ".$this->pdo->quote($cat_id); |
||||||||
1126 | } else { |
||||||||
1127 | $qpart = 'cat_id = NULL'; |
||||||||
1128 | } |
||||||||
1129 | } else { |
||||||||
1130 | $qpart = ""; |
||||||||
1131 | } |
||||||||
1132 | |||||||||
1133 | break; |
||||||||
1134 | |||||||||
1135 | case "feed_language": |
||||||||
1136 | $qpart = "feed_language = ".$this->pdo->quote($feed_language); |
||||||||
1137 | break; |
||||||||
1138 | |||||||||
1139 | } |
||||||||
1140 | |||||||||
1141 | if ($qpart) { |
||||||||
1142 | $sth = $this->pdo->prepare("UPDATE ttrss_feeds SET $qpart WHERE id IN ($feed_ids_qmarks) |
||||||||
1143 | AND owner_uid = ?"); |
||||||||
1144 | $sth->execute(array_merge($feed_ids, [$_SESSION['uid']])); |
||||||||
1145 | } |
||||||||
1146 | } |
||||||||
1147 | |||||||||
1148 | $this->pdo->commit(); |
||||||||
1149 | } |
||||||||
1150 | return; |
||||||||
1151 | } |
||||||||
1152 | |||||||||
1153 | public function remove() { |
||||||||
1154 | |||||||||
1155 | $ids = explode(",", clean($_REQUEST["ids"])); |
||||||||
0 ignored issues
–
show
It seems like
clean($_REQUEST['ids']) can also be of type array ; however, parameter $string of explode() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
1156 | |||||||||
1157 | foreach ($ids as $id) { |
||||||||
1158 | Pref_Feeds::remove_feed($id, $_SESSION["uid"]); |
||||||||
1159 | } |
||||||||
1160 | |||||||||
1161 | return; |
||||||||
1162 | } |
||||||||
1163 | |||||||||
1164 | public function removeCat() { |
||||||||
1165 | $ids = explode(",", clean($_REQUEST["ids"])); |
||||||||
0 ignored issues
–
show
It seems like
clean($_REQUEST['ids']) can also be of type array ; however, parameter $string of explode() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
1166 | foreach ($ids as $id) { |
||||||||
1167 | $this->remove_feed_category($id, $_SESSION["uid"]); |
||||||||
1168 | } |
||||||||
1169 | } |
||||||||
1170 | |||||||||
1171 | public function addCat() { |
||||||||
1172 | $feed_cat = trim(clean($_REQUEST["cat"])); |
||||||||
0 ignored issues
–
show
It seems like
clean($_REQUEST['cat']) can also be of type array ; however, parameter $str of trim() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
1173 | |||||||||
1174 | Feeds::add_feed_category($feed_cat); |
||||||||
1175 | } |
||||||||
1176 | |||||||||
1177 | public function index() { |
||||||||
1178 | |||||||||
1179 | print "<div dojoType='dijit.layout.AccordionContainer' region='center'>"; |
||||||||
1180 | print "<div style='padding : 0px' dojoType='dijit.layout.AccordionPane' |
||||||||
1181 | title=\"<i class='material-icons'>rss_feed</i> ".__('Feeds')."\">"; |
||||||||
1182 | |||||||||
1183 | $sth = $this->pdo->prepare("SELECT COUNT(id) AS num_errors |
||||||||
1184 | FROM ttrss_feeds WHERE last_error != '' AND owner_uid = ?"); |
||||||||
1185 | $sth->execute([$_SESSION['uid']]); |
||||||||
1186 | |||||||||
1187 | if ($row = $sth->fetch()) { |
||||||||
1188 | $num_errors = $row["num_errors"]; |
||||||||
1189 | } else { |
||||||||
1190 | $num_errors = 0; |
||||||||
1191 | } |
||||||||
1192 | |||||||||
1193 | if ($num_errors > 0) { |
||||||||
1194 | |||||||||
1195 | $error_button = "<button dojoType=\"dijit.form.Button\" |
||||||||
1196 | onclick=\"CommonDialogs.showFeedsWithErrors()\" id=\"errorButton\">" . |
||||||||
1197 | __("Feeds with errors")."</button>"; |
||||||||
1198 | } |
||||||||
1199 | |||||||||
1200 | $inactive_button = "<button dojoType=\"dijit.form.Button\" |
||||||||
1201 | id=\"pref_feeds_inactive_btn\" |
||||||||
1202 | style=\"display : none\" |
||||||||
1203 | onclick=\"dijit.byId('feedTree').showInactiveFeeds()\">" . |
||||||||
1204 | __("Inactive feeds")."</button>"; |
||||||||
1205 | |||||||||
1206 | $feed_search = clean($_REQUEST["search"]); |
||||||||
1207 | |||||||||
1208 | if (array_key_exists("search", $_REQUEST)) { |
||||||||
1209 | $_SESSION["prefs_feed_search"] = $feed_search; |
||||||||
1210 | } else { |
||||||||
1211 | $feed_search = $_SESSION["prefs_feed_search"]; |
||||||||
1212 | } |
||||||||
1213 | |||||||||
1214 | print '<div dojoType="dijit.layout.BorderContainer" gutters="false">'; |
||||||||
1215 | |||||||||
1216 | print "<div region='top' dojoType=\"fox.Toolbar\">"; #toolbar |
||||||||
1217 | |||||||||
1218 | print "<div style='float : right; padding-right : 4px;'> |
||||||||
1219 | <input dojoType=\"dijit.form.TextBox\" id=\"feed_search\" size=\"20\" type=\"search\" |
||||||||
1220 | value=\"$feed_search\"> |
||||||||
1221 | <button dojoType=\"dijit.form.Button\" onclick=\"dijit.byId('feedTree').reload()\">". |
||||||||
1222 | __('Search')."</button> |
||||||||
1223 | </div>"; |
||||||||
1224 | |||||||||
1225 | print "<div dojoType=\"fox.form.DropDownButton\">". |
||||||||
1226 | "<span>".__('Select')."</span>"; |
||||||||
1227 | print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">"; |
||||||||
1228 | print "<div onclick=\"dijit.byId('feedTree').model.setAllChecked(true)\" |
||||||||
1229 | dojoType=\"dijit.MenuItem\">".__('All')."</div>"; |
||||||||
1230 | print "<div onclick=\"dijit.byId('feedTree').model.setAllChecked(false)\" |
||||||||
1231 | dojoType=\"dijit.MenuItem\">".__('None')."</div>"; |
||||||||
1232 | print "</div></div>"; |
||||||||
1233 | |||||||||
1234 | print "<div dojoType=\"fox.form.DropDownButton\">". |
||||||||
1235 | "<span>".__('Feeds')."</span>"; |
||||||||
1236 | print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">"; |
||||||||
1237 | print "<div onclick=\"CommonDialogs.quickAddFeed()\" |
||||||||
1238 | dojoType=\"dijit.MenuItem\">".__('Subscribe to feed')."</div>"; |
||||||||
1239 | print "<div onclick=\"dijit.byId('feedTree').editSelectedFeed()\" |
||||||||
1240 | dojoType=\"dijit.MenuItem\">".__('Edit selected feeds')."</div>"; |
||||||||
1241 | print "<div onclick=\"dijit.byId('feedTree').resetFeedOrder()\" |
||||||||
1242 | dojoType=\"dijit.MenuItem\">".__('Reset sort order')."</div>"; |
||||||||
1243 | print "<div onclick=\"dijit.byId('feedTree').batchSubscribe()\" |
||||||||
1244 | dojoType=\"dijit.MenuItem\">".__('Batch subscribe')."</div>"; |
||||||||
1245 | print "<div dojoType=\"dijit.MenuItem\" onclick=\"dijit.byId('feedTree').removeSelectedFeeds()\">" |
||||||||
1246 | .__('Unsubscribe')."</div> "; |
||||||||
1247 | print "</div></div>"; |
||||||||
1248 | |||||||||
1249 | if (get_pref('ENABLE_FEED_CATS')) { |
||||||||
1250 | print "<div dojoType=\"fox.form.DropDownButton\">". |
||||||||
1251 | "<span>".__('Categories')."</span>"; |
||||||||
1252 | print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">"; |
||||||||
1253 | print "<div onclick=\"dijit.byId('feedTree').createCategory()\" |
||||||||
1254 | dojoType=\"dijit.MenuItem\">".__('Add category')."</div>"; |
||||||||
1255 | print "<div onclick=\"dijit.byId('feedTree').resetCatOrder()\" |
||||||||
1256 | dojoType=\"dijit.MenuItem\">".__('Reset sort order')."</div>"; |
||||||||
1257 | print "<div onclick=\"dijit.byId('feedTree').removeSelectedCategories()\" |
||||||||
1258 | dojoType=\"dijit.MenuItem\">".__('Remove selected')."</div>"; |
||||||||
1259 | print "</div></div>"; |
||||||||
1260 | |||||||||
1261 | } |
||||||||
1262 | |||||||||
1263 | print $error_button; |
||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||||||
1264 | print $inactive_button; |
||||||||
1265 | |||||||||
1266 | print "</div>"; # toolbar |
||||||||
1267 | |||||||||
1268 | //print '</div>'; |
||||||||
1269 | print '<div style="padding : 0px" dojoType="dijit.layout.ContentPane" region="center">'; |
||||||||
1270 | |||||||||
1271 | print "<div id=\"feedlistLoading\"> |
||||||||
1272 | <img src='images/indicator_tiny.gif'>". |
||||||||
1273 | __("Loading, please wait...")."</div>"; |
||||||||
1274 | |||||||||
1275 | $auto_expand = $feed_search != "" ? "true" : "false"; |
||||||||
1276 | |||||||||
1277 | print "<div dojoType=\"fox.PrefFeedStore\" jsId=\"feedStore\" |
||||||||
1278 | url=\"backend.php?op=pref-feeds&method=getfeedtree\"> |
||||||||
1279 | </div> |
||||||||
1280 | <div dojoType=\"lib.CheckBoxStoreModel\" jsId=\"feedModel\" store=\"feedStore\" |
||||||||
1281 | query=\"{id:'root'}\" rootId=\"root\" rootLabel=\"Feeds\" |
||||||||
1282 | childrenAttrs=\"items\" checkboxStrict=\"false\" checkboxAll=\"false\"> |
||||||||
1283 | </div> |
||||||||
1284 | <div dojoType=\"fox.PrefFeedTree\" id=\"feedTree\" |
||||||||
1285 | dndController=\"dijit.tree.dndSource\" |
||||||||
1286 | betweenThreshold=\"5\" |
||||||||
1287 | autoExpand='$auto_expand' |
||||||||
1288 | model=\"feedModel\" openOnClick=\"false\"> |
||||||||
1289 | <script type=\"dojo/method\" event=\"onClick\" args=\"item\"> |
||||||||
1290 | var id = String(item.id); |
||||||||
1291 | var bare_id = id.substr(id.indexOf(':')+1); |
||||||||
1292 | |||||||||
1293 | if (id.match('FEED:')) { |
||||||||
1294 | CommonDialogs.editFeed(bare_id); |
||||||||
1295 | } else if (id.match('CAT:')) { |
||||||||
1296 | dijit.byId('feedTree').editCategory(bare_id, item); |
||||||||
1297 | } |
||||||||
1298 | </script> |
||||||||
1299 | <script type=\"dojo/method\" event=\"onLoad\" args=\"item\"> |
||||||||
1300 | Element.hide(\"feedlistLoading\"); |
||||||||
1301 | |||||||||
1302 | dijit.byId('feedTree').checkInactiveFeeds(); |
||||||||
1303 | </script> |
||||||||
1304 | </div>"; |
||||||||
1305 | |||||||||
1306 | # print "<div dojoType=\"dijit.Tooltip\" connectId=\"feedTree\" position=\"below\"> |
||||||||
1307 | # ".__('<b>Hint:</b> you can drag feeds and categories around.')." |
||||||||
1308 | # </div>"; |
||||||||
1309 | |||||||||
1310 | print '</div>'; |
||||||||
1311 | print '</div>'; |
||||||||
1312 | |||||||||
1313 | print "</div>"; # feeds pane |
||||||||
1314 | |||||||||
1315 | print "<div dojoType='dijit.layout.AccordionPane' |
||||||||
1316 | title='<i class=\"material-icons\">import_export</i> ".__('OPML')."'>"; |
||||||||
1317 | |||||||||
1318 | print "<h3>".__("Using OPML you can export and import your feeds, filters, labels and Tiny Tiny RSS settings.")."</h3>"; |
||||||||
1319 | |||||||||
1320 | print_notice("Only main settings profile can be migrated using OPML."); |
||||||||
0 ignored issues
–
show
The call to
print_notice() has too many arguments starting with 'Only main settings prof...e migrated using OPML.' .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above. ![]() The function
print_notice() has been deprecated: Use twig function noticeMessage
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This function has been deprecated. The supplier of the function has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead. ![]() |
|||||||||
1321 | |||||||||
1322 | print "<iframe id=\"upload_iframe\" |
||||||||
1323 | name=\"upload_iframe\" onload=\"Helpers.OPML.onImportComplete(this)\" |
||||||||
1324 | style=\"width: 400px; height: 100px; display: none;\"></iframe>"; |
||||||||
1325 | |||||||||
1326 | print "<form name='opml_form' style='display : inline-block' target='upload_iframe' |
||||||||
1327 | enctype='multipart/form-data' method='POST' |
||||||||
1328 | action='backend.php'> |
||||||||
1329 | <label class='dijitButton'>".__("Choose file...")." |
||||||||
1330 | <input style='display : none' id='opml_file' name='opml_file' type='file'> |
||||||||
1331 | </label> |
||||||||
1332 | <input type='hidden' name='op' value='dlg'> |
||||||||
1333 | <input type='hidden' name='method' value='importOpml'> |
||||||||
1334 | <button dojoType='dijit.form.Button' class='alt-primary' onclick=\"return Helpers.OPML.import();\" type=\"submit\">" . |
||||||||
1335 | __('Import OPML')."</button>"; |
||||||||
1336 | |||||||||
1337 | print "</form>"; |
||||||||
1338 | |||||||||
1339 | print "<form dojoType='dijit.form.Form' id='opmlExportForm' style='display : inline-block'>"; |
||||||||
1340 | |||||||||
1341 | print "<button dojoType='dijit.form.Button' |
||||||||
1342 | onclick='Helpers.OPML.export()' >" . |
||||||||
1343 | __('Export OPML')."</button>"; |
||||||||
1344 | |||||||||
1345 | print " <label class='checkbox'>"; |
||||||||
1346 | print_checkbox("include_settings", true, "1", ""); |
||||||||
1347 | print " ".__("Include settings"); |
||||||||
1348 | print "</label>"; |
||||||||
1349 | |||||||||
1350 | print "</form>"; |
||||||||
1351 | |||||||||
1352 | print "<p/>"; |
||||||||
1353 | |||||||||
1354 | print "<h2>".__("Published OPML")."</h2>"; |
||||||||
1355 | |||||||||
1356 | print "<p>".__('Your OPML can be published publicly and can be subscribed by anyone who knows the URL below.'). |
||||||||
1357 | " ". |
||||||||
1358 | __("Published OPML does not include your Tiny Tiny RSS settings, feeds that require authentication or feeds hidden from Popular feeds.")."</p>"; |
||||||||
1359 | |||||||||
1360 | print "<button dojoType='dijit.form.Button' class='alt-primary' onclick=\"return App.displayDlg('".__("Public OPML URL")."','pubOPMLUrl')\">". |
||||||||
1361 | __('Display published OPML URL')."</button> "; |
||||||||
1362 | |||||||||
1363 | PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION, |
||||||||
1364 | "hook_prefs_tab_section", "prefFeedsOPML"); |
||||||||
1365 | |||||||||
1366 | print "</div>"; # pane |
||||||||
1367 | |||||||||
1368 | print "<div dojoType=\"dijit.layout.AccordionPane\" |
||||||||
1369 | title=\"<i class='material-icons'>share</i> ".__('Published & shared articles / Generated feeds')."\">"; |
||||||||
1370 | |||||||||
1371 | print "<h3>".__('Published articles can be subscribed by anyone who knows the following URL:')."</h3>"; |
||||||||
1372 | |||||||||
1373 | $rss_url = '-2::'.htmlspecialchars(get_self_url_prefix(). |
||||||||
1374 | "/public.php?op=rss&id=-2&view-mode=all_articles"); ; |
||||||||
1375 | |||||||||
1376 | print "<button dojoType='dijit.form.Button' class='alt-primary' onclick=\"return App.displayDlg('".__("Show as feed")."','generatedFeed', '$rss_url')\">". |
||||||||
1377 | __('Display URL')."</button> "; |
||||||||
1378 | |||||||||
1379 | print "<button class=\"alt-danger\" dojoType=\"dijit.form.Button\" onclick=\"return Helpers.clearFeedAccessKeys()\">". |
||||||||
1380 | __('Clear all generated URLs')."</button> "; |
||||||||
1381 | |||||||||
1382 | PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION, |
||||||||
1383 | "hook_prefs_tab_section", "prefFeedsPublishedGenerated"); |
||||||||
1384 | |||||||||
1385 | print "</div>"; #pane |
||||||||
1386 | |||||||||
1387 | PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB, |
||||||||
1388 | "hook_prefs_tab", "prefFeeds"); |
||||||||
1389 | |||||||||
1390 | print "</div>"; #container |
||||||||
1391 | } |
||||||||
1392 | |||||||||
1393 | private function feedlist_init_cat($cat_id) { |
||||||||
1394 | $obj = array(); |
||||||||
1395 | $cat_id = (int) $cat_id; |
||||||||
1396 | |||||||||
1397 | if ($cat_id > 0) { |
||||||||
1398 | $cat_unread = CCache::find($cat_id, $_SESSION["uid"], true); |
||||||||
1399 | } else if ($cat_id == 0 || $cat_id == -2) { |
||||||||
1400 | $cat_unread = Feeds::getCategoryUnread($cat_id); |
||||||||
1401 | } |
||||||||
1402 | |||||||||
1403 | $obj['id'] = 'CAT:'.$cat_id; |
||||||||
1404 | $obj['items'] = array(); |
||||||||
1405 | $obj['name'] = Feeds::getCategoryTitle($cat_id); |
||||||||
1406 | $obj['type'] = 'category'; |
||||||||
1407 | $obj['unread'] = (int) $cat_unread; |
||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||||||
1408 | $obj['bare_id'] = $cat_id; |
||||||||
1409 | |||||||||
1410 | return $obj; |
||||||||
1411 | } |
||||||||
1412 | |||||||||
1413 | private function feedlist_init_feed($feed_id, $title = false, $unread = false, $error = '', $updated = '') { |
||||||||
1414 | $obj = array(); |
||||||||
1415 | $feed_id = (int) $feed_id; |
||||||||
1416 | |||||||||
1417 | if (!$title) { |
||||||||
1418 | $title = Feeds::getFeedTitle($feed_id, false); |
||||||||
1419 | } |
||||||||
1420 | |||||||||
1421 | if ($unread === false) { |
||||||||
1422 | $unread = getFeedUnread($feed_id, false); |
||||||||
1423 | } |
||||||||
1424 | |||||||||
1425 | $obj['id'] = 'FEED:'.$feed_id; |
||||||||
1426 | $obj['name'] = $title; |
||||||||
1427 | $obj['unread'] = (int) $unread; |
||||||||
1428 | $obj['type'] = 'feed'; |
||||||||
1429 | $obj['error'] = $error; |
||||||||
1430 | $obj['updated'] = $updated; |
||||||||
1431 | $obj['icon'] = Feeds::getFeedIcon($feed_id); |
||||||||
1432 | $obj['bare_id'] = $feed_id; |
||||||||
1433 | $obj['auxcounter'] = 0; |
||||||||
1434 | |||||||||
1435 | return $obj; |
||||||||
1436 | } |
||||||||
1437 | |||||||||
1438 | public function inactiveFeeds() { |
||||||||
1439 | |||||||||
1440 | if (DB_TYPE == "pgsql") { |
||||||||
0 ignored issues
–
show
|
|||||||||
1441 | $interval_qpart = "NOW() - INTERVAL '3 months'"; |
||||||||
1442 | } else { |
||||||||
1443 | $interval_qpart = "DATE_SUB(NOW(), INTERVAL 3 MONTH)"; |
||||||||
1444 | } |
||||||||
1445 | |||||||||
1446 | $sth = $this->pdo->prepare("SELECT ttrss_feeds.title, ttrss_feeds.site_url, |
||||||||
1447 | ttrss_feeds.feed_url, ttrss_feeds.id, MAX(updated) AS last_article |
||||||||
1448 | FROM ttrss_feeds, ttrss_entries, ttrss_user_entries WHERE |
||||||||
1449 | (SELECT MAX(updated) FROM ttrss_entries, ttrss_user_entries WHERE |
||||||||
1450 | ttrss_entries.id = ref_id AND |
||||||||
1451 | ttrss_user_entries.feed_id = ttrss_feeds.id) < $interval_qpart |
||||||||
1452 | AND ttrss_feeds.owner_uid = ? AND |
||||||||
1453 | ttrss_user_entries.feed_id = ttrss_feeds.id AND |
||||||||
1454 | ttrss_entries.id = ref_id |
||||||||
1455 | GROUP BY ttrss_feeds.title, ttrss_feeds.id, ttrss_feeds.site_url, ttrss_feeds.feed_url |
||||||||
1456 | ORDER BY last_article"); |
||||||||
1457 | $sth->execute([$_SESSION['uid']]); |
||||||||
1458 | |||||||||
1459 | print "<div dojoType='fox.Toolbar'>"; |
||||||||
1460 | print "<div dojoType='fox.form.DropDownButton'>". |
||||||||
1461 | "<span>".__('Select')."</span>"; |
||||||||
1462 | print "<div dojoType='dijit.Menu' style='display: none'>"; |
||||||||
1463 | print "<div onclick=\"Tables.select('inactive-feeds-list', true)\" |
||||||||
1464 | dojoType='dijit.MenuItem'>".__('All')."</div>"; |
||||||||
1465 | print "<div onclick=\"Tables.select('inactive-feeds-list', false)\" |
||||||||
1466 | dojoType='dijit.MenuItem'>".__('None')."</div>"; |
||||||||
1467 | print "</div></div>"; |
||||||||
1468 | print "</div>"; #toolbar |
||||||||
1469 | |||||||||
1470 | print "<div class='panel panel-scrollable'>"; |
||||||||
1471 | print "<table width='100%' id='inactive-feeds-list'>"; |
||||||||
1472 | |||||||||
1473 | $lnum = 1; |
||||||||
1474 | |||||||||
1475 | while ($line = $sth->fetch()) { |
||||||||
1476 | |||||||||
1477 | $feed_id = $line["id"]; |
||||||||
1478 | |||||||||
1479 | print "<tr data-row-id='$feed_id'>"; |
||||||||
1480 | |||||||||
1481 | print "<td width='5%' align='center'><input |
||||||||
1482 | onclick='Tables.onRowChecked(this);' dojoType='dijit.form.CheckBox' |
||||||||
1483 | type='checkbox'></td>"; |
||||||||
1484 | print "<td>"; |
||||||||
1485 | |||||||||
1486 | print "<a href='#' ". |
||||||||
1487 | "title=\"".__("Click to edit feed")."\" ". |
||||||||
1488 | "onclick=\"CommonDialogs.editFeed(".$line["id"].")\">". |
||||||||
1489 | htmlspecialchars($line["title"])."</a>"; |
||||||||
1490 | |||||||||
1491 | print "</td><td class='text-muted' align='right'>"; |
||||||||
1492 | print make_local_datetime($line['last_article'], false); |
||||||||
1493 | print "</td>"; |
||||||||
1494 | print "</tr>"; |
||||||||
1495 | |||||||||
1496 | ++$lnum; |
||||||||
1497 | } |
||||||||
1498 | |||||||||
1499 | print "</table>"; |
||||||||
1500 | print "</div>"; |
||||||||
1501 | |||||||||
1502 | print "<footer> |
||||||||
1503 | <button style='float : left' class=\"alt-danger\" dojoType='dijit.form.Button' onclick=\"dijit.byId('inactiveFeedsDlg').removeSelected()\">" |
||||||||
1504 | .__('Unsubscribe from selected feeds')."</button> |
||||||||
1505 | <button dojoType='dijit.form.Button' onclick=\"dijit.byId('inactiveFeedsDlg').hide()\">" |
||||||||
1506 | .__('Close this window')."</button> |
||||||||
1507 | </footer>"; |
||||||||
1508 | |||||||||
1509 | } |
||||||||
1510 | |||||||||
1511 | public function feedsWithErrors() { |
||||||||
1512 | $sth = $this->pdo->prepare("SELECT id,title,feed_url,last_error,site_url |
||||||||
1513 | FROM ttrss_feeds WHERE last_error != '' AND owner_uid = ?"); |
||||||||
1514 | $sth->execute([$_SESSION['uid']]); |
||||||||
1515 | |||||||||
1516 | print "<div dojoType=\"fox.Toolbar\">"; |
||||||||
1517 | print "<div dojoType=\"fox.form.DropDownButton\">". |
||||||||
1518 | "<span>".__('Select')."</span>"; |
||||||||
1519 | print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">"; |
||||||||
1520 | print "<div onclick=\"Tables.select('error-feeds-list', true)\" |
||||||||
1521 | dojoType=\"dijit.MenuItem\">".__('All')."</div>"; |
||||||||
1522 | print "<div onclick=\"Tables.select('error-feeds-list', false)\" |
||||||||
1523 | dojoType=\"dijit.MenuItem\">".__('None')."</div>"; |
||||||||
1524 | print "</div></div>"; |
||||||||
1525 | print "</div>"; #toolbar |
||||||||
1526 | |||||||||
1527 | print "<div class='panel panel-scrollable'>"; |
||||||||
1528 | print "<table width='100%' id='error-feeds-list'>"; |
||||||||
1529 | |||||||||
1530 | $lnum = 1; |
||||||||
1531 | |||||||||
1532 | while ($line = $sth->fetch()) { |
||||||||
1533 | |||||||||
1534 | $feed_id = $line["id"]; |
||||||||
1535 | |||||||||
1536 | print "<tr data-row-id='$feed_id'>"; |
||||||||
1537 | |||||||||
1538 | print "<td width='5%' align='center'><input |
||||||||
1539 | onclick='Tables.onRowChecked(this);' dojoType=\"dijit.form.CheckBox\" |
||||||||
1540 | type=\"checkbox\"></td>"; |
||||||||
1541 | print "<td>"; |
||||||||
1542 | |||||||||
1543 | print "<a class=\"visibleLink\" href=\"#\" ". |
||||||||
1544 | "title=\"".__("Click to edit feed")."\" ". |
||||||||
1545 | "onclick=\"CommonDialogs.editFeed(".$line["id"].")\">". |
||||||||
1546 | htmlspecialchars($line["title"])."</a>: "; |
||||||||
1547 | |||||||||
1548 | print "<span class=\"text-muted\">"; |
||||||||
1549 | print htmlspecialchars($line["last_error"]); |
||||||||
1550 | print "</span>"; |
||||||||
1551 | |||||||||
1552 | print "</td>"; |
||||||||
1553 | print "</tr>"; |
||||||||
1554 | |||||||||
1555 | ++$lnum; |
||||||||
1556 | } |
||||||||
1557 | |||||||||
1558 | print "</table>"; |
||||||||
1559 | print "</div>"; |
||||||||
1560 | |||||||||
1561 | print "<footer>"; |
||||||||
1562 | print "<button style='float : left' class=\"alt-danger\" dojoType=\"dijit.form.Button\" onclick=\"dijit.byId('errorFeedsDlg').removeSelected()\">" |
||||||||
1563 | .__('Unsubscribe from selected feeds')."</button> "; |
||||||||
1564 | |||||||||
1565 | print "<button dojoType=\"dijit.form.Button\" onclick=\"dijit.byId('errorFeedsDlg').hide()\">". |
||||||||
1566 | __('Close this window')."</button>"; |
||||||||
1567 | |||||||||
1568 | print "</footer>"; |
||||||||
1569 | } |
||||||||
1570 | |||||||||
1571 | private function remove_feed_category($id, $owner_uid) { |
||||||||
1572 | |||||||||
1573 | $sth = $this->pdo->prepare("DELETE FROM ttrss_feed_categories |
||||||||
1574 | WHERE id = ? AND owner_uid = ?"); |
||||||||
1575 | $sth->execute([$id, $owner_uid]); |
||||||||
1576 | |||||||||
1577 | CCache::remove($id, $owner_uid, true); |
||||||||
1578 | } |
||||||||
1579 | |||||||||
1580 | public static function remove_feed($id, $owner_uid) { |
||||||||
1581 | foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_UNSUBSCRIBE_FEED) as $p) { |
||||||||
1582 | if (!$p->hook_unsubscribe_feed($id, $owner_uid)) { |
||||||||
1583 | user_error("feed $id (owner: $owner_uid) not removed due to plugin error (HOOK_UNSUBSCRIBE_FEED).", E_USER_WARNING); |
||||||||
1584 | return; |
||||||||
1585 | } |
||||||||
1586 | } |
||||||||
1587 | |||||||||
1588 | $pdo = Db::pdo(); |
||||||||
1589 | |||||||||
1590 | if ($id > 0) { |
||||||||
1591 | $pdo->beginTransaction(); |
||||||||
1592 | |||||||||
1593 | /* save starred articles in Archived feed */ |
||||||||
1594 | |||||||||
1595 | /* prepare feed if necessary */ |
||||||||
1596 | |||||||||
1597 | $sth = $pdo->prepare("SELECT feed_url FROM ttrss_feeds WHERE id = ? |
||||||||
1598 | AND owner_uid = ?"); |
||||||||
1599 | $sth->execute([$id, $owner_uid]); |
||||||||
1600 | |||||||||
1601 | if ($row = $sth->fetch()) { |
||||||||
1602 | $feed_url = $row["feed_url"]; |
||||||||
1603 | |||||||||
1604 | $sth = $pdo->prepare("SELECT id FROM ttrss_archived_feeds |
||||||||
1605 | WHERE feed_url = ? AND owner_uid = ?"); |
||||||||
1606 | $sth->execute([$feed_url, $owner_uid]); |
||||||||
1607 | |||||||||
1608 | if ($row = $sth->fetch()) { |
||||||||
1609 | $archive_id = $row["id"]; |
||||||||
1610 | } else { |
||||||||
1611 | $res = $pdo->query("SELECT MAX(id) AS id FROM ttrss_archived_feeds"); |
||||||||
1612 | $row = $res->fetch(); |
||||||||
1613 | |||||||||
1614 | $new_feed_id = (int) $row['id'] + 1; |
||||||||
1615 | |||||||||
1616 | $sth = $pdo->prepare("INSERT INTO ttrss_archived_feeds |
||||||||
1617 | (id, owner_uid, title, feed_url, site_url, created) |
||||||||
1618 | SELECT ?, owner_uid, title, feed_url, site_url, NOW() from ttrss_feeds |
||||||||
1619 | WHERE id = ?"); |
||||||||
1620 | $sth->execute([$new_feed_id, $id]); |
||||||||
1621 | |||||||||
1622 | $archive_id = $new_feed_id; |
||||||||
1623 | } |
||||||||
1624 | |||||||||
1625 | $sth = $pdo->prepare("UPDATE ttrss_user_entries SET feed_id = NULL, |
||||||||
1626 | orig_feed_id = ? WHERE feed_id = ? AND |
||||||||
1627 | marked = true AND owner_uid = ?"); |
||||||||
1628 | |||||||||
1629 | $sth->execute([$archive_id, $id, $owner_uid]); |
||||||||
1630 | |||||||||
1631 | /* Remove access key for the feed */ |
||||||||
1632 | |||||||||
1633 | $sth = $pdo->prepare("DELETE FROM ttrss_access_keys WHERE |
||||||||
1634 | feed_id = ? AND owner_uid = ?"); |
||||||||
1635 | $sth->execute([$id, $owner_uid]); |
||||||||
1636 | |||||||||
1637 | /* remove the feed */ |
||||||||
1638 | |||||||||
1639 | $sth = $pdo->prepare("DELETE FROM ttrss_feeds |
||||||||
1640 | WHERE id = ? AND owner_uid = ?"); |
||||||||
1641 | $sth->execute([$id, $owner_uid]); |
||||||||
1642 | } |
||||||||
1643 | |||||||||
1644 | $pdo->commit(); |
||||||||
1645 | |||||||||
1646 | if (file_exists(ICONS_DIR."/$id.ico")) { |
||||||||
0 ignored issues
–
show
|
|||||||||
1647 | unlink(ICONS_DIR."/$id.ico"); |
||||||||
1648 | } |
||||||||
1649 | |||||||||
1650 | CCache::remove($id, $owner_uid); |
||||||||
1651 | |||||||||
1652 | } else { |
||||||||
1653 | Labels::remove(Labels::feed_to_label_id($id), $owner_uid); |
||||||||
1654 | //CCache::remove($id, $owner_uid); don't think labels are cached |
||||||||
1655 | } |
||||||||
1656 | } |
||||||||
1657 | |||||||||
1658 | public function batchSubscribe() { |
||||||||
1659 | print_hidden("op", "pref-feeds"); |
||||||||
1660 | print_hidden("method", "batchaddfeeds"); |
||||||||
1661 | |||||||||
1662 | print "<header class='horizontal'>".__("One valid feed per line (no detection is done)")."</header>"; |
||||||||
1663 | print "<section>"; |
||||||||
1664 | |||||||||
1665 | print "<textarea |
||||||||
1666 | style='font-size : 12px; width : 98%; height: 200px;' |
||||||||
1667 | dojoType='dijit.form.SimpleTextarea' name='feeds'></textarea>"; |
||||||||
1668 | |||||||||
1669 | if (get_pref('ENABLE_FEED_CATS')) { |
||||||||
1670 | print "<fieldset>"; |
||||||||
1671 | print "<label>".__('Place in category:')."</label> "; |
||||||||
1672 | print_feed_cat_select("cat", false, 'dojoType="fox.form.Select"'); |
||||||||
1673 | print "</fieldset>"; |
||||||||
1674 | } |
||||||||
1675 | |||||||||
1676 | print "</section>"; |
||||||||
1677 | |||||||||
1678 | print "<div id='feedDlg_loginContainer' style='display : none'>"; |
||||||||
1679 | |||||||||
1680 | print "<header>".__("Authentication")."</header>"; |
||||||||
1681 | print "<section>"; |
||||||||
1682 | |||||||||
1683 | print "<input dojoType='dijit.form.TextBox' name='login' placeHolder=\"".__("Login")."\"> |
||||||||
1684 | <input placeHolder=\"".__("Password")."\" dojoType=\"dijit.form.TextBox\" type='password' |
||||||||
1685 | autocomplete='new-password' name='pass''></div>"; |
||||||||
1686 | |||||||||
1687 | print "</section>"; |
||||||||
1688 | print "</div>"; |
||||||||
1689 | |||||||||
1690 | print "<fieldset class='narrow'> |
||||||||
1691 | <label class='checkbox'><input type='checkbox' name='need_auth' dojoType='dijit.form.CheckBox' |
||||||||
1692 | onclick='displayIfChecked(this, \"feedDlg_loginContainer\")'> ". |
||||||||
1693 | __('Feeds require authentication.')."</label></div>"; |
||||||||
1694 | print "</fieldset>"; |
||||||||
1695 | |||||||||
1696 | print "<footer> |
||||||||
1697 | <button dojoType='dijit.form.Button' type='submit' class='alt-primary'>".__('Subscribe')."</button> |
||||||||
1698 | <button dojoType='dijit.form.Button' onclick=\"return dijit.byId('batchSubDlg').hide()\">".__('Cancel')."</button> |
||||||||
1699 | </footer>"; |
||||||||
1700 | } |
||||||||
1701 | |||||||||
1702 | public function batchAddFeeds() { |
||||||||
1703 | $cat_id = clean($_REQUEST['cat']); |
||||||||
1704 | $feeds = explode("\n", clean($_REQUEST['feeds'])); |
||||||||
0 ignored issues
–
show
It seems like
clean($_REQUEST['feeds']) can also be of type array ; however, parameter $string of explode() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
1705 | $login = clean($_REQUEST['login']); |
||||||||
1706 | $pass = trim(clean($_REQUEST['pass'])); |
||||||||
0 ignored issues
–
show
It seems like
clean($_REQUEST['pass']) can also be of type array ; however, parameter $str of trim() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
1707 | |||||||||
1708 | $csth = $this->pdo->prepare("SELECT id FROM ttrss_feeds |
||||||||
1709 | WHERE feed_url = ? AND owner_uid = ?"); |
||||||||
1710 | |||||||||
1711 | $isth = $this->pdo->prepare("INSERT INTO ttrss_feeds |
||||||||
1712 | (owner_uid,feed_url,title,cat_id,auth_login,auth_pass,update_method,auth_pass_encrypted) |
||||||||
1713 | VALUES (?, ?, '[Unknown]', ?, ?, ?, 0, false)"); |
||||||||
1714 | |||||||||
1715 | foreach ($feeds as $feed) { |
||||||||
1716 | $feed = trim($feed); |
||||||||
1717 | |||||||||
1718 | if (Feeds::validate_feed_url($feed)) { |
||||||||
1719 | |||||||||
1720 | $this->pdo->beginTransaction(); |
||||||||
1721 | |||||||||
1722 | $csth->execute([$feed, $_SESSION['uid']]); |
||||||||
1723 | |||||||||
1724 | if (!$csth->fetch()) { |
||||||||
1725 | $isth->execute([$_SESSION['uid'], $feed, $cat_id ? $cat_id : null, $login, $pass]); |
||||||||
1726 | } |
||||||||
1727 | |||||||||
1728 | $this->pdo->commit(); |
||||||||
1729 | } |
||||||||
1730 | } |
||||||||
1731 | } |
||||||||
1732 | |||||||||
1733 | public function regenOPMLKey() { |
||||||||
1734 | $this->update_feed_access_key('OPML:Publish', |
||||||||
1735 | false, $_SESSION["uid"]); |
||||||||
1736 | |||||||||
1737 | $new_link = Opml::opml_publish_url(); |
||||||||
1738 | |||||||||
1739 | print json_encode(array("link" => $new_link)); |
||||||||
1740 | } |
||||||||
1741 | |||||||||
1742 | public function regenFeedKey() { |
||||||||
1743 | $feed_id = clean($_REQUEST['id']); |
||||||||
1744 | $is_cat = clean($_REQUEST['is_cat']); |
||||||||
1745 | |||||||||
1746 | $new_key = $this->update_feed_access_key($feed_id, $is_cat); |
||||||||
1747 | |||||||||
1748 | print json_encode(["link" => $new_key]); |
||||||||
1749 | } |
||||||||
1750 | |||||||||
1751 | |||||||||
1752 | private function update_feed_access_key($feed_id, $is_cat, $owner_uid = false) { |
||||||||
1753 | if (!$owner_uid) { |
||||||||
1754 | $owner_uid = $_SESSION["uid"]; |
||||||||
1755 | } |
||||||||
1756 | |||||||||
1757 | // clear old value and generate new one |
||||||||
1758 | $sth = $this->pdo->prepare("DELETE FROM ttrss_access_keys |
||||||||
1759 | WHERE feed_id = ? AND is_cat = ? AND owner_uid = ?"); |
||||||||
1760 | $sth->execute([$feed_id, bool_to_sql_bool($is_cat), $owner_uid]); |
||||||||
1761 | |||||||||
1762 | return Feeds::get_feed_access_key($feed_id, $is_cat, $owner_uid); |
||||||||
1763 | } |
||||||||
1764 | |||||||||
1765 | // Silent |
||||||||
1766 | public function clearKeys() { |
||||||||
1767 | $sth = $this->pdo->prepare("DELETE FROM ttrss_access_keys WHERE |
||||||||
1768 | owner_uid = ?"); |
||||||||
1769 | $sth->execute([$_SESSION['uid']]); |
||||||||
1770 | } |
||||||||
1771 | |||||||||
1772 | private function calculate_children_count($cat) { |
||||||||
1773 | $c = 0; |
||||||||
1774 | |||||||||
1775 | foreach ($cat['items'] as $child) { |
||||||||
1776 | if ($child['type'] == 'category') { |
||||||||
1777 | $c += $this->calculate_children_count($child); |
||||||||
1778 | } else { |
||||||||
1779 | $c += 1; |
||||||||
1780 | } |
||||||||
1781 | } |
||||||||
1782 | |||||||||
1783 | return $c; |
||||||||
1784 | } |
||||||||
1785 | |||||||||
1786 | public function getinactivefeeds() { |
||||||||
1787 | if (DB_TYPE == "pgsql") { |
||||||||
0 ignored issues
–
show
|
|||||||||
1788 | $interval_qpart = "NOW() - INTERVAL '3 months'"; |
||||||||
1789 | } else { |
||||||||
1790 | $interval_qpart = "DATE_SUB(NOW(), INTERVAL 3 MONTH)"; |
||||||||
1791 | } |
||||||||
1792 | |||||||||
1793 | $sth = $this->pdo->prepare("SELECT COUNT(id) AS num_inactive FROM ttrss_feeds WHERE |
||||||||
1794 | (SELECT MAX(updated) FROM ttrss_entries, ttrss_user_entries WHERE |
||||||||
1795 | ttrss_entries.id = ref_id AND |
||||||||
1796 | ttrss_user_entries.feed_id = ttrss_feeds.id) < $interval_qpart AND |
||||||||
1797 | ttrss_feeds.owner_uid = ?"); |
||||||||
1798 | $sth->execute([$_SESSION['uid']]); |
||||||||
1799 | |||||||||
1800 | if ($row = $sth->fetch()) { |
||||||||
1801 | print (int) $row["num_inactive"]; |
||||||||
1802 | } |
||||||||
1803 | } |
||||||||
1804 | |||||||||
1805 | public static function subscribe_to_feed_url() { |
||||||||
1806 | $url_path = get_self_url_prefix(). |
||||||||
1807 | "/public.php?op=subscribe&feed_url=%s"; |
||||||||
1808 | return $url_path; |
||||||||
1809 | } |
||||||||
1810 | |||||||||
1811 | } |
||||||||
1812 |