Passed
Pull Request — master (#5)
by Cody
03:17
created
classes/feedenclosure.php 1 patch
Indentation   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -1,10 +1,10 @@
 block discarded – undo
1 1
 <?php
2 2
 class FeedEnclosure {
3
-	public $link;
4
-	public $type;
5
-	public $length;
6
-	public $title;
7
-	public $height;
8
-	public $width;
3
+    public $link;
4
+    public $type;
5
+    public $length;
6
+    public $title;
7
+    public $height;
8
+    public $width;
9 9
 }
10 10
 
Please login to merge, or discard this patch.
classes/feedparser.php 1 patch
Indentation   +224 added lines, -224 removed lines patch added patch discarded remove patch
@@ -1,233 +1,233 @@
 block discarded – undo
1 1
 <?php
2 2
 class FeedParser {
3
-	private $doc;
4
-	private $error;
5
-	private $libxml_errors = array();
6
-	private $items;
7
-	private $link;
8
-	private $title;
9
-	private $type;
10
-	private $xpath;
11
-
12
-	const FEED_RDF = 0;
13
-	const FEED_RSS = 1;
14
-	const FEED_ATOM = 2;
15
-
16
-	public function __construct($data) {
17
-		libxml_use_internal_errors(true);
18
-		libxml_clear_errors();
19
-		$this->doc = new DOMDocument();
20
-		$this->doc->loadXML($data);
21
-
22
-		mb_substitute_character("none");
23
-
24
-		$error = libxml_get_last_error();
25
-
26
-		if ($error) {
27
-			foreach (libxml_get_errors() as $error) {
28
-				if ($error->level == LIBXML_ERR_FATAL) {
29
-					if(!isset($this->error)) //currently only the first error is reported
30
-						$this->error = $this->format_error($error);
31
-					$this->libxml_errors [] = $this->format_error($error);
32
-				}
33
-			}
34
-		}
35
-		libxml_clear_errors();
36
-
37
-		$this->items = array();
38
-	}
39
-
40
-	public function init() {
41
-		$xpath = new DOMXPath($this->doc);
42
-		$xpath->registerNamespace('atom', 'http://www.w3.org/2005/Atom');
43
-		$xpath->registerNamespace('atom03', 'http://purl.org/atom/ns#');
44
-		$xpath->registerNamespace('media', 'http://search.yahoo.com/mrss/');
45
-		$xpath->registerNamespace('rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
46
-		$xpath->registerNamespace('slash', 'http://purl.org/rss/1.0/modules/slash/');
47
-		$xpath->registerNamespace('dc', 'http://purl.org/dc/elements/1.1/');
48
-		$xpath->registerNamespace('content', 'http://purl.org/rss/1.0/modules/content/');
49
-		$xpath->registerNamespace('thread', 'http://purl.org/syndication/thread/1.0');
50
-
51
-		$this->xpath = $xpath;
52
-
53
-		$root = $xpath->query("(//atom03:feed|//atom:feed|//channel|//rdf:rdf|//rdf:RDF)");
54
-
55
-		if ($root && $root->length > 0) {
56
-			$root = $root->item(0);
57
-
58
-			if ($root) {
59
-				switch (mb_strtolower($root->tagName)) {
60
-				case "rdf:rdf":
61
-					$this->type = $this::FEED_RDF;
62
-					break;
63
-				case "channel":
64
-					$this->type = $this::FEED_RSS;
65
-					break;
66
-				case "feed":
67
-				case "atom:feed":
68
-					$this->type = $this::FEED_ATOM;
69
-					break;
70
-				default:
71
-					if( !isset($this->error) ){
72
-						$this->error = "Unknown/unsupported feed type";
73
-					}
74
-					return;
75
-				}
76
-			}
77
-
78
-			switch ($this->type) {
79
-			case $this::FEED_ATOM:
80
-
81
-				$title = $xpath->query("//atom:feed/atom:title")->item(0);
82
-
83
-				if (!$title)
84
-					$title = $xpath->query("//atom03:feed/atom03:title")->item(0);
85
-
86
-
87
-				if ($title) {
88
-					$this->title = $title->nodeValue;
89
-				}
90
-
91
-				$link = $xpath->query("//atom:feed/atom:link[not(@rel)]")->item(0);
92
-
93
-				if (!$link)
94
-					$link = $xpath->query("//atom:feed/atom:link[@rel='alternate']")->item(0);
95
-
96
-				if (!$link)
97
-					$link = $xpath->query("//atom03:feed/atom03:link[not(@rel)]")->item(0);
98
-
99
-				if (!$link)
100
-					$link = $xpath->query("//atom03:feed/atom03:link[@rel='alternate']")->item(0);
101
-
102
-				if ($link && $link->hasAttributes()) {
103
-					$this->link = $link->getAttribute("href");
104
-				}
105
-
106
-				$articles = $xpath->query("//atom:entry");
107
-
108
-				if (!$articles || $articles->length == 0)
109
-					$articles = $xpath->query("//atom03:entry");
110
-
111
-				foreach ($articles as $article) {
112
-					array_push($this->items, new FeedItem_Atom($article, $this->doc, $this->xpath));
113
-				}
114
-
115
-				break;
116
-			case $this::FEED_RSS:
117
-				$title = $xpath->query("//channel/title")->item(0);
118
-
119
-				if ($title) {
120
-					$this->title = $title->nodeValue;
121
-				}
122
-
123
-				$link = $xpath->query("//channel/link")->item(0);
124
-
125
-				if ($link) {
126
-					if ($link->getAttribute("href"))
127
-						$this->link = $link->getAttribute("href");
128
-					else if ($link->nodeValue)
129
-						$this->link = $link->nodeValue;
130
-				}
131
-
132
-				$articles = $xpath->query("//channel/item");
133
-
134
-				foreach ($articles as $article) {
135
-					array_push($this->items, new FeedItem_RSS($article, $this->doc, $this->xpath));
136
-				}
137
-
138
-				break;
139
-			case $this::FEED_RDF:
140
-				$xpath->registerNamespace('rssfake', 'http://purl.org/rss/1.0/');
141
-
142
-				$title = $xpath->query("//rssfake:channel/rssfake:title")->item(0);
143
-
144
-				if ($title) {
145
-					$this->title = $title->nodeValue;
146
-				}
147
-
148
-				$link = $xpath->query("//rssfake:channel/rssfake:link")->item(0);
149
-
150
-				if ($link) {
151
-					$this->link = $link->nodeValue;
152
-				}
153
-
154
-				$articles = $xpath->query("//rssfake:item");
155
-
156
-				foreach ($articles as $article) {
157
-					array_push($this->items, new FeedItem_RSS($article, $this->doc, $this->xpath));
158
-				}
159
-
160
-				break;
161
-
162
-			}
163
-
164
-			if ($this->title) $this->title = trim($this->title);
165
-			if ($this->link) $this->link = trim($this->link);
3
+    private $doc;
4
+    private $error;
5
+    private $libxml_errors = array();
6
+    private $items;
7
+    private $link;
8
+    private $title;
9
+    private $type;
10
+    private $xpath;
11
+
12
+    const FEED_RDF = 0;
13
+    const FEED_RSS = 1;
14
+    const FEED_ATOM = 2;
15
+
16
+    public function __construct($data) {
17
+        libxml_use_internal_errors(true);
18
+        libxml_clear_errors();
19
+        $this->doc = new DOMDocument();
20
+        $this->doc->loadXML($data);
21
+
22
+        mb_substitute_character("none");
23
+
24
+        $error = libxml_get_last_error();
25
+
26
+        if ($error) {
27
+            foreach (libxml_get_errors() as $error) {
28
+                if ($error->level == LIBXML_ERR_FATAL) {
29
+                    if(!isset($this->error)) //currently only the first error is reported
30
+                        $this->error = $this->format_error($error);
31
+                    $this->libxml_errors [] = $this->format_error($error);
32
+                }
33
+            }
34
+        }
35
+        libxml_clear_errors();
36
+
37
+        $this->items = array();
38
+    }
39
+
40
+    public function init() {
41
+        $xpath = new DOMXPath($this->doc);
42
+        $xpath->registerNamespace('atom', 'http://www.w3.org/2005/Atom');
43
+        $xpath->registerNamespace('atom03', 'http://purl.org/atom/ns#');
44
+        $xpath->registerNamespace('media', 'http://search.yahoo.com/mrss/');
45
+        $xpath->registerNamespace('rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
46
+        $xpath->registerNamespace('slash', 'http://purl.org/rss/1.0/modules/slash/');
47
+        $xpath->registerNamespace('dc', 'http://purl.org/dc/elements/1.1/');
48
+        $xpath->registerNamespace('content', 'http://purl.org/rss/1.0/modules/content/');
49
+        $xpath->registerNamespace('thread', 'http://purl.org/syndication/thread/1.0');
50
+
51
+        $this->xpath = $xpath;
52
+
53
+        $root = $xpath->query("(//atom03:feed|//atom:feed|//channel|//rdf:rdf|//rdf:RDF)");
54
+
55
+        if ($root && $root->length > 0) {
56
+            $root = $root->item(0);
57
+
58
+            if ($root) {
59
+                switch (mb_strtolower($root->tagName)) {
60
+                case "rdf:rdf":
61
+                    $this->type = $this::FEED_RDF;
62
+                    break;
63
+                case "channel":
64
+                    $this->type = $this::FEED_RSS;
65
+                    break;
66
+                case "feed":
67
+                case "atom:feed":
68
+                    $this->type = $this::FEED_ATOM;
69
+                    break;
70
+                default:
71
+                    if( !isset($this->error) ){
72
+                        $this->error = "Unknown/unsupported feed type";
73
+                    }
74
+                    return;
75
+                }
76
+            }
77
+
78
+            switch ($this->type) {
79
+            case $this::FEED_ATOM:
80
+
81
+                $title = $xpath->query("//atom:feed/atom:title")->item(0);
82
+
83
+                if (!$title)
84
+                    $title = $xpath->query("//atom03:feed/atom03:title")->item(0);
85
+
86
+
87
+                if ($title) {
88
+                    $this->title = $title->nodeValue;
89
+                }
90
+
91
+                $link = $xpath->query("//atom:feed/atom:link[not(@rel)]")->item(0);
92
+
93
+                if (!$link)
94
+                    $link = $xpath->query("//atom:feed/atom:link[@rel='alternate']")->item(0);
95
+
96
+                if (!$link)
97
+                    $link = $xpath->query("//atom03:feed/atom03:link[not(@rel)]")->item(0);
98
+
99
+                if (!$link)
100
+                    $link = $xpath->query("//atom03:feed/atom03:link[@rel='alternate']")->item(0);
101
+
102
+                if ($link && $link->hasAttributes()) {
103
+                    $this->link = $link->getAttribute("href");
104
+                }
105
+
106
+                $articles = $xpath->query("//atom:entry");
107
+
108
+                if (!$articles || $articles->length == 0)
109
+                    $articles = $xpath->query("//atom03:entry");
110
+
111
+                foreach ($articles as $article) {
112
+                    array_push($this->items, new FeedItem_Atom($article, $this->doc, $this->xpath));
113
+                }
114
+
115
+                break;
116
+            case $this::FEED_RSS:
117
+                $title = $xpath->query("//channel/title")->item(0);
118
+
119
+                if ($title) {
120
+                    $this->title = $title->nodeValue;
121
+                }
122
+
123
+                $link = $xpath->query("//channel/link")->item(0);
124
+
125
+                if ($link) {
126
+                    if ($link->getAttribute("href"))
127
+                        $this->link = $link->getAttribute("href");
128
+                    else if ($link->nodeValue)
129
+                        $this->link = $link->nodeValue;
130
+                }
131
+
132
+                $articles = $xpath->query("//channel/item");
133
+
134
+                foreach ($articles as $article) {
135
+                    array_push($this->items, new FeedItem_RSS($article, $this->doc, $this->xpath));
136
+                }
137
+
138
+                break;
139
+            case $this::FEED_RDF:
140
+                $xpath->registerNamespace('rssfake', 'http://purl.org/rss/1.0/');
141
+
142
+                $title = $xpath->query("//rssfake:channel/rssfake:title")->item(0);
143
+
144
+                if ($title) {
145
+                    $this->title = $title->nodeValue;
146
+                }
147
+
148
+                $link = $xpath->query("//rssfake:channel/rssfake:link")->item(0);
149
+
150
+                if ($link) {
151
+                    $this->link = $link->nodeValue;
152
+                }
153
+
154
+                $articles = $xpath->query("//rssfake:item");
155
+
156
+                foreach ($articles as $article) {
157
+                    array_push($this->items, new FeedItem_RSS($article, $this->doc, $this->xpath));
158
+                }
159
+
160
+                break;
161
+
162
+            }
163
+
164
+            if ($this->title) $this->title = trim($this->title);
165
+            if ($this->link) $this->link = trim($this->link);
166 166
 
167
-		} else {
168
-			if( !isset($this->error) ){
169
-				$this->error = "Unknown/unsupported feed type";
170
-			}
171
-			return;
172
-		}
173
-	}
167
+        } else {
168
+            if( !isset($this->error) ){
169
+                $this->error = "Unknown/unsupported feed type";
170
+            }
171
+            return;
172
+        }
173
+    }
174 174
 
175
-	public function format_error($error) {
176
-		if ($error) {
177
-			return sprintf("LibXML error %s at line %d (column %d): %s",
178
-				$error->code, $error->line, $error->column,
179
-				$error->message);
180
-		} else {
181
-			return "";
182
-		}
183
-	}
175
+    public function format_error($error) {
176
+        if ($error) {
177
+            return sprintf("LibXML error %s at line %d (column %d): %s",
178
+                $error->code, $error->line, $error->column,
179
+                $error->message);
180
+        } else {
181
+            return "";
182
+        }
183
+    }
184 184
 
185
-	// libxml may have invalid unicode data in error messages
186
-	public function error() {
187
-		return UConverter::transcode($this->error, 'UTF-8', 'UTF-8');
188
-	}
185
+    // libxml may have invalid unicode data in error messages
186
+    public function error() {
187
+        return UConverter::transcode($this->error, 'UTF-8', 'UTF-8');
188
+    }
189 189
 
190
-	// WARNING: may return invalid unicode data
191
-	public function errors() {
192
-		return $this->libxml_errors;
193
-	}
190
+    // WARNING: may return invalid unicode data
191
+    public function errors() {
192
+        return $this->libxml_errors;
193
+    }
194 194
 
195
-	public function get_link() {
196
-		return clean($this->link);
197
-	}
195
+    public function get_link() {
196
+        return clean($this->link);
197
+    }
198 198
 
199
-	public function get_title() {
200
-		return clean($this->title);
201
-	}
202
-
203
-	public function get_items() {
204
-		return $this->items;
205
-	}
206
-
207
-	public function get_links($rel) {
208
-		$rv = array();
209
-
210
-		switch ($this->type) {
211
-		case $this::FEED_ATOM:
212
-			$links = $this->xpath->query("//atom:feed/atom:link");
213
-
214
-			foreach ($links as $link) {
215
-				if (!$rel || $link->hasAttribute('rel') && $link->getAttribute('rel') == $rel) {
216
-					array_push($rv, clean(trim($link->getAttribute('href'))));
217
-				}
218
-			}
219
-			break;
220
-		case $this::FEED_RSS:
221
-			$links = $this->xpath->query("//atom:link");
222
-
223
-			foreach ($links as $link) {
224
-				if (!$rel || $link->hasAttribute('rel') && $link->getAttribute('rel') == $rel) {
225
-					array_push($rv, clean(trim($link->getAttribute('href'))));
226
-				}
227
-			}
228
-			break;
229
-		}
230
-
231
-		return $rv;
232
-	}
199
+    public function get_title() {
200
+        return clean($this->title);
201
+    }
202
+
203
+    public function get_items() {
204
+        return $this->items;
205
+    }
206
+
207
+    public function get_links($rel) {
208
+        $rv = array();
209
+
210
+        switch ($this->type) {
211
+        case $this::FEED_ATOM:
212
+            $links = $this->xpath->query("//atom:feed/atom:link");
213
+
214
+            foreach ($links as $link) {
215
+                if (!$rel || $link->hasAttribute('rel') && $link->getAttribute('rel') == $rel) {
216
+                    array_push($rv, clean(trim($link->getAttribute('href'))));
217
+                }
218
+            }
219
+            break;
220
+        case $this::FEED_RSS:
221
+            $links = $this->xpath->query("//atom:link");
222
+
223
+            foreach ($links as $link) {
224
+                if (!$rel || $link->hasAttribute('rel') && $link->getAttribute('rel') == $rel) {
225
+                    array_push($rv, clean(trim($link->getAttribute('href'))));
226
+                }
227
+            }
228
+            break;
229
+        }
230
+
231
+        return $rv;
232
+    }
233 233
 }
Please login to merge, or discard this patch.
classes/iauthmodule.php 1 patch
Indentation   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -1,4 +1,4 @@
 block discarded – undo
1 1
 <?php
2 2
 interface IAuthModule {
3
-	public function authenticate($login, $password); // + optional third parameter: $service
3
+    public function authenticate($login, $password); // + optional third parameter: $service
4 4
 }
Please login to merge, or discard this patch.
classes/dbupdater.php 1 patch
Indentation   +78 added lines, -78 removed lines patch added patch discarded remove patch
@@ -2,83 +2,83 @@
 block discarded – undo
2 2
 
3 3
 class DbUpdater {
4 4
 
5
-	private $pdo;
6
-	private $db_type;
7
-	private $need_version;
8
-
9
-	public function __construct($db_type, $need_version) {
10
-		$this->pdo = Db::pdo();
11
-		$this->db_type = $db_type;
12
-		$this->need_version = (int) $need_version;
13
-	}
14
-
15
-	public function getSchemaVersion() {
16
-		$row = $this->pdo->query("SELECT schema_version FROM ttrss_version")->fetch();
17
-		return (int) $row['schema_version'];
18
-	}
19
-
20
-	public function isUpdateRequired() {
21
-		return $this->getSchemaVersion() < $this->need_version;
22
-	}
23
-
24
-	public function getSchemaLines($version) {
25
-		$filename = "schema/versions/".$this->db_type."/$version.sql";
26
-
27
-		if (file_exists($filename)) {
28
-			return explode(";", preg_replace("/[\r\n]/", "", file_get_contents($filename)));
29
-		} else {
30
-			user_error("DB Updater: schema file for version $version is not found.");
31
-			return false;
32
-		}
33
-	}
34
-
35
-	public function performUpdateTo($version, $html_output = true) {
36
-		if ($this->getSchemaVersion() == $version - 1) {
37
-
38
-			$lines = $this->getSchemaLines($version);
39
-
40
-			if (is_array($lines)) {
41
-
42
-				$this->pdo->beginTransaction();
43
-
44
-				foreach ($lines as $line) {
45
-					if (strpos($line, "--") !== 0 && $line) {
46
-
47
-						if ($html_output)
48
-							print "<pre>$line</pre>";
49
-						else
50
-							Debug::log("> $line");
51
-
52
-						try {
53
-							$this->pdo->query($line); // PDO returns errors as exceptions now
54
-						} catch (PDOException $e) {
55
-							if ($html_output) {
56
-								print "<div class='text-error'>Error: " . $e->getMessage() . "</div>";
57
-							} else {
58
-								Debug::log("Error: " . $e->getMessage());
59
-							}
60
-
61
-							$this->pdo->rollBack();
62
-							return false;
63
-						}
64
-					}
65
-				}
66
-
67
-				$db_version = $this->getSchemaVersion();
68
-
69
-				if ($db_version == $version) {
70
-					$this->pdo->commit();
71
-					return true;
72
-				} else {
73
-					$this->pdo->rollBack();
74
-					return false;
75
-				}
76
-			} else {
77
-				return false;
78
-			}
79
-		} else {
80
-			return false;
81
-		}
82
-	}
5
+    private $pdo;
6
+    private $db_type;
7
+    private $need_version;
8
+
9
+    public function __construct($db_type, $need_version) {
10
+        $this->pdo = Db::pdo();
11
+        $this->db_type = $db_type;
12
+        $this->need_version = (int) $need_version;
13
+    }
14
+
15
+    public function getSchemaVersion() {
16
+        $row = $this->pdo->query("SELECT schema_version FROM ttrss_version")->fetch();
17
+        return (int) $row['schema_version'];
18
+    }
19
+
20
+    public function isUpdateRequired() {
21
+        return $this->getSchemaVersion() < $this->need_version;
22
+    }
23
+
24
+    public function getSchemaLines($version) {
25
+        $filename = "schema/versions/".$this->db_type."/$version.sql";
26
+
27
+        if (file_exists($filename)) {
28
+            return explode(";", preg_replace("/[\r\n]/", "", file_get_contents($filename)));
29
+        } else {
30
+            user_error("DB Updater: schema file for version $version is not found.");
31
+            return false;
32
+        }
33
+    }
34
+
35
+    public function performUpdateTo($version, $html_output = true) {
36
+        if ($this->getSchemaVersion() == $version - 1) {
37
+
38
+            $lines = $this->getSchemaLines($version);
39
+
40
+            if (is_array($lines)) {
41
+
42
+                $this->pdo->beginTransaction();
43
+
44
+                foreach ($lines as $line) {
45
+                    if (strpos($line, "--") !== 0 && $line) {
46
+
47
+                        if ($html_output)
48
+                            print "<pre>$line</pre>";
49
+                        else
50
+                            Debug::log("> $line");
51
+
52
+                        try {
53
+                            $this->pdo->query($line); // PDO returns errors as exceptions now
54
+                        } catch (PDOException $e) {
55
+                            if ($html_output) {
56
+                                print "<div class='text-error'>Error: " . $e->getMessage() . "</div>";
57
+                            } else {
58
+                                Debug::log("Error: " . $e->getMessage());
59
+                            }
60
+
61
+                            $this->pdo->rollBack();
62
+                            return false;
63
+                        }
64
+                    }
65
+                }
66
+
67
+                $db_version = $this->getSchemaVersion();
68
+
69
+                if ($db_version == $version) {
70
+                    $this->pdo->commit();
71
+                    return true;
72
+                } else {
73
+                    $this->pdo->rollBack();
74
+                    return false;
75
+                }
76
+            } else {
77
+                return false;
78
+            }
79
+        } else {
80
+            return false;
81
+        }
82
+    }
83 83
 
84 84
 }
Please login to merge, or discard this patch.
classes/feeds.php 1 patch
Indentation   +1546 added lines, -1546 removed lines patch added patch discarded remove patch
@@ -2,298 +2,298 @@  discard block
 block discarded – undo
2 2
 require_once "colors.php";
3 3
 
4 4
 class Feeds extends Handler_Protected {
5
-	const NEVER_GROUP_FEEDS = [ -6, 0 ];
6
-	const NEVER_GROUP_BY_DATE = [ -2, -1, -3 ];
5
+    const NEVER_GROUP_FEEDS = [ -6, 0 ];
6
+    const NEVER_GROUP_BY_DATE = [ -2, -1, -3 ];
7 7
 
8 8
     private $params;
9 9
 
10 10
     function csrf_ignore($method) {
11
-		$csrf_ignored = array("index", "quickaddfeed", "search");
11
+        $csrf_ignored = array("index", "quickaddfeed", "search");
12 12
 
13
-		return array_search($method, $csrf_ignored) !== false;
14
-	}
13
+        return array_search($method, $csrf_ignored) !== false;
14
+    }
15 15
 
16
-	private function format_headline_subtoolbar($feed_site_url, $feed_title,
17
-			$feed_id, $is_cat, $search,
18
-			$error, $feed_last_updated) {
16
+    private function format_headline_subtoolbar($feed_site_url, $feed_title,
17
+            $feed_id, $is_cat, $search,
18
+            $error, $feed_last_updated) {
19 19
 
20
-		if ($is_cat) $cat_q = "&is_cat=$is_cat";
20
+        if ($is_cat) $cat_q = "&is_cat=$is_cat";
21 21
 
22
-		if ($search) {
23
-			$search_q = "&q=$search";
24
-		} else {
25
-			$search_q = "";
26
-		}
22
+        if ($search) {
23
+            $search_q = "&q=$search";
24
+        } else {
25
+            $search_q = "";
26
+        }
27 27
 
28
-		$reply = "";
28
+        $reply = "";
29 29
 
30
-		$rss_link = htmlspecialchars(get_self_url_prefix() .
31
-			"/public.php?op=rss&id=$feed_id$cat_q$search_q");
30
+        $rss_link = htmlspecialchars(get_self_url_prefix() .
31
+            "/public.php?op=rss&id=$feed_id$cat_q$search_q");
32 32
 
33
-		$reply .= "<span class='left'>";
33
+        $reply .= "<span class='left'>";
34 34
 
35
-		$reply .= "<a href=\"#\"
35
+        $reply .= "<a href=\"#\"
36 36
 				title=\"".__("Show as feed")."\"
37 37
 				onclick=\"App.displayDlg('".__("Show as feed")."','generatedFeed', '$feed_id:$is_cat:$rss_link')\">
38 38
 				<i class='icon-syndicate material-icons'>rss_feed</i></a>";
39 39
 
40
-		$reply .= "<span id='feed_title'>";
40
+        $reply .= "<span id='feed_title'>";
41 41
 
42
-		if ($feed_site_url) {
43
-			$last_updated = T_sprintf("Last updated: %s", $feed_last_updated);
42
+        if ($feed_site_url) {
43
+            $last_updated = T_sprintf("Last updated: %s", $feed_last_updated);
44 44
 
45
-			$reply .= "<a title=\"$last_updated\" target='_blank' href=\"$feed_site_url\">".
46
-				truncate_string(strip_tags($feed_title), 30)."</a>";
47
-		} else {
48
-			$reply .= strip_tags($feed_title);
49
-		}
45
+            $reply .= "<a title=\"$last_updated\" target='_blank' href=\"$feed_site_url\">".
46
+                truncate_string(strip_tags($feed_title), 30)."</a>";
47
+        } else {
48
+            $reply .= strip_tags($feed_title);
49
+        }
50 50
 
51
-		if ($error)
52
-			$reply .= " <i title=\"" . htmlspecialchars($error) . "\" class='material-icons icon-error'>error</i>";
51
+        if ($error)
52
+            $reply .= " <i title=\"" . htmlspecialchars($error) . "\" class='material-icons icon-error'>error</i>";
53 53
 
54
-		$reply .= "</span>";
55
-		$reply .= "<span id='feed_current_unread' style='display: none'></span>";
56
-		$reply .= "</span>";
54
+        $reply .= "</span>";
55
+        $reply .= "<span id='feed_current_unread' style='display: none'></span>";
56
+        $reply .= "</span>";
57 57
 
58
-		$reply .= "<span class=\"right\">";
59
-		$reply .= "<span id='selected_prompt'></span>";
60
-		$reply .= "&nbsp;";
61
-		$reply .= "<select dojoType=\"fox.form.Select\"
58
+        $reply .= "<span class=\"right\">";
59
+        $reply .= "<span id='selected_prompt'></span>";
60
+        $reply .= "&nbsp;";
61
+        $reply .= "<select dojoType=\"fox.form.Select\"
62 62
 			onchange=\"Headlines.onActionChanged(this)\">";
63 63
 
64
-		$reply .= "<option value=\"0\" disabled='1'>".__('Select...')."</option>";
64
+        $reply .= "<option value=\"0\" disabled='1'>".__('Select...')."</option>";
65 65
 
66
-		$reply .= "<option value=\"Headlines.select('all')\">".__('All')."</option>";
67
-		$reply .= "<option value=\"Headlines.select('unread')\">".__('Unread')."</option>";
68
-		$reply .= "<option value=\"Headlines.select('invert')\">".__('Invert')."</option>";
69
-		$reply .= "<option value=\"Headlines.select('none')\">".__('None')."</option>";
66
+        $reply .= "<option value=\"Headlines.select('all')\">".__('All')."</option>";
67
+        $reply .= "<option value=\"Headlines.select('unread')\">".__('Unread')."</option>";
68
+        $reply .= "<option value=\"Headlines.select('invert')\">".__('Invert')."</option>";
69
+        $reply .= "<option value=\"Headlines.select('none')\">".__('None')."</option>";
70 70
 
71
-		$reply .= "<option value=\"0\" disabled=\"1\">".__('Selection toggle:')."</option>";
71
+        $reply .= "<option value=\"0\" disabled=\"1\">".__('Selection toggle:')."</option>";
72 72
 
73
-		$reply .= "<option value=\"Headlines.selectionToggleUnread()\">".__('Unread')."</option>
73
+        $reply .= "<option value=\"Headlines.selectionToggleUnread()\">".__('Unread')."</option>
74 74
 			<option value=\"Headlines.selectionToggleMarked()\">".__('Starred')."</option>
75 75
 			<option value=\"Headlines.selectionTogglePublished()\">".__('Published')."</option>";
76 76
 
77
-		$reply .= "<option value=\"0\" disabled=\"1\">".__('Selection:')."</option>";
77
+        $reply .= "<option value=\"0\" disabled=\"1\">".__('Selection:')."</option>";
78 78
 
79
-		$reply .= "<option value=\"Headlines.catchupSelection()\">".__('Mark as read')."</option>";
80
-		$reply .= "<option value=\"Article.selectionSetScore()\">".__('Set score')."</option>";
79
+        $reply .= "<option value=\"Headlines.catchupSelection()\">".__('Mark as read')."</option>";
80
+        $reply .= "<option value=\"Article.selectionSetScore()\">".__('Set score')."</option>";
81 81
 
82
-		if ($feed_id == 0 && !$is_cat) {
83
-			$reply .= "<option value=\"Headlines.archiveSelection()\">".__('Move back')."</option>";
84
-			$reply .= "<option value=\"Headlines.deleteSelection()\">".__('Delete')."</option>";
85
-		} else {
86
-			$reply .= "<option value=\"Headlines.archiveSelection()\">".__('Archive')."</option>";
87
-		}
82
+        if ($feed_id == 0 && !$is_cat) {
83
+            $reply .= "<option value=\"Headlines.archiveSelection()\">".__('Move back')."</option>";
84
+            $reply .= "<option value=\"Headlines.deleteSelection()\">".__('Delete')."</option>";
85
+        } else {
86
+            $reply .= "<option value=\"Headlines.archiveSelection()\">".__('Archive')."</option>";
87
+        }
88 88
 
89
-		if (PluginHost::getInstance()->get_plugin("mail")) {
90
-			$reply .= "<option value=\"Plugins.Mail.send()\">".__('Forward by email').
91
-				"</option>";
92
-		}
89
+        if (PluginHost::getInstance()->get_plugin("mail")) {
90
+            $reply .= "<option value=\"Plugins.Mail.send()\">".__('Forward by email').
91
+                "</option>";
92
+        }
93 93
 
94
-		if (PluginHost::getInstance()->get_plugin("mailto")) {
95
-			$reply .= "<option value=\"Plugins.Mailto.send()\">".__('Forward by email').
96
-				"</option>";
97
-		}
94
+        if (PluginHost::getInstance()->get_plugin("mailto")) {
95
+            $reply .= "<option value=\"Plugins.Mailto.send()\">".__('Forward by email').
96
+                "</option>";
97
+        }
98 98
 
99
-		$reply .= "<option value=\"0\" disabled=\"1\">".__('Feed:')."</option>";
99
+        $reply .= "<option value=\"0\" disabled=\"1\">".__('Feed:')."</option>";
100 100
 
101
-		//$reply .= "<option value=\"catchupPage()\">".__('Mark as read')."</option>";
101
+        //$reply .= "<option value=\"catchupPage()\">".__('Mark as read')."</option>";
102 102
 
103
-		$reply .= "<option value=\"App.displayDlg('".__("Show as feed")."','generatedFeed', '$feed_id:$is_cat:$rss_link')\">".
103
+        $reply .= "<option value=\"App.displayDlg('".__("Show as feed")."','generatedFeed', '$feed_id:$is_cat:$rss_link')\">".
104 104
             __('Show as feed')."</option>";
105 105
 
106
-		$reply .= "</select>";
106
+        $reply .= "</select>";
107 107
 
108
-		//$reply .= "</h2";
108
+        //$reply .= "</h2";
109 109
 
110
-		foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_HEADLINE_TOOLBAR_BUTTON) as $p) {
111
-			 $reply .= $p->hook_headline_toolbar_button($feed_id, $is_cat);
112
-		}
110
+        foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_HEADLINE_TOOLBAR_BUTTON) as $p) {
111
+                $reply .= $p->hook_headline_toolbar_button($feed_id, $is_cat);
112
+        }
113 113
 
114
-		$reply .= "</span>";
114
+        $reply .= "</span>";
115 115
 
116
-		return $reply;
117
-	}
116
+        return $reply;
117
+    }
118 118
 
119
-	private function format_headlines_list($feed, $method, $view_mode, $limit, $cat_view,
120
-					$offset, $override_order = false, $include_children = false, $check_first_id = false,
121
-					$skip_first_id_check = false, $order_by = false) {
119
+    private function format_headlines_list($feed, $method, $view_mode, $limit, $cat_view,
120
+                    $offset, $override_order = false, $include_children = false, $check_first_id = false,
121
+                    $skip_first_id_check = false, $order_by = false) {
122 122
 
123
-		$disable_cache = false;
123
+        $disable_cache = false;
124 124
 
125
-		$reply = array();
125
+        $reply = array();
126 126
 
127
-		$rgba_cache = array();
128
-		$topmost_article_ids = array();
127
+        $rgba_cache = array();
128
+        $topmost_article_ids = array();
129 129
 
130
-		if (!$offset) $offset = 0;
131
-		if ($method == "undefined") $method = "";
130
+        if (!$offset) $offset = 0;
131
+        if ($method == "undefined") $method = "";
132 132
 
133
-		$method_split = explode(":", $method);
133
+        $method_split = explode(":", $method);
134 134
 
135
-		if ($method == "ForceUpdate" && $feed > 0 && is_numeric($feed)) {
135
+        if ($method == "ForceUpdate" && $feed > 0 && is_numeric($feed)) {
136 136
             $sth = $this->pdo->prepare("UPDATE ttrss_feeds
137 137
                             SET last_updated = '1970-01-01', last_update_started = '1970-01-01'
138 138
                             WHERE id = ?");
139 139
             $sth->execute([$feed]);
140
-		}
141
-
142
-		if ($method_split[0] == "MarkAllReadGR")  {
143
-			$this->catchup_feed($method_split[1], false);
144
-		}
145
-
146
-		// FIXME: might break tag display?
147
-
148
-		if (is_numeric($feed) && $feed > 0 && !$cat_view) {
149
-			$sth = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE id = ? LIMIT 1");
150
-			$sth->execute([$feed]);
151
-
152
-			if (!$sth->fetch()) {
153
-				$reply['content'] = "<div align='center'>".__('Feed not found.')."</div>";
154
-			}
155
-		}
156
-
157
-		@$search = $_REQUEST["query"];
158
-		@$search_language = $_REQUEST["search_language"]; // PGSQL only
159
-
160
-		if ($search) {
161
-			$disable_cache = true;
162
-		}
163
-
164
-		if (!$cat_view && is_numeric($feed) && $feed < PLUGIN_FEED_BASE_INDEX && $feed > LABEL_BASE_INDEX) {
165
-			$handler = PluginHost::getInstance()->get_feed_handler(
166
-				PluginHost::feed_to_pfeed_id($feed));
167
-
168
-			if ($handler) {
169
-				$options = array(
170
-					"limit" => $limit,
171
-					"view_mode" => $view_mode,
172
-					"cat_view" => $cat_view,
173
-					"search" => $search,
174
-					"override_order" => $override_order,
175
-					"offset" => $offset,
176
-					"owner_uid" => $_SESSION["uid"],
177
-					"filter" => false,
178
-					"since_id" => 0,
179
-					"include_children" => $include_children,
180
-					"order_by" => $order_by);
181
-
182
-				$qfh_ret = $handler->get_headlines(PluginHost::feed_to_pfeed_id($feed),
183
-					$options);
184
-			}
185
-
186
-		} else {
187
-
188
-			$params = array(
189
-				"feed" => $feed,
190
-				"limit" => $limit,
191
-				"view_mode" => $view_mode,
192
-				"cat_view" => $cat_view,
193
-				"search" => $search,
194
-				"search_language" => $search_language,
195
-				"override_order" => $override_order,
196
-				"offset" => $offset,
197
-				"include_children" => $include_children,
198
-				"check_first_id" => $check_first_id,
199
-				"skip_first_id_check" => $skip_first_id_check,
200
-                "order_by" => $order_by
201
-			);
140
+        }
141
+
142
+        if ($method_split[0] == "MarkAllReadGR")  {
143
+            $this->catchup_feed($method_split[1], false);
144
+        }
145
+
146
+        // FIXME: might break tag display?
147
+
148
+        if (is_numeric($feed) && $feed > 0 && !$cat_view) {
149
+            $sth = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE id = ? LIMIT 1");
150
+            $sth->execute([$feed]);
202 151
 
203
-			$qfh_ret = $this->queryFeedHeadlines($params);
204
-		}
152
+            if (!$sth->fetch()) {
153
+                $reply['content'] = "<div align='center'>".__('Feed not found.')."</div>";
154
+            }
155
+        }
205 156
 
206
-		$vfeed_group_enabled = get_pref("VFEED_GROUP_BY_FEED") &&
207
-			!(in_array($feed, Feeds::NEVER_GROUP_FEEDS) && !$cat_view);
157
+        @$search = $_REQUEST["query"];
158
+        @$search_language = $_REQUEST["search_language"]; // PGSQL only
208 159
 
209
-		$result = $qfh_ret[0]; // this could be either a PDO query result or a -1 if first id changed
210
-		$feed_title = $qfh_ret[1];
211
-		$feed_site_url = $qfh_ret[2];
212
-		$last_error = $qfh_ret[3];
213
-		$last_updated = strpos($qfh_ret[4], '1970-') === FALSE ?
214
-			make_local_datetime($qfh_ret[4], false) : __("Never");
215
-		$highlight_words = $qfh_ret[5];
216
-		$reply['first_id'] = $qfh_ret[6];
217
-		$reply['is_vfeed'] = $qfh_ret[7];
218
-		$query_error_override = $qfh_ret[8];
160
+        if ($search) {
161
+            $disable_cache = true;
162
+        }
219 163
 
220
-		$reply['search_query'] = [$search, $search_language];
221
-		$reply['vfeed_group_enabled'] = $vfeed_group_enabled;
164
+        if (!$cat_view && is_numeric($feed) && $feed < PLUGIN_FEED_BASE_INDEX && $feed > LABEL_BASE_INDEX) {
165
+            $handler = PluginHost::getInstance()->get_feed_handler(
166
+                PluginHost::feed_to_pfeed_id($feed));
167
+
168
+            if ($handler) {
169
+                $options = array(
170
+                    "limit" => $limit,
171
+                    "view_mode" => $view_mode,
172
+                    "cat_view" => $cat_view,
173
+                    "search" => $search,
174
+                    "override_order" => $override_order,
175
+                    "offset" => $offset,
176
+                    "owner_uid" => $_SESSION["uid"],
177
+                    "filter" => false,
178
+                    "since_id" => 0,
179
+                    "include_children" => $include_children,
180
+                    "order_by" => $order_by);
181
+
182
+                $qfh_ret = $handler->get_headlines(PluginHost::feed_to_pfeed_id($feed),
183
+                    $options);
184
+            }
185
+
186
+        } else {
187
+
188
+            $params = array(
189
+                "feed" => $feed,
190
+                "limit" => $limit,
191
+                "view_mode" => $view_mode,
192
+                "cat_view" => $cat_view,
193
+                "search" => $search,
194
+                "search_language" => $search_language,
195
+                "override_order" => $override_order,
196
+                "offset" => $offset,
197
+                "include_children" => $include_children,
198
+                "check_first_id" => $check_first_id,
199
+                "skip_first_id_check" => $skip_first_id_check,
200
+                "order_by" => $order_by
201
+            );
222 202
 
223
-		$reply['toolbar'] = $this->format_headline_subtoolbar($feed_site_url,
224
-			$feed_title,
225
-			$feed, $cat_view, $search,
226
-			$last_error, $last_updated);
203
+            $qfh_ret = $this->queryFeedHeadlines($params);
204
+        }
227 205
 
228
-		if ($offset == 0) {
229
-			foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_HEADLINES_BEFORE) as $p) {
230
-				 $reply['content'] .= $p->hook_headlines_before($feed, $cat_view, $qfh_ret);
231
-			}
232
-		}
206
+        $vfeed_group_enabled = get_pref("VFEED_GROUP_BY_FEED") &&
207
+            !(in_array($feed, Feeds::NEVER_GROUP_FEEDS) && !$cat_view);
208
+
209
+        $result = $qfh_ret[0]; // this could be either a PDO query result or a -1 if first id changed
210
+        $feed_title = $qfh_ret[1];
211
+        $feed_site_url = $qfh_ret[2];
212
+        $last_error = $qfh_ret[3];
213
+        $last_updated = strpos($qfh_ret[4], '1970-') === FALSE ?
214
+            make_local_datetime($qfh_ret[4], false) : __("Never");
215
+        $highlight_words = $qfh_ret[5];
216
+        $reply['first_id'] = $qfh_ret[6];
217
+        $reply['is_vfeed'] = $qfh_ret[7];
218
+        $query_error_override = $qfh_ret[8];
219
+
220
+        $reply['search_query'] = [$search, $search_language];
221
+        $reply['vfeed_group_enabled'] = $vfeed_group_enabled;
222
+
223
+        $reply['toolbar'] = $this->format_headline_subtoolbar($feed_site_url,
224
+            $feed_title,
225
+            $feed, $cat_view, $search,
226
+            $last_error, $last_updated);
227
+
228
+        if ($offset == 0) {
229
+            foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_HEADLINES_BEFORE) as $p) {
230
+                    $reply['content'] .= $p->hook_headlines_before($feed, $cat_view, $qfh_ret);
231
+            }
232
+        }
233 233
 
234
-		$reply['content'] = [];
234
+        $reply['content'] = [];
235 235
 
236
-		$headlines_count = 0;
236
+        $headlines_count = 0;
237 237
 
238 238
         if (is_object($result)) {
239
-			while ($line = $result->fetch(PDO::FETCH_ASSOC)) {
239
+            while ($line = $result->fetch(PDO::FETCH_ASSOC)) {
240 240
 
241
-				++$headlines_count;
241
+                ++$headlines_count;
242 242
 
243
-				if (!get_pref('SHOW_CONTENT_PREVIEW')) {
244
-					$line["content_preview"] = "";
245
-				} else {
246
-					$line["content_preview"] =  "&mdash; " . truncate_string(strip_tags($line["content"]), 250);
243
+                if (!get_pref('SHOW_CONTENT_PREVIEW')) {
244
+                    $line["content_preview"] = "";
245
+                } else {
246
+                    $line["content_preview"] =  "&mdash; " . truncate_string(strip_tags($line["content"]), 250);
247 247
 
248
-					foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_QUERY_HEADLINES) as $p) {
249
-						$line = $p->hook_query_headlines($line, 250, false);
250
-					}
248
+                    foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_QUERY_HEADLINES) as $p) {
249
+                        $line = $p->hook_query_headlines($line, 250, false);
250
+                    }
251 251
                 }
252 252
 
253
-				$id = $line["id"];
253
+                $id = $line["id"];
254 254
 
255
-				// frontend doesn't expect pdo returning booleans as strings on mysql
256
-				if (DB_TYPE == "mysql") {
257
-					foreach (["unread", "marked", "published"] as $k) {
258
-						$line[$k] = $line[$k] === "1";
259
-					}
260
-				}
255
+                // frontend doesn't expect pdo returning booleans as strings on mysql
256
+                if (DB_TYPE == "mysql") {
257
+                    foreach (["unread", "marked", "published"] as $k) {
258
+                        $line[$k] = $line[$k] === "1";
259
+                    }
260
+                }
261 261
 
262
-				// normalize archived feed
263
-				if ($line['feed_id'] === null) {
264
-					$line['feed_id'] = 0;
265
-					$line["feed_title"] = __("Archived articles");
266
-				}
262
+                // normalize archived feed
263
+                if ($line['feed_id'] === null) {
264
+                    $line['feed_id'] = 0;
265
+                    $line["feed_title"] = __("Archived articles");
266
+                }
267 267
 
268
-				$feed_id = $line["feed_id"];
268
+                $feed_id = $line["feed_id"];
269 269
 
270
-				$label_cache = $line["label_cache"];
271
-				$labels = false;
270
+                $label_cache = $line["label_cache"];
271
+                $labels = false;
272 272
 
273
-				if ($label_cache) {
274
-					$label_cache = json_decode($label_cache, true);
273
+                if ($label_cache) {
274
+                    $label_cache = json_decode($label_cache, true);
275 275
 
276
-					if ($label_cache) {
277
-						if ($label_cache["no-labels"] == 1)
278
-							$labels = array();
279
-						else
280
-							$labels = $label_cache;
281
-					}
282
-				}
276
+                    if ($label_cache) {
277
+                        if ($label_cache["no-labels"] == 1)
278
+                            $labels = array();
279
+                        else
280
+                            $labels = $label_cache;
281
+                    }
282
+                }
283 283
 
284
-				if (!is_array($labels)) $labels = Article::get_article_labels($id);
284
+                if (!is_array($labels)) $labels = Article::get_article_labels($id);
285 285
 
286
-				$labels_str = "<span class=\"HLLCTR-$id\">";
287
-				$labels_str .= Article::format_article_labels($labels);
288
-				$labels_str .= "</span>";
286
+                $labels_str = "<span class=\"HLLCTR-$id\">";
287
+                $labels_str .= Article::format_article_labels($labels);
288
+                $labels_str .= "</span>";
289 289
 
290
-				$line["labels"] = $labels_str;
290
+                $line["labels"] = $labels_str;
291 291
 
292
-				if (count($topmost_article_ids) < 3) {
293
-					array_push($topmost_article_ids, $id);
294
-				}
292
+                if (count($topmost_article_ids) < 3) {
293
+                    array_push($topmost_article_ids, $id);
294
+                }
295 295
 
296
-				if (!$line["feed_title"]) $line["feed_title"] = "";
296
+                if (!$line["feed_title"]) $line["feed_title"] = "";
297 297
 
298 298
                 $line["buttons_left"] = "";
299 299
                 foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_ARTICLE_LEFT_BUTTON) as $p) {
@@ -343,341 +343,341 @@  discard block
 block discarded – undo
343 343
                     }
344 344
                 }
345 345
 
346
-				$line["updated_long"] = make_local_datetime($line["updated"],true);
347
-				$line["updated"] = make_local_datetime($line["updated"], false, false, false, true);
346
+                $line["updated_long"] = make_local_datetime($line["updated"],true);
347
+                $line["updated"] = make_local_datetime($line["updated"], false, false, false, true);
348 348
 
349 349
 
350
-				$line['imported'] = T_sprintf("Imported at %s",
351
-					make_local_datetime($line["date_entered"], false));
350
+                $line['imported'] = T_sprintf("Imported at %s",
351
+                    make_local_datetime($line["date_entered"], false));
352 352
 
353
-				if ($line["tag_cache"])
354
-					$tags = explode(",", $line["tag_cache"]);
355
-				else
356
-					$tags = false;
353
+                if ($line["tag_cache"])
354
+                    $tags = explode(",", $line["tag_cache"]);
355
+                else
356
+                    $tags = false;
357 357
 
358
-				$line["tags_str"] = Article::format_tags_string($tags);
358
+                $line["tags_str"] = Article::format_tags_string($tags);
359 359
 
360
-				if (feeds::feedHasIcon($feed_id)) {
361
-					$line['feed_icon'] = "<img class=\"icon\" src=\"".ICONS_URL."/$feed_id.ico\" alt=\"\">";
362
-				} else {
363
-					$line['feed_icon'] = "<i class='icon-no-feed material-icons'>rss_feed</i>";
364
-				}
360
+                if (feeds::feedHasIcon($feed_id)) {
361
+                    $line['feed_icon'] = "<img class=\"icon\" src=\"".ICONS_URL."/$feed_id.ico\" alt=\"\">";
362
+                } else {
363
+                    $line['feed_icon'] = "<i class='icon-no-feed material-icons'>rss_feed</i>";
364
+                }
365 365
 
366
-			    //setting feed headline background color, needs to change text color based on dark/light
367
-				$fav_color = $line['favicon_avg_color'];
366
+                //setting feed headline background color, needs to change text color based on dark/light
367
+                $fav_color = $line['favicon_avg_color'];
368 368
 
369
-				require_once "colors.php";
369
+                require_once "colors.php";
370 370
 
371
-				if (!isset($rgba_cache[$feed_id])) {
372
-					if ($fav_color && $fav_color != 'fail') {
373
-						$rgba_cache[$feed_id] = _color_unpack($fav_color);
374
-					} else {
375
-						$rgba_cache[$feed_id] = _color_unpack($this->color_of($line['feed_title']));
376
-					}
377
-				}
371
+                if (!isset($rgba_cache[$feed_id])) {
372
+                    if ($fav_color && $fav_color != 'fail') {
373
+                        $rgba_cache[$feed_id] = _color_unpack($fav_color);
374
+                    } else {
375
+                        $rgba_cache[$feed_id] = _color_unpack($this->color_of($line['feed_title']));
376
+                    }
377
+                }
378 378
 
379
-				if (isset($rgba_cache[$feed_id])) {
380
-				    $line['feed_bg_color'] = 'rgba(' . implode(",", $rgba_cache[$feed_id]) . ',0.3)';
379
+                if (isset($rgba_cache[$feed_id])) {
380
+                    $line['feed_bg_color'] = 'rgba(' . implode(",", $rgba_cache[$feed_id]) . ',0.3)';
381 381
                 }
382 382
 
383
-				/* we don't need those */
383
+                /* we don't need those */
384 384
 
385 385
                 foreach (["date_entered", "guid", "last_published", "last_marked", "tag_cache", "favicon_avg_color",
386
-                             "uuid", "label_cache", "yyiw"] as $k)
386
+                                "uuid", "label_cache", "yyiw"] as $k)
387 387
                     unset($line[$k]);
388 388
 
389
-				array_push($reply['content'], $line);
390
-			}
391
-        }
392
-
393
-		if (!$headlines_count) {
394
-
395
-			if (is_object($result)) {
396
-
397
-				if ($query_error_override) {
398
-					$message = $query_error_override;
399
-				} else {
400
-					switch ($view_mode) {
401
-						case "unread":
402
-							$message = __("No unread articles found to display.");
403
-							break;
404
-						case "updated":
405
-							$message = __("No updated articles found to display.");
406
-							break;
407
-						case "marked":
408
-							$message = __("No starred articles found to display.");
409
-							break;
410
-						default:
411
-							if ($feed < LABEL_BASE_INDEX) {
412
-								$message = __("No articles found to display. You can assign articles to labels manually from article header context menu (applies to all selected articles) or use a filter.");
413
-							} else {
414
-								$message = __("No articles found to display.");
415
-							}
416
-					}
417
-				}
418
-
419
-				if (!$offset && $message) {
420
-					$reply['content'] = "<div class='whiteBox'>$message";
421
-
422
-					$reply['content'] .= "<p><span class=\"text-muted\">";
423
-
424
-					$sth = $this->pdo->prepare("SELECT " . SUBSTRING_FOR_DATE . "(MAX(last_updated), 1, 19) AS last_updated FROM ttrss_feeds
389
+                array_push($reply['content'], $line);
390
+            }
391
+        }
392
+
393
+        if (!$headlines_count) {
394
+
395
+            if (is_object($result)) {
396
+
397
+                if ($query_error_override) {
398
+                    $message = $query_error_override;
399
+                } else {
400
+                    switch ($view_mode) {
401
+                        case "unread":
402
+                            $message = __("No unread articles found to display.");
403
+                            break;
404
+                        case "updated":
405
+                            $message = __("No updated articles found to display.");
406
+                            break;
407
+                        case "marked":
408
+                            $message = __("No starred articles found to display.");
409
+                            break;
410
+                        default:
411
+                            if ($feed < LABEL_BASE_INDEX) {
412
+                                $message = __("No articles found to display. You can assign articles to labels manually from article header context menu (applies to all selected articles) or use a filter.");
413
+                            } else {
414
+                                $message = __("No articles found to display.");
415
+                            }
416
+                    }
417
+                }
418
+
419
+                if (!$offset && $message) {
420
+                    $reply['content'] = "<div class='whiteBox'>$message";
421
+
422
+                    $reply['content'] .= "<p><span class=\"text-muted\">";
423
+
424
+                    $sth = $this->pdo->prepare("SELECT " . SUBSTRING_FOR_DATE . "(MAX(last_updated), 1, 19) AS last_updated FROM ttrss_feeds
425 425
                         WHERE owner_uid = ?");
426
-					$sth->execute([$_SESSION['uid']]);
427
-					$row = $sth->fetch();
426
+                    $sth->execute([$_SESSION['uid']]);
427
+                    $row = $sth->fetch();
428 428
 
429
-					$last_updated = make_local_datetime($row["last_updated"], false);
429
+                    $last_updated = make_local_datetime($row["last_updated"], false);
430 430
 
431
-					$reply['content'] .= sprintf(__("Feeds last updated at %s"), $last_updated);
431
+                    $reply['content'] .= sprintf(__("Feeds last updated at %s"), $last_updated);
432 432
 
433
-					$sth = $this->pdo->prepare("SELECT COUNT(id) AS num_errors
433
+                    $sth = $this->pdo->prepare("SELECT COUNT(id) AS num_errors
434 434
                         FROM ttrss_feeds WHERE last_error != '' AND owner_uid = ?");
435
-					$sth->execute([$_SESSION['uid']]);
436
-					$row = $sth->fetch();
435
+                    $sth->execute([$_SESSION['uid']]);
436
+                    $row = $sth->fetch();
437 437
 
438
-					$num_errors = $row["num_errors"];
438
+                    $num_errors = $row["num_errors"];
439 439
 
440
-					if ($num_errors > 0) {
441
-						$reply['content'] .= "<br/>";
442
-						$reply['content'] .= "<a class=\"text-muted\" href=\"#\" onclick=\"CommonDialogs.showFeedsWithErrors()\">" .
443
-							__('Some feeds have update errors (click for details)') . "</a>";
444
-					}
445
-					$reply['content'] .= "</span></p></div>";
440
+                    if ($num_errors > 0) {
441
+                        $reply['content'] .= "<br/>";
442
+                        $reply['content'] .= "<a class=\"text-muted\" href=\"#\" onclick=\"CommonDialogs.showFeedsWithErrors()\">" .
443
+                            __('Some feeds have update errors (click for details)') . "</a>";
444
+                    }
445
+                    $reply['content'] .= "</span></p></div>";
446 446
 
447
-				}
448
-			} else if (is_numeric($result) && $result == -1) {
449
-				$reply['first_id_changed'] = true;
450
-			}
451
-		}
447
+                }
448
+            } else if (is_numeric($result) && $result == -1) {
449
+                $reply['first_id_changed'] = true;
450
+            }
451
+        }
452 452
 
453
-		return array($topmost_article_ids, $headlines_count, $feed, $disable_cache, $reply);
454
-	}
453
+        return array($topmost_article_ids, $headlines_count, $feed, $disable_cache, $reply);
454
+    }
455 455
 
456
-	public function catchupAll() {
457
-		$sth = $this->pdo->prepare("UPDATE ttrss_user_entries SET
456
+    public function catchupAll() {
457
+        $sth = $this->pdo->prepare("UPDATE ttrss_user_entries SET
458 458
 						last_read = NOW(), unread = false WHERE unread = true AND owner_uid = ?");
459
-		$sth->execute([$_SESSION['uid']]);
459
+        $sth->execute([$_SESSION['uid']]);
460 460
 
461
-		CCache::zero_all($_SESSION["uid"]);
462
-	}
461
+        CCache::zero_all($_SESSION["uid"]);
462
+    }
463 463
 
464
-	public function view() {
465
-		$reply = array();
464
+    public function view() {
465
+        $reply = array();
466 466
 
467
-		$feed = $_REQUEST["feed"];
468
-		$method = $_REQUEST["m"];
469
-		$view_mode = $_REQUEST["view_mode"];
470
-		$limit = 30;
471
-		@$cat_view = $_REQUEST["cat"] == "true";
472
-		@$next_unread_feed = $_REQUEST["nuf"];
473
-		@$offset = $_REQUEST["skip"];
474
-		$order_by = $_REQUEST["order_by"];
475
-		$check_first_id = $_REQUEST["fid"];
467
+        $feed = $_REQUEST["feed"];
468
+        $method = $_REQUEST["m"];
469
+        $view_mode = $_REQUEST["view_mode"];
470
+        $limit = 30;
471
+        @$cat_view = $_REQUEST["cat"] == "true";
472
+        @$next_unread_feed = $_REQUEST["nuf"];
473
+        @$offset = $_REQUEST["skip"];
474
+        $order_by = $_REQUEST["order_by"];
475
+        $check_first_id = $_REQUEST["fid"];
476 476
 
477
-		if (is_numeric($feed)) $feed = (int) $feed;
477
+        if (is_numeric($feed)) $feed = (int) $feed;
478 478
 
479
-		/* Feed -5 is a special case: it is used to display auxiliary information
479
+        /* Feed -5 is a special case: it is used to display auxiliary information
480 480
 		 * when there's nothing to load - e.g. no stuff in fresh feed */
481 481
 
482
-		if ($feed == -5) {
483
-			print json_encode($this->generate_dashboard_feed());
484
-			return;
485
-		}
482
+        if ($feed == -5) {
483
+            print json_encode($this->generate_dashboard_feed());
484
+            return;
485
+        }
486 486
 
487
-		$sth = false;
488
-		if ($feed < LABEL_BASE_INDEX) {
487
+        $sth = false;
488
+        if ($feed < LABEL_BASE_INDEX) {
489 489
 
490
-			$label_feed = Labels::feed_to_label_id($feed);
490
+            $label_feed = Labels::feed_to_label_id($feed);
491 491
 
492
-			$sth = $this->pdo->prepare("SELECT id FROM ttrss_labels2 WHERE
492
+            $sth = $this->pdo->prepare("SELECT id FROM ttrss_labels2 WHERE
493 493
 							id = ? AND owner_uid = ?");
494
-			$sth->execute([$label_feed, $_SESSION['uid']]);
494
+            $sth->execute([$label_feed, $_SESSION['uid']]);
495 495
 
496
-		} else if (!$cat_view && is_numeric($feed) && $feed > 0) {
496
+        } else if (!$cat_view && is_numeric($feed) && $feed > 0) {
497 497
 
498
-			$sth = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE
498
+            $sth = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE
499 499
 							id = ? AND owner_uid = ?");
500
-			$sth->execute([$feed, $_SESSION['uid']]);
500
+            $sth->execute([$feed, $_SESSION['uid']]);
501 501
 
502
-		} else if ($cat_view && is_numeric($feed) && $feed > 0) {
502
+        } else if ($cat_view && is_numeric($feed) && $feed > 0) {
503 503
 
504
-			$sth = $this->pdo->prepare("SELECT id FROM ttrss_feed_categories WHERE
504
+            $sth = $this->pdo->prepare("SELECT id FROM ttrss_feed_categories WHERE
505 505
 							id = ? AND owner_uid = ?");
506 506
 
507
-			$sth->execute([$feed, $_SESSION['uid']]);
508
-		}
507
+            $sth->execute([$feed, $_SESSION['uid']]);
508
+        }
509 509
 
510
-		if ($sth && !$sth->fetch()) {
511
-			print json_encode($this->generate_error_feed(__("Feed not found.")));
512
-			return;
513
-		}
510
+        if ($sth && !$sth->fetch()) {
511
+            print json_encode($this->generate_error_feed(__("Feed not found.")));
512
+            return;
513
+        }
514 514
 
515
-		/* Updating a label ccache means recalculating all of the caches
515
+        /* Updating a label ccache means recalculating all of the caches
516 516
 		 * so for performance reasons we don't do that here */
517 517
 
518
-		if ($feed >= 0) {
519
-			CCache::update($feed, $_SESSION["uid"], $cat_view);
520
-		}
518
+        if ($feed >= 0) {
519
+            CCache::update($feed, $_SESSION["uid"], $cat_view);
520
+        }
521 521
 
522
-		set_pref("_DEFAULT_VIEW_MODE", $view_mode);
523
-		set_pref("_DEFAULT_VIEW_ORDER_BY", $order_by);
522
+        set_pref("_DEFAULT_VIEW_MODE", $view_mode);
523
+        set_pref("_DEFAULT_VIEW_ORDER_BY", $order_by);
524 524
 
525
-		/* bump login timestamp if needed */
526
-		if (time() - $_SESSION["last_login_update"] > 3600) {
527
-			$sth = $this->pdo->prepare("UPDATE ttrss_users SET last_login = NOW() WHERE id = ?");
528
-			$sth->execute([$_SESSION['uid']]);
525
+        /* bump login timestamp if needed */
526
+        if (time() - $_SESSION["last_login_update"] > 3600) {
527
+            $sth = $this->pdo->prepare("UPDATE ttrss_users SET last_login = NOW() WHERE id = ?");
528
+            $sth->execute([$_SESSION['uid']]);
529 529
 
530
-			$_SESSION["last_login_update"] = time();
531
-		}
530
+            $_SESSION["last_login_update"] = time();
531
+        }
532 532
 
533
-		if (!$cat_view && is_numeric($feed) && $feed > 0) {
534
-			$sth = $this->pdo->prepare("UPDATE ttrss_feeds SET last_viewed = NOW()
533
+        if (!$cat_view && is_numeric($feed) && $feed > 0) {
534
+            $sth = $this->pdo->prepare("UPDATE ttrss_feeds SET last_viewed = NOW()
535 535
 							WHERE id = ? AND owner_uid = ?");
536
-			$sth->execute([$feed, $_SESSION['uid']]);
537
-		}
538
-
539
-		$reply['headlines'] = [];
540
-
541
-		$override_order = false;
542
-		$skip_first_id_check = false;
536
+            $sth->execute([$feed, $_SESSION['uid']]);
537
+        }
543 538
 
544
-		switch ($order_by) {
545
-		case "title":
546
-			$override_order = "ttrss_entries.title, date_entered, updated";
547
-			break;
548
-		case "date_reverse":
549
-			$override_order = "score DESC, date_entered, updated";
550
-			$skip_first_id_check = true;
551
-			break;
552
-		case "feed_dates":
553
-			$override_order = "updated DESC";
554
-			break;
555
-		}
539
+        $reply['headlines'] = [];
540
+
541
+        $override_order = false;
542
+        $skip_first_id_check = false;
543
+
544
+        switch ($order_by) {
545
+        case "title":
546
+            $override_order = "ttrss_entries.title, date_entered, updated";
547
+            break;
548
+        case "date_reverse":
549
+            $override_order = "score DESC, date_entered, updated";
550
+            $skip_first_id_check = true;
551
+            break;
552
+        case "feed_dates":
553
+            $override_order = "updated DESC";
554
+            break;
555
+        }
556 556
 
557
-		$ret = $this->format_headlines_list($feed, $method,
558
-			$view_mode, $limit, $cat_view, $offset,
559
-			$override_order, true, $check_first_id, $skip_first_id_check, $order_by);
557
+        $ret = $this->format_headlines_list($feed, $method,
558
+            $view_mode, $limit, $cat_view, $offset,
559
+            $override_order, true, $check_first_id, $skip_first_id_check, $order_by);
560 560
 
561
-		$headlines_count = $ret[1];
562
-		$disable_cache = $ret[3];
563
-		$reply['headlines'] = $ret[4];
561
+        $headlines_count = $ret[1];
562
+        $disable_cache = $ret[3];
563
+        $reply['headlines'] = $ret[4];
564 564
 
565
-		if (!$next_unread_feed)
566
-			$reply['headlines']['id'] = $feed;
567
-		else
568
-			$reply['headlines']['id'] = $next_unread_feed;
565
+        if (!$next_unread_feed)
566
+            $reply['headlines']['id'] = $feed;
567
+        else
568
+            $reply['headlines']['id'] = $next_unread_feed;
569 569
 
570
-		$reply['headlines']['is_cat'] = (bool) $cat_view;
570
+        $reply['headlines']['is_cat'] = (bool) $cat_view;
571 571
 
572
-		$reply['headlines-info'] = ["count" => (int) $headlines_count,
573
-            						"disable_cache" => (bool) $disable_cache];
572
+        $reply['headlines-info'] = ["count" => (int) $headlines_count,
573
+                                    "disable_cache" => (bool) $disable_cache];
574 574
 
575
-		// this is parsed by handleRpcJson() on first viewfeed() to set cdm expanded, etc
576
-		$reply['runtime-info'] = make_runtime_info();
575
+        // this is parsed by handleRpcJson() on first viewfeed() to set cdm expanded, etc
576
+        $reply['runtime-info'] = make_runtime_info();
577 577
 
578
-		$reply_json = json_encode($reply);
578
+        $reply_json = json_encode($reply);
579 579
 
580
-		if (!$reply_json) {
581
-		    $reply_json = json_encode(["error" => ["code" => 15,
580
+        if (!$reply_json) {
581
+            $reply_json = json_encode(["error" => ["code" => 15,
582 582
                 "message" => json_last_error_msg()]]);
583 583
         }
584 584
 
585
-		print $reply_json;
585
+        print $reply_json;
586 586
 
587
-	}
587
+    }
588 588
 
589
-	private function generate_dashboard_feed() {
590
-		$reply = array();
589
+    private function generate_dashboard_feed() {
590
+        $reply = array();
591 591
 
592
-		$reply['headlines']['id'] = -5;
593
-		$reply['headlines']['is_cat'] = false;
592
+        $reply['headlines']['id'] = -5;
593
+        $reply['headlines']['is_cat'] = false;
594 594
 
595
-		$reply['headlines']['toolbar'] = '';
595
+        $reply['headlines']['toolbar'] = '';
596 596
 
597
-		$reply['headlines']['content'] = "<div class='whiteBox'>".__('No feed selected.');
597
+        $reply['headlines']['content'] = "<div class='whiteBox'>".__('No feed selected.');
598 598
 
599
-		$reply['headlines']['content'] .= "<p><span class=\"text-muted\">";
599
+        $reply['headlines']['content'] .= "<p><span class=\"text-muted\">";
600 600
 
601
-		$sth = $this->pdo->prepare("SELECT ".SUBSTRING_FOR_DATE."(MAX(last_updated), 1, 19) AS last_updated FROM ttrss_feeds
601
+        $sth = $this->pdo->prepare("SELECT ".SUBSTRING_FOR_DATE."(MAX(last_updated), 1, 19) AS last_updated FROM ttrss_feeds
602 602
 			WHERE owner_uid = ?");
603
-		$sth->execute([$_SESSION['uid']]);
604
-		$row = $sth->fetch();
603
+        $sth->execute([$_SESSION['uid']]);
604
+        $row = $sth->fetch();
605 605
 
606
-		$last_updated = make_local_datetime($row["last_updated"], false);
606
+        $last_updated = make_local_datetime($row["last_updated"], false);
607 607
 
608
-		$reply['headlines']['content'] .= sprintf(__("Feeds last updated at %s"), $last_updated);
608
+        $reply['headlines']['content'] .= sprintf(__("Feeds last updated at %s"), $last_updated);
609 609
 
610
-		$sth = $this->pdo->prepare("SELECT COUNT(id) AS num_errors
610
+        $sth = $this->pdo->prepare("SELECT COUNT(id) AS num_errors
611 611
 			FROM ttrss_feeds WHERE last_error != '' AND owner_uid = ?");
612
-		$sth->execute([$_SESSION['uid']]);
613
-		$row = $sth->fetch();
612
+        $sth->execute([$_SESSION['uid']]);
613
+        $row = $sth->fetch();
614 614
 
615
-		$num_errors = $row["num_errors"];
615
+        $num_errors = $row["num_errors"];
616 616
 
617
-		if ($num_errors > 0) {
618
-			$reply['headlines']['content'] .= "<br/>";
619
-			$reply['headlines']['content'] .= "<a class=\"text-muted\" href=\"#\" onclick=\"CommonDialogs.showFeedsWithErrors()\">".
620
-				__('Some feeds have update errors (click for details)')."</a>";
621
-		}
622
-		$reply['headlines']['content'] .= "</span></p>";
617
+        if ($num_errors > 0) {
618
+            $reply['headlines']['content'] .= "<br/>";
619
+            $reply['headlines']['content'] .= "<a class=\"text-muted\" href=\"#\" onclick=\"CommonDialogs.showFeedsWithErrors()\">".
620
+                __('Some feeds have update errors (click for details)')."</a>";
621
+        }
622
+        $reply['headlines']['content'] .= "</span></p>";
623 623
 
624
-		$reply['headlines-info'] = array("count" => 0,
625
-			"unread" => 0,
626
-			"disable_cache" => true);
624
+        $reply['headlines-info'] = array("count" => 0,
625
+            "unread" => 0,
626
+            "disable_cache" => true);
627 627
 
628
-		return $reply;
629
-	}
628
+        return $reply;
629
+    }
630 630
 
631
-	private function generate_error_feed($error) {
632
-		$reply = array();
631
+    private function generate_error_feed($error) {
632
+        $reply = array();
633 633
 
634
-		$reply['headlines']['id'] = -7;
635
-		$reply['headlines']['is_cat'] = false;
634
+        $reply['headlines']['id'] = -7;
635
+        $reply['headlines']['is_cat'] = false;
636 636
 
637
-		$reply['headlines']['toolbar'] = '';
638
-		$reply['headlines']['content'] = "<div class='whiteBox'>". $error . "</div>";
637
+        $reply['headlines']['toolbar'] = '';
638
+        $reply['headlines']['content'] = "<div class='whiteBox'>". $error . "</div>";
639 639
 
640
-		$reply['headlines-info'] = array("count" => 0,
641
-			"unread" => 0,
642
-			"disable_cache" => true);
640
+        $reply['headlines-info'] = array("count" => 0,
641
+            "unread" => 0,
642
+            "disable_cache" => true);
643 643
 
644
-		return $reply;
645
-	}
644
+        return $reply;
645
+    }
646 646
 
647
-	public function quickAddFeed() {
648
-		print "<form onsubmit='return false'>";
647
+    public function quickAddFeed() {
648
+        print "<form onsubmit='return false'>";
649 649
 
650
-		print_hidden("op", "rpc");
651
-		print_hidden("method", "addfeed");
650
+        print_hidden("op", "rpc");
651
+        print_hidden("method", "addfeed");
652 652
 
653
-		print "<div id='fadd_error_message' style='display : none' class='alert alert-danger'></div>";
653
+        print "<div id='fadd_error_message' style='display : none' class='alert alert-danger'></div>";
654 654
 
655
-		print "<div id='fadd_multiple_notify' style='display : none'>";
656
-		print_notice("Provided URL is a HTML page referencing multiple feeds, please select required feed from the dropdown menu below.");
657
-		print "<p></div>";
655
+        print "<div id='fadd_multiple_notify' style='display : none'>";
656
+        print_notice("Provided URL is a HTML page referencing multiple feeds, please select required feed from the dropdown menu below.");
657
+        print "<p></div>";
658 658
 
659
-		print "<section>";
659
+        print "<section>";
660 660
 
661
-		print "<fieldset>";
662
-		print "<div style='float : right'><img style='display : none' id='feed_add_spinner' src='images/indicator_white.gif'></div>";
663
-		print "<input style='font-size : 16px; width : 500px;'
661
+        print "<fieldset>";
662
+        print "<div style='float : right'><img style='display : none' id='feed_add_spinner' src='images/indicator_white.gif'></div>";
663
+        print "<input style='font-size : 16px; width : 500px;'
664 664
 			placeHolder=\"".__("Feed or site URL")."\"
665 665
 			dojoType='dijit.form.ValidationTextBox' required='1' name='feed' id='feedDlg_feedUrl'>";
666 666
 
667
-		print "</fieldset>";
667
+        print "</fieldset>";
668 668
 
669
-		print "<fieldset>";
669
+        print "<fieldset>";
670 670
 
671
-		if (get_pref('ENABLE_FEED_CATS')) {
672
-			print "<label class='inline'>" . __('Place in category:') . "</label> ";
673
-			print_feed_cat_select("cat", false, 'dojoType="fox.form.Select"');
674
-		}
671
+        if (get_pref('ENABLE_FEED_CATS')) {
672
+            print "<label class='inline'>" . __('Place in category:') . "</label> ";
673
+            print_feed_cat_select("cat", false, 'dojoType="fox.form.Select"');
674
+        }
675 675
 
676
-		print "</fieldset>";
676
+        print "</fieldset>";
677 677
 
678
-		print "</section>";
678
+        print "</section>";
679 679
 
680
-		print '<div id="feedDlg_feedsContainer" style="display : none">
680
+        print '<div id="feedDlg_feedsContainer" style="display : none">
681 681
 				<header>' . __('Available feeds') . '</header>
682 682
 				<section>
683 683
 					<fieldset>
@@ -691,7 +691,7 @@  discard block
 block discarded – undo
691 691
 				</section>
692 692
 			</div>';
693 693
 
694
-		print "<div id='feedDlg_loginContainer' style='display : none'>
694
+        print "<div id='feedDlg_loginContainer' style='display : none'>
695 695
 				<section>
696 696
 				<fieldset>
697 697
 					<input dojoType=\"dijit.form.TextBox\" name='login'\"
@@ -707,98 +707,98 @@  discard block
 block discarded – undo
707 707
 				</section>
708 708
 			</div>";
709 709
 
710
-		print "<section>";
711
-		print "<label>
710
+        print "<section>";
711
+        print "<label>
712 712
 			<label class='checkbox'><input type='checkbox' name='need_auth' dojoType='dijit.form.CheckBox' id='feedDlg_loginCheck'
713 713
 					onclick='displayIfChecked(this, \"feedDlg_loginContainer\")'>
714 714
 				".__('This feed requires authentication.')."</label>";
715
-		print "</section>";
715
+        print "</section>";
716 716
 
717
-		print "<footer>";
718
-		print "<button dojoType='dijit.form.Button' class='alt-primary' type='submit'
717
+        print "<footer>";
718
+        print "<button dojoType='dijit.form.Button' class='alt-primary' type='submit'
719 719
 				onclick=\"return dijit.byId('feedAddDlg').execute()\">".__('Subscribe')."</button>";
720 720
 
721
-		print "<button dojoType='dijit.form.Button' onclick=\"return dijit.byId('feedAddDlg').hide()\">".__('Cancel')."</button>";
722
-		print "</footer>";
721
+        print "<button dojoType='dijit.form.Button' onclick=\"return dijit.byId('feedAddDlg').hide()\">".__('Cancel')."</button>";
722
+        print "</footer>";
723 723
 
724
-		print "</form>";
725
-	}
724
+        print "</form>";
725
+    }
726 726
 
727
-	public function search() {
728
-		$this->params = explode(":", $_REQUEST["param"], 2);
727
+    public function search() {
728
+        $this->params = explode(":", $_REQUEST["param"], 2);
729 729
 
730
-		$active_feed_id = sprintf("%d", $this->params[0]);
731
-		$is_cat = $this->params[1] != "false";
730
+        $active_feed_id = sprintf("%d", $this->params[0]);
731
+        $is_cat = $this->params[1] != "false";
732 732
 
733
-		print "<form onsubmit='return false;'>";
733
+        print "<form onsubmit='return false;'>";
734 734
 
735
-		print "<section>";
735
+        print "<section>";
736 736
 
737
-		print "<fieldset>";
738
-		print "<input dojoType='dijit.form.ValidationTextBox' id='search_query'
737
+        print "<fieldset>";
738
+        print "<input dojoType='dijit.form.ValidationTextBox' id='search_query'
739 739
 			style='font-size : 16px; width : 540px;'
740 740
 			placeHolder=\"".T_sprintf("Search %s...", $this->getFeedTitle($active_feed_id, $is_cat))."\"
741 741
 			name='query' type='search' value=''>";
742
-		print "</fieldset>";
743
-
744
-		if (DB_TYPE == "pgsql") {
745
-			print "<fieldset>";
746
-			print "<label class='inline'>" . __("Language:") . "</label>";
747
-			print_select("search_language", get_pref('DEFAULT_SEARCH_LANGUAGE'), Pref_Feeds::get_ts_languages(),
748
-				"dojoType='fox.form.Select' title=\"".__('Used for word stemming')."\"");
749
-			print "</fieldset>";
750
-		}
742
+        print "</fieldset>";
743
+
744
+        if (DB_TYPE == "pgsql") {
745
+            print "<fieldset>";
746
+            print "<label class='inline'>" . __("Language:") . "</label>";
747
+            print_select("search_language", get_pref('DEFAULT_SEARCH_LANGUAGE'), Pref_Feeds::get_ts_languages(),
748
+                "dojoType='fox.form.Select' title=\"".__('Used for word stemming')."\"");
749
+            print "</fieldset>";
750
+        }
751 751
 
752
-		print "</section>";
752
+        print "</section>";
753 753
 
754
-		print "<footer>";
754
+        print "<footer>";
755 755
 
756
-		if (count(PluginHost::getInstance()->get_hooks(PluginHost::HOOK_SEARCH)) == 0) {
757
-			print "<button dojoType='dijit.form.Button' style='float : left' class='alt-info' onclick='window.open(\"https://tt-rss.org/wiki/SearchSyntax\")'>
756
+        if (count(PluginHost::getInstance()->get_hooks(PluginHost::HOOK_SEARCH)) == 0) {
757
+            print "<button dojoType='dijit.form.Button' style='float : left' class='alt-info' onclick='window.open(\"https://tt-rss.org/wiki/SearchSyntax\")'>
758 758
 				<i class='material-icons'>help</i> ".__("Search syntax")."</button>";
759
-		}
759
+        }
760 760
 
761
-		print "<button dojoType='dijit.form.Button' type='submit' class='alt-primary' onclick=\"dijit.byId('searchDlg').execute()\">".__('Search')."</button>
761
+        print "<button dojoType='dijit.form.Button' type='submit' class='alt-primary' onclick=\"dijit.byId('searchDlg').execute()\">".__('Search')."</button>
762 762
 			<button dojoType='dijit.form.Button' onclick=\"dijit.byId('searchDlg').hide()\">".__('Cancel')."</button>";
763 763
 
764
-		print "</footer>";
764
+        print "</footer>";
765 765
 
766
-		print "</form>";
767
-	}
766
+        print "</form>";
767
+    }
768 768
 
769
-	public function update_debugger() {
770
-		header("Content-type: text/html");
769
+    public function update_debugger() {
770
+        header("Content-type: text/html");
771 771
 
772
-		Debug::set_enabled(true);
773
-		Debug::set_loglevel($_REQUEST["xdebug"]);
772
+        Debug::set_enabled(true);
773
+        Debug::set_loglevel($_REQUEST["xdebug"]);
774 774
 
775
-		$feed_id = (int)$_REQUEST["feed_id"];
776
-		@$do_update = $_REQUEST["action"] == "do_update";
777
-		$csrf_token = $_REQUEST["csrf_token"];
775
+        $feed_id = (int)$_REQUEST["feed_id"];
776
+        @$do_update = $_REQUEST["action"] == "do_update";
777
+        $csrf_token = $_REQUEST["csrf_token"];
778 778
 
779
-		$sth = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE id = ? AND owner_uid = ?");
780
-		$sth->execute([$feed_id, $_SESSION['uid']]);
779
+        $sth = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE id = ? AND owner_uid = ?");
780
+        $sth->execute([$feed_id, $_SESSION['uid']]);
781 781
 
782
-		if (!$sth->fetch()) {
783
-		    print "Access denied.";
784
-		    return;
782
+        if (!$sth->fetch()) {
783
+            print "Access denied.";
784
+            return;
785 785
         }
786 786
 
787
-		$refetch_checked = isset($_REQUEST["force_refetch"]) ? "checked" : "";
788
-		$rehash_checked = isset($_REQUEST["force_rehash"]) ? "checked" : "";
787
+        $refetch_checked = isset($_REQUEST["force_refetch"]) ? "checked" : "";
788
+        $rehash_checked = isset($_REQUEST["force_rehash"]) ? "checked" : "";
789 789
 
790
-		?>
790
+        ?>
791 791
 		<!DOCTYPE html>
792 792
 		<html>
793 793
 		<head>
794 794
 			<?php echo stylesheet_tag("css/default.css") ?>
795 795
 			<title>Feed Debugger</title>
796 796
 			<?php
797
-				echo stylesheet_tag("css/default.css");
798
-				echo javascript_tag("lib/prototype.js");
799
-				echo javascript_tag("lib/dojo/dojo.js");
800
-				echo javascript_tag("lib/dojo/tt-rss-layer.js");
801
-			?>
797
+                echo stylesheet_tag("css/default.css");
798
+                echo javascript_tag("lib/prototype.js");
799
+                echo javascript_tag("lib/dojo/dojo.js");
800
+                echo javascript_tag("lib/dojo/tt-rss-layer.js");
801
+            ?>
802 802
 		</head>
803 803
 		<body class="flat ttrss_utility feed_debugger">
804 804
 		<script type="text/javascript">
@@ -836,904 +836,904 @@  discard block
 block discarded – undo
836 836
 
837 837
 					<pre><?php
838 838
 
839
-					if ($do_update) {
840
-						RSSUtils::update_rss_feed($feed_id, true);
841
-					}
839
+                    if ($do_update) {
840
+                        RSSUtils::update_rss_feed($feed_id, true);
841
+                    }
842 842
 
843
-					?></pre>
843
+                    ?></pre>
844 844
 				</div>
845 845
 			</div>
846 846
 		</body>
847 847
 		</html>
848 848
 		<?php
849 849
 
850
-	}
851
-
852
-	public static function catchup_feed($feed, $cat_view, $owner_uid = false, $mode = 'all', $search = false) {
853
-
854
-		if (!$owner_uid) $owner_uid = $_SESSION['uid'];
855
-
856
-		$pdo = Db::pdo();
857
-
858
-		if (is_array($search) && $search[0]) {
859
-			$search_qpart = "";
860
-
861
-			foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_SEARCH) as $plugin) {
862
-				list($search_qpart, $search_words) = $plugin->hook_search($search[0]);
863
-				break;
864
-			}
865
-
866
-			// fall back in case of no plugins
867
-			if (!$search_qpart) {
868
-				list($search_qpart, $search_words) = Feeds::search_to_sql($search[0], $search[1]);
869
-			}
870
-		} else {
871
-			$search_qpart = "true";
872
-		}
873
-
874
-		// TODO: all this interval stuff needs some generic generator function
875
-
876
-		switch ($mode) {
877
-			case "1day":
878
-				if (DB_TYPE == "pgsql") {
879
-					$date_qpart = "date_entered < NOW() - INTERVAL '1 day' ";
880
-				} else {
881
-					$date_qpart = "date_entered < DATE_SUB(NOW(), INTERVAL 1 DAY) ";
882
-				}
883
-				break;
884
-			case "1week":
885
-				if (DB_TYPE == "pgsql") {
886
-					$date_qpart = "date_entered < NOW() - INTERVAL '1 week' ";
887
-				} else {
888
-					$date_qpart = "date_entered < DATE_SUB(NOW(), INTERVAL 1 WEEK) ";
889
-				}
890
-				break;
891
-			case "2week":
892
-				if (DB_TYPE == "pgsql") {
893
-					$date_qpart = "date_entered < NOW() - INTERVAL '2 week' ";
894
-				} else {
895
-					$date_qpart = "date_entered < DATE_SUB(NOW(), INTERVAL 2 WEEK) ";
896
-				}
897
-				break;
898
-			default:
899
-				$date_qpart = "true";
900
-		}
901
-
902
-		if (is_numeric($feed)) {
903
-			if ($cat_view) {
904
-
905
-				if ($feed >= 0) {
906
-
907
-					if ($feed > 0) {
908
-						$children = Feeds::getChildCategories($feed, $owner_uid);
909
-						array_push($children, $feed);
910
-						$children = array_map("intval", $children);
911
-
912
-						$children = join(",", $children);
913
-
914
-						$cat_qpart = "cat_id IN ($children)";
915
-					} else {
916
-						$cat_qpart = "cat_id IS NULL";
917
-					}
918
-
919
-					$sth = $pdo->prepare("UPDATE ttrss_user_entries
850
+    }
851
+
852
+    public static function catchup_feed($feed, $cat_view, $owner_uid = false, $mode = 'all', $search = false) {
853
+
854
+        if (!$owner_uid) $owner_uid = $_SESSION['uid'];
855
+
856
+        $pdo = Db::pdo();
857
+
858
+        if (is_array($search) && $search[0]) {
859
+            $search_qpart = "";
860
+
861
+            foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_SEARCH) as $plugin) {
862
+                list($search_qpart, $search_words) = $plugin->hook_search($search[0]);
863
+                break;
864
+            }
865
+
866
+            // fall back in case of no plugins
867
+            if (!$search_qpart) {
868
+                list($search_qpart, $search_words) = Feeds::search_to_sql($search[0], $search[1]);
869
+            }
870
+        } else {
871
+            $search_qpart = "true";
872
+        }
873
+
874
+        // TODO: all this interval stuff needs some generic generator function
875
+
876
+        switch ($mode) {
877
+            case "1day":
878
+                if (DB_TYPE == "pgsql") {
879
+                    $date_qpart = "date_entered < NOW() - INTERVAL '1 day' ";
880
+                } else {
881
+                    $date_qpart = "date_entered < DATE_SUB(NOW(), INTERVAL 1 DAY) ";
882
+                }
883
+                break;
884
+            case "1week":
885
+                if (DB_TYPE == "pgsql") {
886
+                    $date_qpart = "date_entered < NOW() - INTERVAL '1 week' ";
887
+                } else {
888
+                    $date_qpart = "date_entered < DATE_SUB(NOW(), INTERVAL 1 WEEK) ";
889
+                }
890
+                break;
891
+            case "2week":
892
+                if (DB_TYPE == "pgsql") {
893
+                    $date_qpart = "date_entered < NOW() - INTERVAL '2 week' ";
894
+                } else {
895
+                    $date_qpart = "date_entered < DATE_SUB(NOW(), INTERVAL 2 WEEK) ";
896
+                }
897
+                break;
898
+            default:
899
+                $date_qpart = "true";
900
+        }
901
+
902
+        if (is_numeric($feed)) {
903
+            if ($cat_view) {
904
+
905
+                if ($feed >= 0) {
906
+
907
+                    if ($feed > 0) {
908
+                        $children = Feeds::getChildCategories($feed, $owner_uid);
909
+                        array_push($children, $feed);
910
+                        $children = array_map("intval", $children);
911
+
912
+                        $children = join(",", $children);
913
+
914
+                        $cat_qpart = "cat_id IN ($children)";
915
+                    } else {
916
+                        $cat_qpart = "cat_id IS NULL";
917
+                    }
918
+
919
+                    $sth = $pdo->prepare("UPDATE ttrss_user_entries
920 920
 						SET unread = false, last_read = NOW() WHERE ref_id IN
921 921
 							(SELECT id FROM
922 922
 								(SELECT DISTINCT id FROM ttrss_entries, ttrss_user_entries WHERE ref_id = id
923 923
 									AND owner_uid = ? AND unread = true AND feed_id IN
924 924
 										(SELECT id FROM ttrss_feeds WHERE $cat_qpart) AND $date_qpart AND $search_qpart) as tmp)");
925
-					$sth->execute([$owner_uid]);
925
+                    $sth->execute([$owner_uid]);
926 926
 
927
-				} else if ($feed == -2) {
927
+                } else if ($feed == -2) {
928 928
 
929
-					$sth = $pdo->prepare("UPDATE ttrss_user_entries
929
+                    $sth = $pdo->prepare("UPDATE ttrss_user_entries
930 930
 						SET unread = false,last_read = NOW() WHERE (SELECT COUNT(*)
931 931
 							FROM ttrss_user_labels2, ttrss_entries WHERE article_id = ref_id AND id = ref_id AND $date_qpart AND $search_qpart) > 0
932 932
 							AND unread = true AND owner_uid = ?");
933
-					$sth->execute([$owner_uid]);
934
-				}
933
+                    $sth->execute([$owner_uid]);
934
+                }
935 935
 
936
-			} else if ($feed > 0) {
936
+            } else if ($feed > 0) {
937 937
 
938
-				$sth = $pdo->prepare("UPDATE ttrss_user_entries
938
+                $sth = $pdo->prepare("UPDATE ttrss_user_entries
939 939
 					SET unread = false, last_read = NOW() WHERE ref_id IN
940 940
 						(SELECT id FROM
941 941
 							(SELECT DISTINCT id FROM ttrss_entries, ttrss_user_entries WHERE ref_id = id
942 942
 								AND owner_uid = ? AND unread = true AND feed_id = ? AND $date_qpart AND $search_qpart) as tmp)");
943
-				$sth->execute([$owner_uid, $feed]);
943
+                $sth->execute([$owner_uid, $feed]);
944 944
 
945
-			} else if ($feed < 0 && $feed > LABEL_BASE_INDEX) { // special, like starred
945
+            } else if ($feed < 0 && $feed > LABEL_BASE_INDEX) { // special, like starred
946 946
 
947
-				if ($feed == -1) {
948
-					$sth = $pdo->prepare("UPDATE ttrss_user_entries
947
+                if ($feed == -1) {
948
+                    $sth = $pdo->prepare("UPDATE ttrss_user_entries
949 949
 						SET unread = false, last_read = NOW() WHERE ref_id IN
950 950
 							(SELECT id FROM
951 951
 								(SELECT DISTINCT id FROM ttrss_entries, ttrss_user_entries WHERE ref_id = id
952 952
 									AND owner_uid = ? AND unread = true AND marked = true AND $date_qpart AND $search_qpart) as tmp)");
953
-					$sth->execute([$owner_uid]);
954
-				}
953
+                    $sth->execute([$owner_uid]);
954
+                }
955 955
 
956
-				if ($feed == -2) {
957
-					$sth = $pdo->prepare("UPDATE ttrss_user_entries
956
+                if ($feed == -2) {
957
+                    $sth = $pdo->prepare("UPDATE ttrss_user_entries
958 958
 						SET unread = false, last_read = NOW() WHERE ref_id IN
959 959
 							(SELECT id FROM
960 960
 								(SELECT DISTINCT id FROM ttrss_entries, ttrss_user_entries WHERE ref_id = id
961 961
 									AND owner_uid = ? AND unread = true AND published = true AND $date_qpart AND $search_qpart) as tmp)");
962
-					$sth->execute([$owner_uid]);
963
-				}
962
+                    $sth->execute([$owner_uid]);
963
+                }
964 964
 
965
-				if ($feed == -3) {
965
+                if ($feed == -3) {
966 966
 
967
-					$intl = (int) get_pref("FRESH_ARTICLE_MAX_AGE");
967
+                    $intl = (int) get_pref("FRESH_ARTICLE_MAX_AGE");
968 968
 
969
-					if (DB_TYPE == "pgsql") {
970
-						$match_part = "date_entered > NOW() - INTERVAL '$intl hour' ";
971
-					} else {
972
-						$match_part = "date_entered > DATE_SUB(NOW(),
969
+                    if (DB_TYPE == "pgsql") {
970
+                        $match_part = "date_entered > NOW() - INTERVAL '$intl hour' ";
971
+                    } else {
972
+                        $match_part = "date_entered > DATE_SUB(NOW(),
973 973
 							INTERVAL $intl HOUR) ";
974
-					}
974
+                    }
975 975
 
976
-					$sth = $pdo->prepare("UPDATE ttrss_user_entries
976
+                    $sth = $pdo->prepare("UPDATE ttrss_user_entries
977 977
 						SET unread = false, last_read = NOW() WHERE ref_id IN
978 978
 							(SELECT id FROM
979 979
 								(SELECT DISTINCT id FROM ttrss_entries, ttrss_user_entries WHERE ref_id = id
980 980
 									AND owner_uid = ? AND score >= 0 AND unread = true AND $date_qpart AND $match_part AND $search_qpart) as tmp)");
981
-					$sth->execute([$owner_uid]);
982
-				}
981
+                    $sth->execute([$owner_uid]);
982
+                }
983 983
 
984
-				if ($feed == -4) {
985
-					$sth = $pdo->prepare("UPDATE ttrss_user_entries
984
+                if ($feed == -4) {
985
+                    $sth = $pdo->prepare("UPDATE ttrss_user_entries
986 986
 						SET unread = false, last_read = NOW() WHERE ref_id IN
987 987
 							(SELECT id FROM
988 988
 								(SELECT DISTINCT id FROM ttrss_entries, ttrss_user_entries WHERE ref_id = id
989 989
 									AND owner_uid = ? AND unread = true AND $date_qpart AND $search_qpart) as tmp)");
990
-					$sth->execute([$owner_uid]);
991
-				}
990
+                    $sth->execute([$owner_uid]);
991
+                }
992 992
 
993
-			} else if ($feed < LABEL_BASE_INDEX) { // label
993
+            } else if ($feed < LABEL_BASE_INDEX) { // label
994 994
 
995
-				$label_id = Labels::feed_to_label_id($feed);
995
+                $label_id = Labels::feed_to_label_id($feed);
996 996
 
997
-				$sth = $pdo->prepare("UPDATE ttrss_user_entries
997
+                $sth = $pdo->prepare("UPDATE ttrss_user_entries
998 998
 					SET unread = false, last_read = NOW() WHERE ref_id IN
999 999
 						(SELECT id FROM
1000 1000
 							(SELECT DISTINCT ttrss_entries.id FROM ttrss_entries, ttrss_user_entries, ttrss_user_labels2 WHERE ref_id = id
1001 1001
 								AND label_id = ? AND ref_id = article_id
1002 1002
 								AND owner_uid = ? AND unread = true AND $date_qpart AND $search_qpart) as tmp)");
1003
-				$sth->execute([$label_id, $owner_uid]);
1003
+                $sth->execute([$label_id, $owner_uid]);
1004 1004
 
1005
-			}
1005
+            }
1006 1006
 
1007
-			CCache::update($feed, $owner_uid, $cat_view);
1007
+            CCache::update($feed, $owner_uid, $cat_view);
1008 1008
 
1009
-		} else { // tag
1010
-			$sth = $pdo->prepare("UPDATE ttrss_user_entries
1009
+        } else { // tag
1010
+            $sth = $pdo->prepare("UPDATE ttrss_user_entries
1011 1011
 				SET unread = false, last_read = NOW() WHERE ref_id IN
1012 1012
 					(SELECT id FROM
1013 1013
 						(SELECT DISTINCT ttrss_entries.id FROM ttrss_entries, ttrss_user_entries, ttrss_tags WHERE ref_id = ttrss_entries.id
1014 1014
 							AND post_int_id = int_id AND tag_name = ?
1015 1015
 							AND ttrss_user_entries.owner_uid = ? AND unread = true AND $date_qpart AND $search_qpart) as tmp)");
1016
-			$sth->execute([$feed, $owner_uid]);
1016
+            $sth->execute([$feed, $owner_uid]);
1017 1017
 
1018
-		}
1019
-	}
1018
+        }
1019
+    }
1020 1020
 
1021
-	public static function getFeedArticles($feed, $is_cat = false, $unread_only = false,
1022
-							 $owner_uid = false) {
1021
+    public static function getFeedArticles($feed, $is_cat = false, $unread_only = false,
1022
+                                $owner_uid = false) {
1023 1023
 
1024
-		$n_feed = (int) $feed;
1025
-		$need_entries = false;
1024
+        $n_feed = (int) $feed;
1025
+        $need_entries = false;
1026 1026
 
1027
-		$pdo = Db::pdo();
1027
+        $pdo = Db::pdo();
1028 1028
 
1029
-		if (!$owner_uid) $owner_uid = $_SESSION["uid"];
1029
+        if (!$owner_uid) $owner_uid = $_SESSION["uid"];
1030 1030
 
1031
-		if ($unread_only) {
1032
-			$unread_qpart = "unread = true";
1033
-		} else {
1034
-			$unread_qpart = "true";
1035
-		}
1031
+        if ($unread_only) {
1032
+            $unread_qpart = "unread = true";
1033
+        } else {
1034
+            $unread_qpart = "true";
1035
+        }
1036 1036
 
1037
-		$match_part = "";
1037
+        $match_part = "";
1038 1038
 
1039
-		if ($is_cat) {
1040
-			return Feeds::getCategoryUnread($n_feed, $owner_uid);
1041
-		} else if ($n_feed == -6) {
1042
-			return 0;
1043
-		} else if ($feed != "0" && $n_feed == 0) {
1039
+        if ($is_cat) {
1040
+            return Feeds::getCategoryUnread($n_feed, $owner_uid);
1041
+        } else if ($n_feed == -6) {
1042
+            return 0;
1043
+        } else if ($feed != "0" && $n_feed == 0) {
1044 1044
 
1045
-			$sth = $pdo->prepare("SELECT SUM((SELECT COUNT(int_id)
1045
+            $sth = $pdo->prepare("SELECT SUM((SELECT COUNT(int_id)
1046 1046
 				FROM ttrss_user_entries,ttrss_entries WHERE int_id = post_int_id
1047 1047
 					AND ref_id = id AND $unread_qpart)) AS count FROM ttrss_tags
1048 1048
 				WHERE owner_uid = ? AND tag_name = ?");
1049 1049
 
1050
-			$sth->execute([$owner_uid, $feed]);
1051
-			$row = $sth->fetch();
1050
+            $sth->execute([$owner_uid, $feed]);
1051
+            $row = $sth->fetch();
1052 1052
 
1053
-			return $row["count"];
1053
+            return $row["count"];
1054 1054
 
1055
-		} else if ($n_feed == -1) {
1056
-			$match_part = "marked = true";
1057
-		} else if ($n_feed == -2) {
1058
-			$match_part = "published = true";
1059
-		} else if ($n_feed == -3) {
1060
-			$match_part = "unread = true AND score >= 0";
1055
+        } else if ($n_feed == -1) {
1056
+            $match_part = "marked = true";
1057
+        } else if ($n_feed == -2) {
1058
+            $match_part = "published = true";
1059
+        } else if ($n_feed == -3) {
1060
+            $match_part = "unread = true AND score >= 0";
1061 1061
 
1062
-			$intl = (int) get_pref("FRESH_ARTICLE_MAX_AGE", $owner_uid);
1062
+            $intl = (int) get_pref("FRESH_ARTICLE_MAX_AGE", $owner_uid);
1063 1063
 
1064
-			if (DB_TYPE == "pgsql") {
1065
-				$match_part .= " AND date_entered > NOW() - INTERVAL '$intl hour' ";
1066
-			} else {
1067
-				$match_part .= " AND date_entered > DATE_SUB(NOW(), INTERVAL $intl HOUR) ";
1068
-			}
1064
+            if (DB_TYPE == "pgsql") {
1065
+                $match_part .= " AND date_entered > NOW() - INTERVAL '$intl hour' ";
1066
+            } else {
1067
+                $match_part .= " AND date_entered > DATE_SUB(NOW(), INTERVAL $intl HOUR) ";
1068
+            }
1069 1069
 
1070
-			$need_entries = true;
1070
+            $need_entries = true;
1071 1071
 
1072
-		} else if ($n_feed == -4) {
1073
-			$match_part = "true";
1074
-		} else if ($n_feed >= 0) {
1072
+        } else if ($n_feed == -4) {
1073
+            $match_part = "true";
1074
+        } else if ($n_feed >= 0) {
1075 1075
 
1076
-			if ($n_feed != 0) {
1077
-				$match_part = "feed_id = " . (int)$n_feed;
1078
-			} else {
1079
-				$match_part = "feed_id IS NULL";
1080
-			}
1076
+            if ($n_feed != 0) {
1077
+                $match_part = "feed_id = " . (int)$n_feed;
1078
+            } else {
1079
+                $match_part = "feed_id IS NULL";
1080
+            }
1081 1081
 
1082
-		} else if ($feed < LABEL_BASE_INDEX) {
1082
+        } else if ($feed < LABEL_BASE_INDEX) {
1083 1083
 
1084
-			$label_id = Labels::feed_to_label_id($feed);
1084
+            $label_id = Labels::feed_to_label_id($feed);
1085 1085
 
1086
-			return Feeds::getLabelUnread($label_id, $owner_uid);
1087
-		}
1086
+            return Feeds::getLabelUnread($label_id, $owner_uid);
1087
+        }
1088 1088
 
1089
-		if ($match_part) {
1089
+        if ($match_part) {
1090 1090
 
1091
-			if ($need_entries) {
1092
-				$from_qpart = "ttrss_user_entries,ttrss_entries";
1093
-				$from_where = "ttrss_entries.id = ttrss_user_entries.ref_id AND";
1094
-			} else {
1095
-				$from_qpart = "ttrss_user_entries";
1096
-				$from_where = "";
1097
-			}
1091
+            if ($need_entries) {
1092
+                $from_qpart = "ttrss_user_entries,ttrss_entries";
1093
+                $from_where = "ttrss_entries.id = ttrss_user_entries.ref_id AND";
1094
+            } else {
1095
+                $from_qpart = "ttrss_user_entries";
1096
+                $from_where = "";
1097
+            }
1098 1098
 
1099
-			$sth = $pdo->prepare("SELECT count(int_id) AS unread
1099
+            $sth = $pdo->prepare("SELECT count(int_id) AS unread
1100 1100
 				FROM $from_qpart WHERE
1101 1101
 				$unread_qpart AND $from_where ($match_part) AND ttrss_user_entries.owner_uid = ?");
1102
-			$sth->execute([$owner_uid]);
1103
-			$row = $sth->fetch();
1102
+            $sth->execute([$owner_uid]);
1103
+            $row = $sth->fetch();
1104 1104
 
1105
-			return $row["unread"];
1105
+            return $row["unread"];
1106 1106
 
1107
-		} else {
1107
+        } else {
1108 1108
 
1109
-			$sth = $pdo->prepare("SELECT COUNT(post_int_id) AS unread
1109
+            $sth = $pdo->prepare("SELECT COUNT(post_int_id) AS unread
1110 1110
 				FROM ttrss_tags,ttrss_user_entries,ttrss_entries
1111 1111
 				WHERE tag_name = ? AND post_int_id = int_id AND ref_id = ttrss_entries.id
1112 1112
 				AND $unread_qpart AND ttrss_tags.owner_uid = ,");
1113 1113
 
1114
-			$sth->execute([$feed, $owner_uid]);
1115
-			$row = $sth->fetch();
1116
-
1117
-			return $row["unread"];
1118
-		}
1119
-	}
1120
-
1121
-	/**
1122
-	 * @return array (code => Status code, message => error message if available)
1123
-	 *
1124
-	 *                 0 - OK, Feed already exists
1125
-	 *                 1 - OK, Feed added
1126
-	 *                 2 - Invalid URL
1127
-	 *                 3 - URL content is HTML, no feeds available
1128
-	 *                 4 - URL content is HTML which contains multiple feeds.
1129
-	 *                     Here you should call extractfeedurls in rpc-backend
1130
-	 *                     to get all possible feeds.
1131
-	 *                 5 - Couldn't download the URL content.
1132
-	 *                 6 - Content is an invalid XML.
1133
-	 */
1134
-	public static function subscribe_to_feed($url, $cat_id = 0,
1135
-							   $auth_login = '', $auth_pass = '') {
1136
-
1137
-		global $fetch_last_error;
1138
-		global $fetch_last_error_content;
1139
-		global $fetch_last_content_type;
1140
-
1141
-		$pdo = Db::pdo();
1142
-
1143
-		$url = Feeds::fix_url($url);
1144
-
1145
-		if (!$url || !Feeds::validate_feed_url($url)) return array("code" => 2);
1146
-
1147
-		$contents = @fetch_file_contents($url, false, $auth_login, $auth_pass);
1114
+            $sth->execute([$feed, $owner_uid]);
1115
+            $row = $sth->fetch();
1148 1116
 
1149
-		foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_SUBSCRIBE_FEED) as $plugin) {
1150
-			$contents = $plugin->hook_subscribe_feed($contents, $url, $auth_login, $auth_pass);
1151
-		}
1117
+            return $row["unread"];
1118
+        }
1119
+    }
1120
+
1121
+    /**
1122
+     * @return array (code => Status code, message => error message if available)
1123
+     *
1124
+     *                 0 - OK, Feed already exists
1125
+     *                 1 - OK, Feed added
1126
+     *                 2 - Invalid URL
1127
+     *                 3 - URL content is HTML, no feeds available
1128
+     *                 4 - URL content is HTML which contains multiple feeds.
1129
+     *                     Here you should call extractfeedurls in rpc-backend
1130
+     *                     to get all possible feeds.
1131
+     *                 5 - Couldn't download the URL content.
1132
+     *                 6 - Content is an invalid XML.
1133
+     */
1134
+    public static function subscribe_to_feed($url, $cat_id = 0,
1135
+                                $auth_login = '', $auth_pass = '') {
1136
+
1137
+        global $fetch_last_error;
1138
+        global $fetch_last_error_content;
1139
+        global $fetch_last_content_type;
1140
+
1141
+        $pdo = Db::pdo();
1142
+
1143
+        $url = Feeds::fix_url($url);
1144
+
1145
+        if (!$url || !Feeds::validate_feed_url($url)) return array("code" => 2);
1146
+
1147
+        $contents = @fetch_file_contents($url, false, $auth_login, $auth_pass);
1148
+
1149
+        foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_SUBSCRIBE_FEED) as $plugin) {
1150
+            $contents = $plugin->hook_subscribe_feed($contents, $url, $auth_login, $auth_pass);
1151
+        }
1152 1152
 
1153
-		if (!$contents) {
1154
-			if (preg_match("/cloudflare\.com/", $fetch_last_error_content)) {
1155
-				$fetch_last_error .= " (feed behind Cloudflare)";
1156
-			}
1153
+        if (!$contents) {
1154
+            if (preg_match("/cloudflare\.com/", $fetch_last_error_content)) {
1155
+                $fetch_last_error .= " (feed behind Cloudflare)";
1156
+            }
1157 1157
 
1158
-			return array("code" => 5, "message" => $fetch_last_error);
1159
-		}
1158
+            return array("code" => 5, "message" => $fetch_last_error);
1159
+        }
1160 1160
 
1161
-		if (mb_strpos($fetch_last_content_type, "html") !== FALSE && Feeds::is_html($contents)) {
1162
-			$feedUrls = Feeds::get_feeds_from_html($url, $contents);
1161
+        if (mb_strpos($fetch_last_content_type, "html") !== FALSE && Feeds::is_html($contents)) {
1162
+            $feedUrls = Feeds::get_feeds_from_html($url, $contents);
1163 1163
 
1164
-			if (count($feedUrls) == 0) {
1165
-				return array("code" => 3);
1166
-			} else if (count($feedUrls) > 1) {
1167
-				return array("code" => 4, "feeds" => $feedUrls);
1168
-			}
1169
-			//use feed url as new URL
1170
-			$url = key($feedUrls);
1171
-		}
1164
+            if (count($feedUrls) == 0) {
1165
+                return array("code" => 3);
1166
+            } else if (count($feedUrls) > 1) {
1167
+                return array("code" => 4, "feeds" => $feedUrls);
1168
+            }
1169
+            //use feed url as new URL
1170
+            $url = key($feedUrls);
1171
+        }
1172 1172
 
1173
-		if (!$cat_id) $cat_id = null;
1173
+        if (!$cat_id) $cat_id = null;
1174 1174
 
1175
-		$sth = $pdo->prepare("SELECT id FROM ttrss_feeds
1175
+        $sth = $pdo->prepare("SELECT id FROM ttrss_feeds
1176 1176
 			WHERE feed_url = ? AND owner_uid = ?");
1177
-		$sth->execute([$url, $_SESSION['uid']]);
1177
+        $sth->execute([$url, $_SESSION['uid']]);
1178 1178
 
1179
-		if ($row = $sth->fetch()) {
1180
-			return array("code" => 0, "feed_id" => (int) $row["id"]);
1181
-		} else {
1182
-			$sth = $pdo->prepare(
1183
-				"INSERT INTO ttrss_feeds
1179
+        if ($row = $sth->fetch()) {
1180
+            return array("code" => 0, "feed_id" => (int) $row["id"]);
1181
+        } else {
1182
+            $sth = $pdo->prepare(
1183
+                "INSERT INTO ttrss_feeds
1184 1184
 					(owner_uid,feed_url,title,cat_id, auth_login,auth_pass,update_method,auth_pass_encrypted)
1185 1185
 				VALUES (?, ?, ?, ?, ?, ?, 0, false)");
1186 1186
 
1187
-			$sth->execute([$_SESSION['uid'], $url, "[Unknown]", $cat_id, (string)$auth_login, (string)$auth_pass]);
1187
+            $sth->execute([$_SESSION['uid'], $url, "[Unknown]", $cat_id, (string)$auth_login, (string)$auth_pass]);
1188 1188
 
1189
-			$sth = $pdo->prepare("SELECT id FROM ttrss_feeds WHERE feed_url = ?
1189
+            $sth = $pdo->prepare("SELECT id FROM ttrss_feeds WHERE feed_url = ?
1190 1190
 					AND owner_uid = ?");
1191
-			$sth->execute([$url, $_SESSION['uid']]);
1192
-			$row = $sth->fetch();
1193
-
1194
-			$feed_id = $row["id"];
1195
-
1196
-			if ($feed_id) {
1197
-				RSSUtils::set_basic_feed_info($feed_id);
1198
-			}
1199
-
1200
-			return array("code" => 1, "feed_id" => (int) $feed_id);
1201
-
1202
-		}
1203
-	}
1204
-
1205
-	public static function getIconFile($feed_id) {
1206
-		return ICONS_DIR . "/$feed_id.ico";
1207
-	}
1208
-
1209
-	public static function feedHasIcon($id) {
1210
-		return is_file(ICONS_DIR . "/$id.ico") && filesize(ICONS_DIR . "/$id.ico") > 0;
1211
-	}
1212
-
1213
-	public static function getFeedIcon($id) {
1214
-		switch ($id) {
1215
-			case 0:
1216
-				return "archive";
1217
-			case -1:
1218
-				return "star";
1219
-			case -2:
1220
-				return "rss_feed";
1221
-			case -3:
1222
-				return "whatshot";
1223
-			case -4:
1224
-				return "inbox";
1225
-			case -6:
1226
-				return "restore";
1227
-			default:
1228
-				if ($id < LABEL_BASE_INDEX) {
1229
-					return "label";
1230
-				} else {
1231
-					$icon = self::getIconFile($id);
1232
-
1233
-                    if ($icon && file_exists($icon)) {
1234
-						return ICONS_URL . "/" . basename($icon) . "?" . filemtime($icon);
1235
-					}
1236
-				}
1237
-		}
1238
-
1239
-		return false;
1240
-	}
1241
-
1242
-	public static function getFeedTitle($id, $cat = false) {
1243
-	    $pdo = Db::pdo();
1244
-
1245
-		if ($cat) {
1246
-			return Feeds::getCategoryTitle($id);
1247
-		} else if ($id == -1) {
1248
-			return __("Starred articles");
1249
-		} else if ($id == -2) {
1250
-			return __("Published articles");
1251
-		} else if ($id == -3) {
1252
-			return __("Fresh articles");
1253
-		} else if ($id == -4) {
1254
-			return __("All articles");
1255
-		} else if ($id === 0 || $id === "0") {
1256
-			return __("Archived articles");
1257
-		} else if ($id == -6) {
1258
-			return __("Recently read");
1259
-		} else if ($id < LABEL_BASE_INDEX) {
1260
-
1261
-			$label_id = Labels::feed_to_label_id($id);
1191
+            $sth->execute([$url, $_SESSION['uid']]);
1192
+            $row = $sth->fetch();
1262 1193
 
1263
-			$sth = $pdo->prepare("SELECT caption FROM ttrss_labels2 WHERE id = ?");
1264
-			$sth->execute([$label_id]);
1194
+            $feed_id = $row["id"];
1265 1195
 
1266
-			if ($row = $sth->fetch()) {
1267
-				return $row["caption"];
1268
-			} else {
1269
-				return "Unknown label ($label_id)";
1270
-			}
1196
+            if ($feed_id) {
1197
+                RSSUtils::set_basic_feed_info($feed_id);
1198
+            }
1271 1199
 
1272
-		} else if (is_numeric($id) && $id > 0) {
1200
+            return array("code" => 1, "feed_id" => (int) $feed_id);
1273 1201
 
1274
-		    $sth = $pdo->prepare("SELECT title FROM ttrss_feeds WHERE id = ?");
1275
-		    $sth->execute([$id]);
1202
+        }
1203
+    }
1204
+
1205
+    public static function getIconFile($feed_id) {
1206
+        return ICONS_DIR . "/$feed_id.ico";
1207
+    }
1208
+
1209
+    public static function feedHasIcon($id) {
1210
+        return is_file(ICONS_DIR . "/$id.ico") && filesize(ICONS_DIR . "/$id.ico") > 0;
1211
+    }
1212
+
1213
+    public static function getFeedIcon($id) {
1214
+        switch ($id) {
1215
+            case 0:
1216
+                return "archive";
1217
+            case -1:
1218
+                return "star";
1219
+            case -2:
1220
+                return "rss_feed";
1221
+            case -3:
1222
+                return "whatshot";
1223
+            case -4:
1224
+                return "inbox";
1225
+            case -6:
1226
+                return "restore";
1227
+            default:
1228
+                if ($id < LABEL_BASE_INDEX) {
1229
+                    return "label";
1230
+                } else {
1231
+                    $icon = self::getIconFile($id);
1276 1232
 
1277
-		    if ($row = $sth->fetch()) {
1278
-				return $row["title"];
1279
-			} else {
1280
-				return "Unknown feed ($id)";
1281
-			}
1233
+                    if ($icon && file_exists($icon)) {
1234
+                        return ICONS_URL . "/" . basename($icon) . "?" . filemtime($icon);
1235
+                    }
1236
+                }
1237
+        }
1282 1238
 
1283
-		} else {
1284
-			return $id;
1285
-		}
1286
-	}
1239
+        return false;
1240
+    }
1241
+
1242
+    public static function getFeedTitle($id, $cat = false) {
1243
+        $pdo = Db::pdo();
1244
+
1245
+        if ($cat) {
1246
+            return Feeds::getCategoryTitle($id);
1247
+        } else if ($id == -1) {
1248
+            return __("Starred articles");
1249
+        } else if ($id == -2) {
1250
+            return __("Published articles");
1251
+        } else if ($id == -3) {
1252
+            return __("Fresh articles");
1253
+        } else if ($id == -4) {
1254
+            return __("All articles");
1255
+        } else if ($id === 0 || $id === "0") {
1256
+            return __("Archived articles");
1257
+        } else if ($id == -6) {
1258
+            return __("Recently read");
1259
+        } else if ($id < LABEL_BASE_INDEX) {
1260
+
1261
+            $label_id = Labels::feed_to_label_id($id);
1262
+
1263
+            $sth = $pdo->prepare("SELECT caption FROM ttrss_labels2 WHERE id = ?");
1264
+            $sth->execute([$label_id]);
1265
+
1266
+            if ($row = $sth->fetch()) {
1267
+                return $row["caption"];
1268
+            } else {
1269
+                return "Unknown label ($label_id)";
1270
+            }
1271
+
1272
+        } else if (is_numeric($id) && $id > 0) {
1273
+
1274
+            $sth = $pdo->prepare("SELECT title FROM ttrss_feeds WHERE id = ?");
1275
+            $sth->execute([$id]);
1276
+
1277
+            if ($row = $sth->fetch()) {
1278
+                return $row["title"];
1279
+            } else {
1280
+                return "Unknown feed ($id)";
1281
+            }
1282
+
1283
+        } else {
1284
+            return $id;
1285
+        }
1286
+    }
1287 1287
 
1288
-	public static function getCategoryUnread($cat, $owner_uid = false) {
1288
+    public static function getCategoryUnread($cat, $owner_uid = false) {
1289 1289
 
1290
-		if (!$owner_uid) $owner_uid = $_SESSION["uid"];
1290
+        if (!$owner_uid) $owner_uid = $_SESSION["uid"];
1291 1291
 
1292
-		$pdo = Db::pdo();
1292
+        $pdo = Db::pdo();
1293 1293
 
1294
-		if ($cat >= 0) {
1294
+        if ($cat >= 0) {
1295 1295
 
1296
-		    if (!$cat) $cat = null;
1296
+            if (!$cat) $cat = null;
1297 1297
 
1298
-			$sth = $pdo->prepare("SELECT id FROM ttrss_feeds
1298
+            $sth = $pdo->prepare("SELECT id FROM ttrss_feeds
1299 1299
                     WHERE (cat_id = :cat OR (:cat IS NULL AND cat_id IS NULL))
1300 1300
 					AND owner_uid = :uid");
1301 1301
 
1302
-			$sth->execute([":cat" => $cat, ":uid" => $owner_uid]);
1302
+            $sth->execute([":cat" => $cat, ":uid" => $owner_uid]);
1303 1303
 
1304
-			$cat_feeds = array();
1305
-			while ($line = $sth->fetch()) {
1306
-				array_push($cat_feeds, "feed_id = " . (int)$line["id"]);
1307
-			}
1304
+            $cat_feeds = array();
1305
+            while ($line = $sth->fetch()) {
1306
+                array_push($cat_feeds, "feed_id = " . (int)$line["id"]);
1307
+            }
1308 1308
 
1309
-			if (count($cat_feeds) == 0) return 0;
1309
+            if (count($cat_feeds) == 0) return 0;
1310 1310
 
1311
-			$match_part = implode(" OR ", $cat_feeds);
1311
+            $match_part = implode(" OR ", $cat_feeds);
1312 1312
 
1313
-			$sth = $pdo->prepare("SELECT COUNT(int_id) AS unread
1313
+            $sth = $pdo->prepare("SELECT COUNT(int_id) AS unread
1314 1314
 				FROM ttrss_user_entries
1315 1315
 				WHERE	unread = true AND ($match_part)
1316 1316
 				AND owner_uid = ?");
1317
-			$sth->execute([$owner_uid]);
1317
+            $sth->execute([$owner_uid]);
1318 1318
 
1319
-			$unread = 0;
1319
+            $unread = 0;
1320 1320
 
1321
-			# this needs to be rewritten
1322
-			while ($line = $sth->fetch()) {
1323
-				$unread += $line["unread"];
1324
-			}
1321
+            # this needs to be rewritten
1322
+            while ($line = $sth->fetch()) {
1323
+                $unread += $line["unread"];
1324
+            }
1325 1325
 
1326
-			return $unread;
1327
-		} else if ($cat == -1) {
1328
-			return getFeedUnread(-1) + getFeedUnread(-2) + getFeedUnread(-3) + getFeedUnread(0);
1329
-		} else if ($cat == -2) {
1326
+            return $unread;
1327
+        } else if ($cat == -1) {
1328
+            return getFeedUnread(-1) + getFeedUnread(-2) + getFeedUnread(-3) + getFeedUnread(0);
1329
+        } else if ($cat == -2) {
1330 1330
 
1331
-			$sth = $pdo->prepare("SELECT COUNT(unread) AS unread FROM
1331
+            $sth = $pdo->prepare("SELECT COUNT(unread) AS unread FROM
1332 1332
 					ttrss_user_entries, ttrss_user_labels2
1333 1333
 				WHERE article_id = ref_id AND unread = true
1334 1334
 					AND ttrss_user_entries.owner_uid = ?");
1335
-			$sth->execute([$owner_uid]);
1335
+            $sth->execute([$owner_uid]);
1336 1336
             $row = $sth->fetch();
1337 1337
 
1338
-			return $row["unread"];
1339
-		}
1340
-	}
1338
+            return $row["unread"];
1339
+        }
1340
+    }
1341 1341
 
1342
-	// only accepts real cats (>= 0)
1343
-	public static function getCategoryChildrenUnread($cat, $owner_uid = false) {
1344
-		if (!$owner_uid) $owner_uid = $_SESSION["uid"];
1342
+    // only accepts real cats (>= 0)
1343
+    public static function getCategoryChildrenUnread($cat, $owner_uid = false) {
1344
+        if (!$owner_uid) $owner_uid = $_SESSION["uid"];
1345 1345
 
1346
-		$pdo = Db::pdo();
1346
+        $pdo = Db::pdo();
1347 1347
 
1348
-		$sth = $pdo->prepare("SELECT id FROM ttrss_feed_categories WHERE parent_cat = ?
1348
+        $sth = $pdo->prepare("SELECT id FROM ttrss_feed_categories WHERE parent_cat = ?
1349 1349
 				AND owner_uid = ?");
1350
-		$sth->execute([$cat, $owner_uid]);
1350
+        $sth->execute([$cat, $owner_uid]);
1351 1351
 
1352
-		$unread = 0;
1352
+        $unread = 0;
1353 1353
 
1354
-		while ($line = $sth->fetch()) {
1355
-			$unread += Feeds::getCategoryUnread($line["id"], $owner_uid);
1356
-			$unread += Feeds::getCategoryChildrenUnread($line["id"], $owner_uid);
1357
-		}
1354
+        while ($line = $sth->fetch()) {
1355
+            $unread += Feeds::getCategoryUnread($line["id"], $owner_uid);
1356
+            $unread += Feeds::getCategoryChildrenUnread($line["id"], $owner_uid);
1357
+        }
1358 1358
 
1359
-		return $unread;
1360
-	}
1359
+        return $unread;
1360
+    }
1361 1361
 
1362
-	public static function getGlobalUnread($user_id = false) {
1362
+    public static function getGlobalUnread($user_id = false) {
1363 1363
 
1364
-		if (!$user_id) $user_id = $_SESSION["uid"];
1364
+        if (!$user_id) $user_id = $_SESSION["uid"];
1365 1365
 
1366
-		$pdo = Db::pdo();
1366
+        $pdo = Db::pdo();
1367 1367
 
1368
-		$sth = $pdo->prepare("SELECT SUM(value) AS c_id FROM ttrss_counters_cache
1368
+        $sth = $pdo->prepare("SELECT SUM(value) AS c_id FROM ttrss_counters_cache
1369 1369
 			WHERE owner_uid = ? AND feed_id > 0");
1370
-		$sth->execute([$user_id]);
1371
-		$row = $sth->fetch();
1370
+        $sth->execute([$user_id]);
1371
+        $row = $sth->fetch();
1372 1372
 
1373
-		return $row["c_id"];
1374
-	}
1373
+        return $row["c_id"];
1374
+    }
1375 1375
 
1376
-	public static function getCategoryTitle($cat_id) {
1376
+    public static function getCategoryTitle($cat_id) {
1377 1377
 
1378
-		if ($cat_id == -1) {
1379
-			return __("Special");
1380
-		} else if ($cat_id == -2) {
1381
-			return __("Labels");
1382
-		} else {
1378
+        if ($cat_id == -1) {
1379
+            return __("Special");
1380
+        } else if ($cat_id == -2) {
1381
+            return __("Labels");
1382
+        } else {
1383 1383
 
1384
-		    $pdo = Db::pdo();
1384
+            $pdo = Db::pdo();
1385 1385
 
1386
-			$sth = $pdo->prepare("SELECT title FROM ttrss_feed_categories WHERE
1386
+            $sth = $pdo->prepare("SELECT title FROM ttrss_feed_categories WHERE
1387 1387
 				id = ?");
1388
-			$sth->execute([$cat_id]);
1388
+            $sth->execute([$cat_id]);
1389 1389
 
1390
-			if ($row = $sth->fetch()) {
1391
-				return $row["title"];
1392
-			} else {
1393
-				return __("Uncategorized");
1394
-			}
1395
-		}
1396
-	}
1390
+            if ($row = $sth->fetch()) {
1391
+                return $row["title"];
1392
+            } else {
1393
+                return __("Uncategorized");
1394
+            }
1395
+        }
1396
+    }
1397 1397
 
1398
-	public static function getLabelUnread($label_id, $owner_uid = false) {
1399
-		if (!$owner_uid) $owner_uid = $_SESSION["uid"];
1398
+    public static function getLabelUnread($label_id, $owner_uid = false) {
1399
+        if (!$owner_uid) $owner_uid = $_SESSION["uid"];
1400 1400
 
1401
-		$pdo = Db::pdo();
1401
+        $pdo = Db::pdo();
1402 1402
 
1403
-		$sth = $pdo->prepare("SELECT COUNT(ref_id) AS unread FROM ttrss_user_entries, ttrss_user_labels2
1403
+        $sth = $pdo->prepare("SELECT COUNT(ref_id) AS unread FROM ttrss_user_entries, ttrss_user_labels2
1404 1404
 			WHERE owner_uid = ? AND unread = true AND label_id = ? AND article_id = ref_id");
1405 1405
 
1406
-		$sth->execute([$owner_uid, $label_id]);
1406
+        $sth->execute([$owner_uid, $label_id]);
1407 1407
 
1408
-		if ($row = $sth->fetch()) {
1409
-			return $row["unread"];
1410
-		} else {
1411
-			return 0;
1412
-		}
1413
-	}
1408
+        if ($row = $sth->fetch()) {
1409
+            return $row["unread"];
1410
+        } else {
1411
+            return 0;
1412
+        }
1413
+    }
1414 1414
 
1415
-	public static function queryFeedHeadlines($params) {
1415
+    public static function queryFeedHeadlines($params) {
1416 1416
 
1417
-		$pdo = Db::pdo();
1417
+        $pdo = Db::pdo();
1418 1418
 
1419
-		// WARNING: due to highly dynamic nature of this query its going to quote parameters
1419
+        // WARNING: due to highly dynamic nature of this query its going to quote parameters
1420 1420
         // right before adding them to SQL part
1421 1421
 
1422
-		$feed = $params["feed"];
1423
-		$limit = isset($params["limit"]) ? $params["limit"] : 30;
1424
-		$view_mode = $params["view_mode"];
1425
-		$cat_view = isset($params["cat_view"]) ? $params["cat_view"] : false;
1426
-		$search = isset($params["search"]) ? $params["search"] : false;
1427
-		$search_language = isset($params["search_language"]) ? $params["search_language"] : "";
1428
-		$override_order = isset($params["override_order"]) ? $params["override_order"] : false;
1429
-		$offset = isset($params["offset"]) ? $params["offset"] : 0;
1430
-		$owner_uid = isset($params["owner_uid"]) ? $params["owner_uid"] : $_SESSION["uid"];
1431
-		$since_id = isset($params["since_id"]) ? $params["since_id"] : 0;
1432
-		$include_children = isset($params["include_children"]) ? $params["include_children"] : false;
1433
-		$ignore_vfeed_group = isset($params["ignore_vfeed_group"]) ? $params["ignore_vfeed_group"] : false;
1434
-		$override_strategy = isset($params["override_strategy"]) ? $params["override_strategy"] : false;
1435
-		$override_vfeed = isset($params["override_vfeed"]) ? $params["override_vfeed"] : false;
1436
-		$start_ts = isset($params["start_ts"]) ? $params["start_ts"] : false;
1437
-		$check_first_id = isset($params["check_first_id"]) ? $params["check_first_id"] : false;
1438
-		$skip_first_id_check = isset($params["skip_first_id_check"]) ? $params["skip_first_id_check"] : false;
1439
-		//$order_by = isset($params["order_by"]) ? $params["order_by"] : false;
1440
-
1441
-		$ext_tables_part = "";
1442
-		$limit_query_part = "";
1443
-		$query_error_override = "";
1444
-
1445
-		$search_words = [];
1446
-
1447
-		if ($search) {
1448
-			$search_query_part = "";
1449
-
1450
-			foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_SEARCH) as $plugin) {
1451
-				list($search_query_part, $search_words) = $plugin->hook_search($search);
1452
-				break;
1453
-			}
1454
-
1455
-			// fall back in case of no plugins
1456
-			if (!$search_query_part) {
1457
-				list($search_query_part, $search_words) = Feeds::search_to_sql($search, $search_language);
1458
-			}
1459
-
1460
-			if (DB_TYPE == "pgsql") {
1461
-				$test_sth = $pdo->prepare("select $search_query_part
1422
+        $feed = $params["feed"];
1423
+        $limit = isset($params["limit"]) ? $params["limit"] : 30;
1424
+        $view_mode = $params["view_mode"];
1425
+        $cat_view = isset($params["cat_view"]) ? $params["cat_view"] : false;
1426
+        $search = isset($params["search"]) ? $params["search"] : false;
1427
+        $search_language = isset($params["search_language"]) ? $params["search_language"] : "";
1428
+        $override_order = isset($params["override_order"]) ? $params["override_order"] : false;
1429
+        $offset = isset($params["offset"]) ? $params["offset"] : 0;
1430
+        $owner_uid = isset($params["owner_uid"]) ? $params["owner_uid"] : $_SESSION["uid"];
1431
+        $since_id = isset($params["since_id"]) ? $params["since_id"] : 0;
1432
+        $include_children = isset($params["include_children"]) ? $params["include_children"] : false;
1433
+        $ignore_vfeed_group = isset($params["ignore_vfeed_group"]) ? $params["ignore_vfeed_group"] : false;
1434
+        $override_strategy = isset($params["override_strategy"]) ? $params["override_strategy"] : false;
1435
+        $override_vfeed = isset($params["override_vfeed"]) ? $params["override_vfeed"] : false;
1436
+        $start_ts = isset($params["start_ts"]) ? $params["start_ts"] : false;
1437
+        $check_first_id = isset($params["check_first_id"]) ? $params["check_first_id"] : false;
1438
+        $skip_first_id_check = isset($params["skip_first_id_check"]) ? $params["skip_first_id_check"] : false;
1439
+        //$order_by = isset($params["order_by"]) ? $params["order_by"] : false;
1440
+
1441
+        $ext_tables_part = "";
1442
+        $limit_query_part = "";
1443
+        $query_error_override = "";
1444
+
1445
+        $search_words = [];
1446
+
1447
+        if ($search) {
1448
+            $search_query_part = "";
1449
+
1450
+            foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_SEARCH) as $plugin) {
1451
+                list($search_query_part, $search_words) = $plugin->hook_search($search);
1452
+                break;
1453
+            }
1454
+
1455
+            // fall back in case of no plugins
1456
+            if (!$search_query_part) {
1457
+                list($search_query_part, $search_words) = Feeds::search_to_sql($search, $search_language);
1458
+            }
1459
+
1460
+            if (DB_TYPE == "pgsql") {
1461
+                $test_sth = $pdo->prepare("select $search_query_part
1462 1462
 					FROM ttrss_entries, ttrss_user_entries WHERE id = ref_id limit 1");
1463 1463
 
1464
-				try {
1465
-					$test_sth->execute();
1466
-				} catch (PDOException $e) {
1467
-					// looks like tsquery syntax is invalid
1468
-					$search_query_part = "false";
1464
+                try {
1465
+                    $test_sth->execute();
1466
+                } catch (PDOException $e) {
1467
+                    // looks like tsquery syntax is invalid
1468
+                    $search_query_part = "false";
1469 1469
 
1470
-					$query_error_override = T_sprintf("Incorrect search syntax: %s.", implode(" ", $search_words));
1471
-				}
1472
-			}
1470
+                    $query_error_override = T_sprintf("Incorrect search syntax: %s.", implode(" ", $search_words));
1471
+                }
1472
+            }
1473 1473
 
1474
-			$search_query_part .= " AND ";
1475
-		} else {
1476
-			$search_query_part = "";
1477
-		}
1474
+            $search_query_part .= " AND ";
1475
+        } else {
1476
+            $search_query_part = "";
1477
+        }
1478 1478
 
1479
-		if ($since_id) {
1480
-			$since_id_part = "ttrss_entries.id > ".$pdo->quote($since_id)." AND ";
1481
-		} else {
1482
-			$since_id_part = "";
1483
-		}
1479
+        if ($since_id) {
1480
+            $since_id_part = "ttrss_entries.id > ".$pdo->quote($since_id)." AND ";
1481
+        } else {
1482
+            $since_id_part = "";
1483
+        }
1484 1484
 
1485
-		$view_query_part = "";
1485
+        $view_query_part = "";
1486 1486
 
1487
-		if ($view_mode == "adaptive") {
1488
-			if ($search) {
1489
-				$view_query_part = " ";
1490
-			} else if ($feed != -1) {
1487
+        if ($view_mode == "adaptive") {
1488
+            if ($search) {
1489
+                $view_query_part = " ";
1490
+            } else if ($feed != -1) {
1491 1491
 
1492
-				$unread = getFeedUnread($feed, $cat_view);
1492
+                $unread = getFeedUnread($feed, $cat_view);
1493 1493
 
1494
-				if ($cat_view && $feed > 0 && $include_children)
1495
-					$unread += Feeds::getCategoryChildrenUnread($feed);
1494
+                if ($cat_view && $feed > 0 && $include_children)
1495
+                    $unread += Feeds::getCategoryChildrenUnread($feed);
1496 1496
 
1497
-				if ($unread > 0) {
1498
-					$view_query_part = " unread = true AND ";
1499
-				}
1500
-			}
1501
-		}
1497
+                if ($unread > 0) {
1498
+                    $view_query_part = " unread = true AND ";
1499
+                }
1500
+            }
1501
+        }
1502 1502
 
1503
-		if ($view_mode == "marked") {
1504
-			$view_query_part = " marked = true AND ";
1505
-		}
1503
+        if ($view_mode == "marked") {
1504
+            $view_query_part = " marked = true AND ";
1505
+        }
1506 1506
 
1507
-		if ($view_mode == "has_note") {
1508
-			$view_query_part = " (note IS NOT NULL AND note != '') AND ";
1509
-		}
1507
+        if ($view_mode == "has_note") {
1508
+            $view_query_part = " (note IS NOT NULL AND note != '') AND ";
1509
+        }
1510 1510
 
1511
-		if ($view_mode == "published") {
1512
-			$view_query_part = " published = true AND ";
1513
-		}
1511
+        if ($view_mode == "published") {
1512
+            $view_query_part = " published = true AND ";
1513
+        }
1514 1514
 
1515
-		if ($view_mode == "unread" && $feed != -6) {
1516
-			$view_query_part = " unread = true AND ";
1517
-		}
1515
+        if ($view_mode == "unread" && $feed != -6) {
1516
+            $view_query_part = " unread = true AND ";
1517
+        }
1518 1518
 
1519
-		if ($limit > 0) {
1520
-			$limit_query_part = "LIMIT " . (int)$limit;
1521
-		}
1519
+        if ($limit > 0) {
1520
+            $limit_query_part = "LIMIT " . (int)$limit;
1521
+        }
1522 1522
 
1523
-		$allow_archived = false;
1523
+        $allow_archived = false;
1524 1524
 
1525
-		$vfeed_query_part = "";
1525
+        $vfeed_query_part = "";
1526 1526
 
1527
-		/* tags */
1528
-		if (!is_numeric($feed)) {
1529
-			$query_strategy_part = "true";
1530
-			$vfeed_query_part = "(SELECT title FROM ttrss_feeds WHERE
1527
+        /* tags */
1528
+        if (!is_numeric($feed)) {
1529
+            $query_strategy_part = "true";
1530
+            $vfeed_query_part = "(SELECT title FROM ttrss_feeds WHERE
1531 1531
 					id = feed_id) as feed_title,";
1532
-		} else if ($feed > 0) {
1533
-
1534
-			if ($cat_view) {
1535
-
1536
-				if ($feed > 0) {
1537
-					if ($include_children) {
1538
-						# sub-cats
1539
-						$subcats = Feeds::getChildCategories($feed, $owner_uid);
1540
-						array_push($subcats, $feed);
1541
-						$subcats = array_map("intval", $subcats);
1542
-
1543
-						$query_strategy_part = "cat_id IN (".
1544
-							implode(",", $subcats).")";
1545
-
1546
-					} else {
1547
-						$query_strategy_part = "cat_id = " . $pdo->quote($feed);
1548
-					}
1549
-
1550
-				} else {
1551
-					$query_strategy_part = "cat_id IS NULL";
1552
-				}
1532
+        } else if ($feed > 0) {
1553 1533
 
1554
-				$vfeed_query_part = "ttrss_feeds.title AS feed_title,";
1534
+            if ($cat_view) {
1555 1535
 
1556
-			} else {
1557
-				$query_strategy_part = "feed_id = " . $pdo->quote($feed);
1558
-			}
1559
-		} else if ($feed == 0 && !$cat_view) { // archive virtual feed
1560
-			$query_strategy_part = "feed_id IS NULL";
1561
-			$allow_archived = true;
1562
-		} else if ($feed == 0 && $cat_view) { // uncategorized
1563
-			$query_strategy_part = "cat_id IS NULL AND feed_id IS NOT NULL";
1564
-			$vfeed_query_part = "ttrss_feeds.title AS feed_title,";
1565
-		} else if ($feed == -1) { // starred virtual feed
1566
-			$query_strategy_part = "marked = true";
1567
-			$vfeed_query_part = "ttrss_feeds.title AS feed_title,";
1568
-			$allow_archived = true;
1536
+                if ($feed > 0) {
1537
+                    if ($include_children) {
1538
+                        # sub-cats
1539
+                        $subcats = Feeds::getChildCategories($feed, $owner_uid);
1540
+                        array_push($subcats, $feed);
1541
+                        $subcats = array_map("intval", $subcats);
1569 1542
 
1570
-			if (!$override_order) {
1571
-				$override_order = "last_marked DESC, date_entered DESC, updated DESC";
1572
-			}
1543
+                        $query_strategy_part = "cat_id IN (".
1544
+                            implode(",", $subcats).")";
1573 1545
 
1574
-		} else if ($feed == -2) { // published virtual feed OR labels category
1546
+                    } else {
1547
+                        $query_strategy_part = "cat_id = " . $pdo->quote($feed);
1548
+                    }
1575 1549
 
1576
-			if (!$cat_view) {
1577
-				$query_strategy_part = "published = true";
1578
-				$vfeed_query_part = "ttrss_feeds.title AS feed_title,";
1579
-				$allow_archived = true;
1550
+                } else {
1551
+                    $query_strategy_part = "cat_id IS NULL";
1552
+                }
1580 1553
 
1581
-				if (!$override_order) {
1582
-					$override_order = "last_published DESC, date_entered DESC, updated DESC";
1583
-				}
1554
+                $vfeed_query_part = "ttrss_feeds.title AS feed_title,";
1555
+
1556
+            } else {
1557
+                $query_strategy_part = "feed_id = " . $pdo->quote($feed);
1558
+            }
1559
+        } else if ($feed == 0 && !$cat_view) { // archive virtual feed
1560
+            $query_strategy_part = "feed_id IS NULL";
1561
+            $allow_archived = true;
1562
+        } else if ($feed == 0 && $cat_view) { // uncategorized
1563
+            $query_strategy_part = "cat_id IS NULL AND feed_id IS NOT NULL";
1564
+            $vfeed_query_part = "ttrss_feeds.title AS feed_title,";
1565
+        } else if ($feed == -1) { // starred virtual feed
1566
+            $query_strategy_part = "marked = true";
1567
+            $vfeed_query_part = "ttrss_feeds.title AS feed_title,";
1568
+            $allow_archived = true;
1569
+
1570
+            if (!$override_order) {
1571
+                $override_order = "last_marked DESC, date_entered DESC, updated DESC";
1572
+            }
1573
+
1574
+        } else if ($feed == -2) { // published virtual feed OR labels category
1575
+
1576
+            if (!$cat_view) {
1577
+                $query_strategy_part = "published = true";
1578
+                $vfeed_query_part = "ttrss_feeds.title AS feed_title,";
1579
+                $allow_archived = true;
1580
+
1581
+                if (!$override_order) {
1582
+                    $override_order = "last_published DESC, date_entered DESC, updated DESC";
1583
+                }
1584 1584
 
1585
-			} else {
1586
-				$vfeed_query_part = "ttrss_feeds.title AS feed_title,";
1585
+            } else {
1586
+                $vfeed_query_part = "ttrss_feeds.title AS feed_title,";
1587 1587
 
1588
-				$ext_tables_part = "ttrss_labels2,ttrss_user_labels2,";
1588
+                $ext_tables_part = "ttrss_labels2,ttrss_user_labels2,";
1589 1589
 
1590
-				$query_strategy_part = "ttrss_labels2.id = ttrss_user_labels2.label_id AND
1590
+                $query_strategy_part = "ttrss_labels2.id = ttrss_user_labels2.label_id AND
1591 1591
 						ttrss_user_labels2.article_id = ref_id";
1592 1592
 
1593
-			}
1594
-		} else if ($feed == -6) { // recently read
1595
-			$query_strategy_part = "unread = false AND last_read IS NOT NULL";
1593
+            }
1594
+        } else if ($feed == -6) { // recently read
1595
+            $query_strategy_part = "unread = false AND last_read IS NOT NULL";
1596 1596
 
1597
-			if (DB_TYPE == "pgsql") {
1598
-				$query_strategy_part .= " AND last_read > NOW() - INTERVAL '1 DAY' ";
1599
-			} else {
1600
-				$query_strategy_part .= " AND last_read > DATE_SUB(NOW(), INTERVAL 1 DAY) ";
1601
-			}
1597
+            if (DB_TYPE == "pgsql") {
1598
+                $query_strategy_part .= " AND last_read > NOW() - INTERVAL '1 DAY' ";
1599
+            } else {
1600
+                $query_strategy_part .= " AND last_read > DATE_SUB(NOW(), INTERVAL 1 DAY) ";
1601
+            }
1602 1602
 
1603
-			$vfeed_query_part = "ttrss_feeds.title AS feed_title,";
1604
-			$allow_archived = true;
1605
-			$ignore_vfeed_group = true;
1603
+            $vfeed_query_part = "ttrss_feeds.title AS feed_title,";
1604
+            $allow_archived = true;
1605
+            $ignore_vfeed_group = true;
1606 1606
 
1607
-			if (!$override_order) $override_order = "last_read DESC";
1607
+            if (!$override_order) $override_order = "last_read DESC";
1608 1608
 
1609
-		} else if ($feed == -3) { // fresh virtual feed
1610
-			$query_strategy_part = "unread = true AND score >= 0";
1609
+        } else if ($feed == -3) { // fresh virtual feed
1610
+            $query_strategy_part = "unread = true AND score >= 0";
1611 1611
 
1612
-			$intl = (int) get_pref("FRESH_ARTICLE_MAX_AGE", $owner_uid);
1612
+            $intl = (int) get_pref("FRESH_ARTICLE_MAX_AGE", $owner_uid);
1613 1613
 
1614
-			if (DB_TYPE == "pgsql") {
1615
-				$query_strategy_part .= " AND date_entered > NOW() - INTERVAL '$intl hour' ";
1616
-			} else {
1617
-				$query_strategy_part .= " AND date_entered > DATE_SUB(NOW(), INTERVAL $intl HOUR) ";
1618
-			}
1614
+            if (DB_TYPE == "pgsql") {
1615
+                $query_strategy_part .= " AND date_entered > NOW() - INTERVAL '$intl hour' ";
1616
+            } else {
1617
+                $query_strategy_part .= " AND date_entered > DATE_SUB(NOW(), INTERVAL $intl HOUR) ";
1618
+            }
1619 1619
 
1620
-			$vfeed_query_part = "ttrss_feeds.title AS feed_title,";
1621
-		} else if ($feed == -4) { // all articles virtual feed
1622
-			$allow_archived = true;
1623
-			$query_strategy_part = "true";
1624
-			$vfeed_query_part = "ttrss_feeds.title AS feed_title,";
1625
-		} else if ($feed <= LABEL_BASE_INDEX) { // labels
1626
-			$label_id = Labels::feed_to_label_id($feed);
1620
+            $vfeed_query_part = "ttrss_feeds.title AS feed_title,";
1621
+        } else if ($feed == -4) { // all articles virtual feed
1622
+            $allow_archived = true;
1623
+            $query_strategy_part = "true";
1624
+            $vfeed_query_part = "ttrss_feeds.title AS feed_title,";
1625
+        } else if ($feed <= LABEL_BASE_INDEX) { // labels
1626
+            $label_id = Labels::feed_to_label_id($feed);
1627 1627
 
1628
-			$query_strategy_part = "label_id = ".$pdo->quote($label_id)." AND
1628
+            $query_strategy_part = "label_id = ".$pdo->quote($label_id)." AND
1629 1629
 					ttrss_labels2.id = ttrss_user_labels2.label_id AND
1630 1630
 					ttrss_user_labels2.article_id = ref_id";
1631 1631
 
1632
-			$vfeed_query_part = "ttrss_feeds.title AS feed_title,";
1633
-			$ext_tables_part = "ttrss_labels2,ttrss_user_labels2,";
1634
-			$allow_archived = true;
1632
+            $vfeed_query_part = "ttrss_feeds.title AS feed_title,";
1633
+            $ext_tables_part = "ttrss_labels2,ttrss_user_labels2,";
1634
+            $allow_archived = true;
1635 1635
 
1636
-		} else {
1637
-			$query_strategy_part = "true";
1638
-		}
1636
+        } else {
1637
+            $query_strategy_part = "true";
1638
+        }
1639 1639
 
1640
-		$order_by = "score DESC, date_entered DESC, updated DESC";
1640
+        $order_by = "score DESC, date_entered DESC, updated DESC";
1641 1641
 
1642
-		if ($override_order) {
1643
-			$order_by = $override_order;
1644
-		}
1642
+        if ($override_order) {
1643
+            $order_by = $override_order;
1644
+        }
1645 1645
 
1646
-		if ($override_strategy) {
1647
-			$query_strategy_part = $override_strategy;
1648
-		}
1646
+        if ($override_strategy) {
1647
+            $query_strategy_part = $override_strategy;
1648
+        }
1649 1649
 
1650
-		if ($override_vfeed) {
1651
-			$vfeed_query_part = $override_vfeed;
1652
-		}
1650
+        if ($override_vfeed) {
1651
+            $vfeed_query_part = $override_vfeed;
1652
+        }
1653 1653
 
1654
-		if ($search) {
1655
-			$feed_title = T_sprintf("Search results: %s", $search);
1656
-		} else {
1657
-			if ($cat_view) {
1658
-				$feed_title = Feeds::getCategoryTitle($feed);
1659
-			} else {
1660
-				if (is_numeric($feed) && $feed > 0) {
1661
-					$ssth = $pdo->prepare("SELECT title,site_url,last_error,last_updated
1654
+        if ($search) {
1655
+            $feed_title = T_sprintf("Search results: %s", $search);
1656
+        } else {
1657
+            if ($cat_view) {
1658
+                $feed_title = Feeds::getCategoryTitle($feed);
1659
+            } else {
1660
+                if (is_numeric($feed) && $feed > 0) {
1661
+                    $ssth = $pdo->prepare("SELECT title,site_url,last_error,last_updated
1662 1662
 							FROM ttrss_feeds WHERE id = ? AND owner_uid = ?");
1663
-					$ssth->execute([$feed, $owner_uid]);
1663
+                    $ssth->execute([$feed, $owner_uid]);
1664 1664
                     $row = $ssth->fetch();
1665 1665
 
1666
-					$feed_title = $row["title"];
1667
-					$feed_site_url = $row["site_url"];
1668
-					$last_error = $row["last_error"];
1669
-					$last_updated = $row["last_updated"];
1670
-				} else {
1671
-					$feed_title = Feeds::getFeedTitle($feed);
1672
-				}
1673
-			}
1674
-		}
1675
-
1676
-		$content_query_part = "content, ";
1677
-
1678
-		if ($limit_query_part) {
1679
-			$offset_query_part = "OFFSET " . (int)$offset;
1680
-		} else {
1681
-			$offset_query_part = "";
1682
-		}
1683
-
1684
-		if ($start_ts) {
1685
-			$start_ts_formatted = date("Y/m/d H:i:s", strtotime($start_ts));
1686
-			$start_ts_query_part = "date_entered >= '$start_ts_formatted' AND";
1687
-		} else {
1688
-			$start_ts_query_part = "";
1689
-		}
1690
-
1691
-		if (is_numeric($feed)) {
1692
-			// proper override_order applied above
1693
-			if ($vfeed_query_part && !$ignore_vfeed_group && get_pref('VFEED_GROUP_BY_FEED', $owner_uid)) {
1694
-
1695
-				if (!(in_array($feed, Feeds::NEVER_GROUP_BY_DATE) && !$cat_view)) {
1696
-					$yyiw_desc = $order_by == "date_reverse" ? "" : "desc";
1697
-					$yyiw_order_qpart = "yyiw $yyiw_desc, ";
1698
-				} else {
1699
-					$yyiw_order_qpart = "";
1700
-				}
1701
-
1702
-				if (!$override_order) {
1703
-					$order_by = "$yyiw_order_qpart ttrss_feeds.title, $order_by";
1704
-				} else {
1705
-					$order_by = "$yyiw_order_qpart ttrss_feeds.title, $override_order";
1706
-				}
1707
-			}
1708
-
1709
-			if (!$allow_archived) {
1710
-				$from_qpart = "${ext_tables_part}ttrss_entries LEFT JOIN ttrss_user_entries ON (ref_id = ttrss_entries.id),ttrss_feeds";
1711
-				$feed_check_qpart = "ttrss_user_entries.feed_id = ttrss_feeds.id AND";
1712
-
1713
-			} else {
1714
-				$from_qpart = "${ext_tables_part}ttrss_entries LEFT JOIN ttrss_user_entries ON (ref_id = ttrss_entries.id)
1666
+                    $feed_title = $row["title"];
1667
+                    $feed_site_url = $row["site_url"];
1668
+                    $last_error = $row["last_error"];
1669
+                    $last_updated = $row["last_updated"];
1670
+                } else {
1671
+                    $feed_title = Feeds::getFeedTitle($feed);
1672
+                }
1673
+            }
1674
+        }
1675
+
1676
+        $content_query_part = "content, ";
1677
+
1678
+        if ($limit_query_part) {
1679
+            $offset_query_part = "OFFSET " . (int)$offset;
1680
+        } else {
1681
+            $offset_query_part = "";
1682
+        }
1683
+
1684
+        if ($start_ts) {
1685
+            $start_ts_formatted = date("Y/m/d H:i:s", strtotime($start_ts));
1686
+            $start_ts_query_part = "date_entered >= '$start_ts_formatted' AND";
1687
+        } else {
1688
+            $start_ts_query_part = "";
1689
+        }
1690
+
1691
+        if (is_numeric($feed)) {
1692
+            // proper override_order applied above
1693
+            if ($vfeed_query_part && !$ignore_vfeed_group && get_pref('VFEED_GROUP_BY_FEED', $owner_uid)) {
1694
+
1695
+                if (!(in_array($feed, Feeds::NEVER_GROUP_BY_DATE) && !$cat_view)) {
1696
+                    $yyiw_desc = $order_by == "date_reverse" ? "" : "desc";
1697
+                    $yyiw_order_qpart = "yyiw $yyiw_desc, ";
1698
+                } else {
1699
+                    $yyiw_order_qpart = "";
1700
+                }
1701
+
1702
+                if (!$override_order) {
1703
+                    $order_by = "$yyiw_order_qpart ttrss_feeds.title, $order_by";
1704
+                } else {
1705
+                    $order_by = "$yyiw_order_qpart ttrss_feeds.title, $override_order";
1706
+                }
1707
+            }
1708
+
1709
+            if (!$allow_archived) {
1710
+                $from_qpart = "${ext_tables_part}ttrss_entries LEFT JOIN ttrss_user_entries ON (ref_id = ttrss_entries.id),ttrss_feeds";
1711
+                $feed_check_qpart = "ttrss_user_entries.feed_id = ttrss_feeds.id AND";
1712
+
1713
+            } else {
1714
+                $from_qpart = "${ext_tables_part}ttrss_entries LEFT JOIN ttrss_user_entries ON (ref_id = ttrss_entries.id)
1715 1715
 						LEFT JOIN ttrss_feeds ON (feed_id = ttrss_feeds.id)";
1716
-			}
1716
+            }
1717 1717
 
1718
-			if ($vfeed_query_part) $vfeed_query_part .= "favicon_avg_color,";
1718
+            if ($vfeed_query_part) $vfeed_query_part .= "favicon_avg_color,";
1719 1719
 
1720
-			$first_id = 0;
1721
-			$first_id_query_strategy_part = $query_strategy_part;
1720
+            $first_id = 0;
1721
+            $first_id_query_strategy_part = $query_strategy_part;
1722 1722
 
1723
-			if ($feed == -3)
1724
-				$first_id_query_strategy_part = "true";
1723
+            if ($feed == -3)
1724
+                $first_id_query_strategy_part = "true";
1725 1725
 
1726
-			if (DB_TYPE == "pgsql") {
1727
-				$sanity_interval_qpart = "date_entered >= NOW() - INTERVAL '1 hour' AND";
1728
-				$yyiw_qpart = "to_char(date_entered, 'IYYY-IW') AS yyiw";
1729
-			} else {
1730
-				$sanity_interval_qpart = "date_entered >= DATE_SUB(NOW(), INTERVAL 1 hour) AND";
1731
-				$yyiw_qpart = "date_format(date_entered, '%Y-%u') AS yyiw";
1732
-			}
1726
+            if (DB_TYPE == "pgsql") {
1727
+                $sanity_interval_qpart = "date_entered >= NOW() - INTERVAL '1 hour' AND";
1728
+                $yyiw_qpart = "to_char(date_entered, 'IYYY-IW') AS yyiw";
1729
+            } else {
1730
+                $sanity_interval_qpart = "date_entered >= DATE_SUB(NOW(), INTERVAL 1 hour) AND";
1731
+                $yyiw_qpart = "date_format(date_entered, '%Y-%u') AS yyiw";
1732
+            }
1733 1733
 
1734
-			if (!$search && !$skip_first_id_check) {
1735
-				// if previous topmost article id changed that means our current pagination is no longer valid
1736
-				$query = "SELECT DISTINCT
1734
+            if (!$search && !$skip_first_id_check) {
1735
+                // if previous topmost article id changed that means our current pagination is no longer valid
1736
+                $query = "SELECT DISTINCT
1737 1737
 							ttrss_feeds.title,
1738 1738
 							date_entered,
1739 1739
                             $yyiw_qpart,
@@ -1758,22 +1758,22 @@  discard block
 block discarded – undo
1758 1758
 						$sanity_interval_qpart
1759 1759
 						$first_id_query_strategy_part ORDER BY $order_by LIMIT 1";
1760 1760
 
1761
-				/*if ($_REQUEST["debug"]) {
1761
+                /*if ($_REQUEST["debug"]) {
1762 1762
 					print $query;
1763 1763
 				}*/
1764 1764
 
1765
-				$res = $pdo->query($query);
1765
+                $res = $pdo->query($query);
1766 1766
 
1767
-				if ($row = $res->fetch()) {
1768
-					$first_id = (int)$row["id"];
1767
+                if ($row = $res->fetch()) {
1768
+                    $first_id = (int)$row["id"];
1769 1769
 
1770
-					if ($offset > 0 && $first_id && $check_first_id && $first_id != $check_first_id) {
1771
-						return array(-1, $feed_title, $feed_site_url, $last_error, $last_updated, $search_words, $first_id, $vfeed_query_part != "", $query_error_override);
1772
-					}
1773
-				}
1774
-			}
1770
+                    if ($offset > 0 && $first_id && $check_first_id && $first_id != $check_first_id) {
1771
+                        return array(-1, $feed_title, $feed_site_url, $last_error, $last_updated, $search_words, $first_id, $vfeed_query_part != "", $query_error_override);
1772
+                    }
1773
+                }
1774
+            }
1775 1775
 
1776
-			$query = "SELECT DISTINCT
1776
+            $query = "SELECT DISTINCT
1777 1777
 						date_entered,
1778 1778
                         $yyiw_qpart,
1779 1779
 						guid,
@@ -1807,14 +1807,14 @@  discard block
 block discarded – undo
1807 1807
 					$query_strategy_part ORDER BY $order_by
1808 1808
 					$limit_query_part $offset_query_part";
1809 1809
 
1810
-			//if ($_REQUEST["debug"]) print $query;
1810
+            //if ($_REQUEST["debug"]) print $query;
1811 1811
 
1812
-			$res = $pdo->query($query);
1812
+            $res = $pdo->query($query);
1813 1813
 
1814
-		} else {
1815
-			// browsing by tag
1814
+        } else {
1815
+            // browsing by tag
1816 1816
 
1817
-			$query = "SELECT DISTINCT
1817
+            $query = "SELECT DISTINCT
1818 1818
 							date_entered,
1819 1819
 							guid,
1820 1820
 							note,
@@ -1853,63 +1853,63 @@  discard block
 block discarded – undo
1853 1853
 							$query_strategy_part ORDER BY $order_by
1854 1854
 							$limit_query_part $offset_query_part";
1855 1855
 
1856
-			if ($_REQUEST["debug"]) print $query;
1856
+            if ($_REQUEST["debug"]) print $query;
1857 1857
 
1858
-			$res = $pdo->query($query);
1859
-		}
1858
+            $res = $pdo->query($query);
1859
+        }
1860 1860
 
1861
-		return array($res, $feed_title, $feed_site_url, $last_error, $last_updated, $search_words, $first_id, $vfeed_query_part != "", $query_error_override);
1861
+        return array($res, $feed_title, $feed_site_url, $last_error, $last_updated, $search_words, $first_id, $vfeed_query_part != "", $query_error_override);
1862 1862
 
1863
-	}
1863
+    }
1864 1864
 
1865
-	public static function getParentCategories($cat, $owner_uid) {
1866
-		$rv = array();
1865
+    public static function getParentCategories($cat, $owner_uid) {
1866
+        $rv = array();
1867 1867
 
1868
-		$pdo = Db::pdo();
1868
+        $pdo = Db::pdo();
1869 1869
 
1870
-		$sth = $pdo->prepare("SELECT parent_cat FROM ttrss_feed_categories
1870
+        $sth = $pdo->prepare("SELECT parent_cat FROM ttrss_feed_categories
1871 1871
 			WHERE id = ? AND parent_cat IS NOT NULL AND owner_uid = ?");
1872
-		$sth->execute([$cat, $owner_uid]);
1872
+        $sth->execute([$cat, $owner_uid]);
1873 1873
 
1874
-		while ($line = $sth->fetch()) {
1875
-			array_push($rv, $line["parent_cat"]);
1876
-			$rv = array_merge($rv, Feeds::getParentCategories($line["parent_cat"], $owner_uid));
1877
-		}
1874
+        while ($line = $sth->fetch()) {
1875
+            array_push($rv, $line["parent_cat"]);
1876
+            $rv = array_merge($rv, Feeds::getParentCategories($line["parent_cat"], $owner_uid));
1877
+        }
1878 1878
 
1879
-		return $rv;
1880
-	}
1879
+        return $rv;
1880
+    }
1881 1881
 
1882
-	public static function getChildCategories($cat, $owner_uid) {
1883
-		$rv = array();
1882
+    public static function getChildCategories($cat, $owner_uid) {
1883
+        $rv = array();
1884 1884
 
1885
-		$pdo = Db::pdo();
1885
+        $pdo = Db::pdo();
1886 1886
 
1887
-		$sth = $pdo->prepare("SELECT id FROM ttrss_feed_categories
1887
+        $sth = $pdo->prepare("SELECT id FROM ttrss_feed_categories
1888 1888
 			WHERE parent_cat = ? AND owner_uid = ?");
1889
-		$sth->execute([$cat, $owner_uid]);
1889
+        $sth->execute([$cat, $owner_uid]);
1890 1890
 
1891
-		while ($line = $sth->fetch()) {
1892
-			array_push($rv, $line["id"]);
1893
-			$rv = array_merge($rv, Feeds::getChildCategories($line["id"], $owner_uid));
1894
-		}
1891
+        while ($line = $sth->fetch()) {
1892
+            array_push($rv, $line["id"]);
1893
+            $rv = array_merge($rv, Feeds::getChildCategories($line["id"], $owner_uid));
1894
+        }
1895 1895
 
1896
-		return $rv;
1897
-	}
1896
+        return $rv;
1897
+    }
1898 1898
 
1899
-	public static function getFeedCategory($feed) {
1900
-		$pdo = Db::pdo();
1899
+    public static function getFeedCategory($feed) {
1900
+        $pdo = Db::pdo();
1901 1901
 
1902
-	    $sth = $pdo->prepare("SELECT cat_id FROM ttrss_feeds
1902
+        $sth = $pdo->prepare("SELECT cat_id FROM ttrss_feeds
1903 1903
 				WHERE id = ?");
1904
-	    $sth->execute([$feed]);
1904
+        $sth->execute([$feed]);
1905 1905
 
1906
-		if ($row = $sth->fetch()) {
1907
-			return $row["cat_id"];
1908
-		} else {
1909
-			return false;
1910
-		}
1906
+        if ($row = $sth->fetch()) {
1907
+            return $row["cat_id"];
1908
+        } else {
1909
+            return false;
1910
+        }
1911 1911
 
1912
-	}
1912
+    }
1913 1913
 
1914 1914
     function color_of($name) {
1915 1915
         $colormap = [ "#1cd7d7","#d91111","#1212d7","#8e16e5","#7b7b7b",
@@ -1925,402 +1925,402 @@  discard block
 block discarded – undo
1925 1925
         $sum %= count($colormap);
1926 1926
 
1927 1927
         return $colormap[$sum];
1928
-	}
1929
-
1930
-	public static function get_feeds_from_html($url, $content) {
1931
-		$url     = Feeds::fix_url($url);
1932
-		$baseUrl = substr($url, 0, strrpos($url, '/') + 1);
1933
-
1934
-		$feedUrls = [];
1935
-
1936
-		$doc = new DOMDocument();
1937
-		if ($doc->loadHTML($content)) {
1938
-			$xpath = new DOMXPath($doc);
1939
-			$entries = $xpath->query('/html/head/link[@rel="alternate" and '.
1940
-				'(contains(@type,"rss") or contains(@type,"atom"))]|/html/head/link[@rel="feed"]');
1941
-
1942
-			foreach ($entries as $entry) {
1943
-				if ($entry->hasAttribute('href')) {
1944
-					$title = $entry->getAttribute('title');
1945
-					if ($title == '') {
1946
-						$title = $entry->getAttribute('type');
1947
-					}
1948
-					$feedUrl = rewrite_relative_url(
1949
-						$baseUrl, $entry->getAttribute('href')
1950
-					);
1951
-					$feedUrls[$feedUrl] = $title;
1952
-				}
1953
-			}
1954
-		}
1955
-		return $feedUrls;
1956
-	}
1957
-
1958
-	public static function is_html($content) {
1959
-		return preg_match("/<html|DOCTYPE html/i", substr($content, 0, 8192)) !== 0;
1960
-	}
1961
-
1962
-	public static function validate_feed_url($url) {
1963
-		$parts = parse_url($url);
1964
-
1965
-		return ($parts['scheme'] == 'http' || $parts['scheme'] == 'feed' || $parts['scheme'] == 'https');
1966
-	}
1967
-
1968
-	/**
1969
-	 * Fixes incomplete URLs by prepending "http://".
1970
-	 * Also replaces feed:// with http://, and
1971
-	 * prepends a trailing slash if the url is a domain name only.
1972
-	 *
1973
-	 * @param string $url Possibly incomplete URL
1974
-	 *
1975
-	 * @return string Fixed URL.
1976
-	 */
1977
-	public static function fix_url($url) {
1978
-
1979
-		// support schema-less urls
1980
-		if (strpos($url, '//') === 0) {
1981
-			$url = 'https:' . $url;
1982
-		}
1983
-
1984
-		if (strpos($url, '://') === false) {
1985
-			$url = 'http://' . $url;
1986
-		} else if (substr($url, 0, 5) == 'feed:') {
1987
-			$url = 'http:' . substr($url, 5);
1988
-		}
1989
-
1990
-		//prepend slash if the URL has no slash in it
1991
-		// "http://www.example" -> "http://www.example/"
1992
-		if (strpos($url, '/', strpos($url, ':') + 3) === false) {
1993
-			$url .= '/';
1994
-		}
1995
-
1996
-		//convert IDNA hostname to punycode if possible
1997
-		if (function_exists("idn_to_ascii")) {
1998
-			$parts = parse_url($url);
1999
-			if (mb_detect_encoding($parts['host']) != 'ASCII')
2000
-			{
2001
-				$parts['host'] = idn_to_ascii($parts['host']);
2002
-				$url = build_url($parts);
2003
-			}
2004
-		}
2005
-
2006
-		if ($url != "http:///")
2007
-			return $url;
2008
-		else
2009
-			return '';
2010
-	}
2011
-
2012
-	public static function add_feed_category($feed_cat, $parent_cat_id = false, $order_id = 0) {
2013
-
2014
-		if (!$feed_cat) return false;
2015
-
2016
-		$feed_cat = mb_substr($feed_cat, 0, 250);
2017
-		if (!$parent_cat_id) $parent_cat_id = null;
2018
-
2019
-		$pdo = Db::pdo();
2020
-		$tr_in_progress = false;
2021
-
2022
-		try {
2023
-			$pdo->beginTransaction();
2024
-		} catch (Exception $e) {
2025
-			$tr_in_progress = true;
2026
-		}
2027
-
2028
-		$sth = $pdo->prepare("SELECT id FROM ttrss_feed_categories
1928
+    }
1929
+
1930
+    public static function get_feeds_from_html($url, $content) {
1931
+        $url     = Feeds::fix_url($url);
1932
+        $baseUrl = substr($url, 0, strrpos($url, '/') + 1);
1933
+
1934
+        $feedUrls = [];
1935
+
1936
+        $doc = new DOMDocument();
1937
+        if ($doc->loadHTML($content)) {
1938
+            $xpath = new DOMXPath($doc);
1939
+            $entries = $xpath->query('/html/head/link[@rel="alternate" and '.
1940
+                '(contains(@type,"rss") or contains(@type,"atom"))]|/html/head/link[@rel="feed"]');
1941
+
1942
+            foreach ($entries as $entry) {
1943
+                if ($entry->hasAttribute('href')) {
1944
+                    $title = $entry->getAttribute('title');
1945
+                    if ($title == '') {
1946
+                        $title = $entry->getAttribute('type');
1947
+                    }
1948
+                    $feedUrl = rewrite_relative_url(
1949
+                        $baseUrl, $entry->getAttribute('href')
1950
+                    );
1951
+                    $feedUrls[$feedUrl] = $title;
1952
+                }
1953
+            }
1954
+        }
1955
+        return $feedUrls;
1956
+    }
1957
+
1958
+    public static function is_html($content) {
1959
+        return preg_match("/<html|DOCTYPE html/i", substr($content, 0, 8192)) !== 0;
1960
+    }
1961
+
1962
+    public static function validate_feed_url($url) {
1963
+        $parts = parse_url($url);
1964
+
1965
+        return ($parts['scheme'] == 'http' || $parts['scheme'] == 'feed' || $parts['scheme'] == 'https');
1966
+    }
1967
+
1968
+    /**
1969
+     * Fixes incomplete URLs by prepending "http://".
1970
+     * Also replaces feed:// with http://, and
1971
+     * prepends a trailing slash if the url is a domain name only.
1972
+     *
1973
+     * @param string $url Possibly incomplete URL
1974
+     *
1975
+     * @return string Fixed URL.
1976
+     */
1977
+    public static function fix_url($url) {
1978
+
1979
+        // support schema-less urls
1980
+        if (strpos($url, '//') === 0) {
1981
+            $url = 'https:' . $url;
1982
+        }
1983
+
1984
+        if (strpos($url, '://') === false) {
1985
+            $url = 'http://' . $url;
1986
+        } else if (substr($url, 0, 5) == 'feed:') {
1987
+            $url = 'http:' . substr($url, 5);
1988
+        }
1989
+
1990
+        //prepend slash if the URL has no slash in it
1991
+        // "http://www.example" -> "http://www.example/"
1992
+        if (strpos($url, '/', strpos($url, ':') + 3) === false) {
1993
+            $url .= '/';
1994
+        }
1995
+
1996
+        //convert IDNA hostname to punycode if possible
1997
+        if (function_exists("idn_to_ascii")) {
1998
+            $parts = parse_url($url);
1999
+            if (mb_detect_encoding($parts['host']) != 'ASCII')
2000
+            {
2001
+                $parts['host'] = idn_to_ascii($parts['host']);
2002
+                $url = build_url($parts);
2003
+            }
2004
+        }
2005
+
2006
+        if ($url != "http:///")
2007
+            return $url;
2008
+        else
2009
+            return '';
2010
+    }
2011
+
2012
+    public static function add_feed_category($feed_cat, $parent_cat_id = false, $order_id = 0) {
2013
+
2014
+        if (!$feed_cat) return false;
2015
+
2016
+        $feed_cat = mb_substr($feed_cat, 0, 250);
2017
+        if (!$parent_cat_id) $parent_cat_id = null;
2018
+
2019
+        $pdo = Db::pdo();
2020
+        $tr_in_progress = false;
2021
+
2022
+        try {
2023
+            $pdo->beginTransaction();
2024
+        } catch (Exception $e) {
2025
+            $tr_in_progress = true;
2026
+        }
2027
+
2028
+        $sth = $pdo->prepare("SELECT id FROM ttrss_feed_categories
2029 2029
 				WHERE (parent_cat = :parent OR (:parent IS NULL AND parent_cat IS NULL))
2030 2030
 				AND title = :title AND owner_uid = :uid");
2031
-		$sth->execute([':parent' => $parent_cat_id, ':title' => $feed_cat, ':uid' => $_SESSION['uid']]);
2031
+        $sth->execute([':parent' => $parent_cat_id, ':title' => $feed_cat, ':uid' => $_SESSION['uid']]);
2032 2032
 
2033
-		if (!$sth->fetch()) {
2033
+        if (!$sth->fetch()) {
2034 2034
 
2035
-			$sth = $pdo->prepare("INSERT INTO ttrss_feed_categories (owner_uid,title,parent_cat,order_id)
2035
+            $sth = $pdo->prepare("INSERT INTO ttrss_feed_categories (owner_uid,title,parent_cat,order_id)
2036 2036
 					VALUES (?, ?, ?, ?)");
2037
-			$sth->execute([$_SESSION['uid'], $feed_cat, $parent_cat_id, (int)$order_id]);
2037
+            $sth->execute([$_SESSION['uid'], $feed_cat, $parent_cat_id, (int)$order_id]);
2038 2038
 
2039
-			if (!$tr_in_progress) $pdo->commit();
2039
+            if (!$tr_in_progress) $pdo->commit();
2040 2040
 
2041
-			return true;
2042
-		}
2041
+            return true;
2042
+        }
2043 2043
 
2044
-		$pdo->commit();
2044
+        $pdo->commit();
2045 2045
 
2046
-		return false;
2047
-	}
2046
+        return false;
2047
+    }
2048 2048
 
2049
-	public static function get_feed_access_key($feed_id, $is_cat, $owner_uid = false) {
2049
+    public static function get_feed_access_key($feed_id, $is_cat, $owner_uid = false) {
2050 2050
 
2051
-		if (!$owner_uid) $owner_uid = $_SESSION["uid"];
2051
+        if (!$owner_uid) $owner_uid = $_SESSION["uid"];
2052 2052
 
2053
-		$is_cat = bool_to_sql_bool($is_cat);
2053
+        $is_cat = bool_to_sql_bool($is_cat);
2054 2054
 
2055
-		$pdo = Db::pdo();
2055
+        $pdo = Db::pdo();
2056 2056
 
2057
-		$sth = $pdo->prepare("SELECT access_key FROM ttrss_access_keys
2057
+        $sth = $pdo->prepare("SELECT access_key FROM ttrss_access_keys
2058 2058
 				WHERE feed_id = ? AND is_cat = ?
2059 2059
 				AND owner_uid = ?");
2060
-		$sth->execute([$feed_id, $is_cat, $owner_uid]);
2060
+        $sth->execute([$feed_id, $is_cat, $owner_uid]);
2061 2061
 
2062
-		if ($row = $sth->fetch()) {
2063
-			return $row["access_key"];
2064
-		} else {
2065
-			$key = uniqid_short();
2062
+        if ($row = $sth->fetch()) {
2063
+            return $row["access_key"];
2064
+        } else {
2065
+            $key = uniqid_short();
2066 2066
 
2067
-			$sth = $pdo->prepare("INSERT INTO ttrss_access_keys
2067
+            $sth = $pdo->prepare("INSERT INTO ttrss_access_keys
2068 2068
 					(access_key, feed_id, is_cat, owner_uid)
2069 2069
 					VALUES (?, ?, ?, ?)");
2070 2070
 
2071
-			$sth->execute([$key, $feed_id, $is_cat, $owner_uid]);
2071
+            $sth->execute([$key, $feed_id, $is_cat, $owner_uid]);
2072 2072
 
2073
-			return $key;
2074
-		}
2075
-	}
2073
+            return $key;
2074
+        }
2075
+    }
2076 2076
 
2077
-	/**
2078
-	 * Purge a feed old posts.
2079
-	 *
2080
-	 * @param mixed $link A database connection.
2081
-	 * @param mixed $feed_id The id of the purged feed.
2082
-	 * @param mixed $purge_interval Olderness of purged posts.
2083
-	 * @param boolean $debug Set to True to enable the debug. False by default.
2084
-	 * @access public
2085
-	 * @return void
2086
-	 */
2087
-	public static function purge_feed($feed_id, $purge_interval) {
2077
+    /**
2078
+     * Purge a feed old posts.
2079
+     *
2080
+     * @param mixed $link A database connection.
2081
+     * @param mixed $feed_id The id of the purged feed.
2082
+     * @param mixed $purge_interval Olderness of purged posts.
2083
+     * @param boolean $debug Set to True to enable the debug. False by default.
2084
+     * @access public
2085
+     * @return void
2086
+     */
2087
+    public static function purge_feed($feed_id, $purge_interval) {
2088 2088
 
2089
-		if (!$purge_interval) $purge_interval = Feeds::feed_purge_interval($feed_id);
2089
+        if (!$purge_interval) $purge_interval = Feeds::feed_purge_interval($feed_id);
2090 2090
 
2091
-		$pdo = Db::pdo();
2091
+        $pdo = Db::pdo();
2092 2092
 
2093
-		$sth = $pdo->prepare("SELECT owner_uid FROM ttrss_feeds WHERE id = ?");
2094
-		$sth->execute([$feed_id]);
2093
+        $sth = $pdo->prepare("SELECT owner_uid FROM ttrss_feeds WHERE id = ?");
2094
+        $sth->execute([$feed_id]);
2095 2095
 
2096
-		$owner_uid = false;
2096
+        $owner_uid = false;
2097 2097
 
2098
-		if ($row = $sth->fetch()) {
2099
-			$owner_uid = $row["owner_uid"];
2100
-		}
2098
+        if ($row = $sth->fetch()) {
2099
+            $owner_uid = $row["owner_uid"];
2100
+        }
2101 2101
 
2102
-		if ($purge_interval == -1 || !$purge_interval) {
2103
-			if ($owner_uid) {
2104
-				CCache::update($feed_id, $owner_uid);
2105
-			}
2106
-			return;
2107
-		}
2102
+        if ($purge_interval == -1 || !$purge_interval) {
2103
+            if ($owner_uid) {
2104
+                CCache::update($feed_id, $owner_uid);
2105
+            }
2106
+            return;
2107
+        }
2108 2108
 
2109
-		if (!$owner_uid) return;
2109
+        if (!$owner_uid) return;
2110 2110
 
2111
-		if (FORCE_ARTICLE_PURGE == 0) {
2112
-			$purge_unread = get_pref("PURGE_UNREAD_ARTICLES",
2113
-				$owner_uid, false);
2114
-		} else {
2115
-			$purge_unread = true;
2116
-			$purge_interval = FORCE_ARTICLE_PURGE;
2117
-		}
2111
+        if (FORCE_ARTICLE_PURGE == 0) {
2112
+            $purge_unread = get_pref("PURGE_UNREAD_ARTICLES",
2113
+                $owner_uid, false);
2114
+        } else {
2115
+            $purge_unread = true;
2116
+            $purge_interval = FORCE_ARTICLE_PURGE;
2117
+        }
2118 2118
 
2119
-		if (!$purge_unread)
2120
-			$query_limit = " unread = false AND ";
2121
-		else
2122
-			$query_limit = "";
2119
+        if (!$purge_unread)
2120
+            $query_limit = " unread = false AND ";
2121
+        else
2122
+            $query_limit = "";
2123 2123
 
2124
-		$purge_interval = (int) $purge_interval;
2124
+        $purge_interval = (int) $purge_interval;
2125 2125
 
2126
-		if (DB_TYPE == "pgsql") {
2127
-			$sth = $pdo->prepare("DELETE FROM ttrss_user_entries
2126
+        if (DB_TYPE == "pgsql") {
2127
+            $sth = $pdo->prepare("DELETE FROM ttrss_user_entries
2128 2128
 				USING ttrss_entries
2129 2129
 				WHERE ttrss_entries.id = ref_id AND
2130 2130
 				marked = false AND
2131 2131
 				feed_id = ? AND
2132 2132
 				$query_limit
2133 2133
 				ttrss_entries.date_updated < NOW() - INTERVAL '$purge_interval days'");
2134
-			$sth->execute([$feed_id]);
2134
+            $sth->execute([$feed_id]);
2135 2135
 
2136
-		} else {
2137
-			$sth  = $pdo->prepare("DELETE FROM ttrss_user_entries
2136
+        } else {
2137
+            $sth  = $pdo->prepare("DELETE FROM ttrss_user_entries
2138 2138
 				USING ttrss_user_entries, ttrss_entries
2139 2139
 				WHERE ttrss_entries.id = ref_id AND
2140 2140
 				marked = false AND
2141 2141
 				feed_id = ? AND
2142 2142
 				$query_limit
2143 2143
 				ttrss_entries.date_updated < DATE_SUB(NOW(), INTERVAL $purge_interval DAY)");
2144
-			$sth->execute([$feed_id]);
2144
+            $sth->execute([$feed_id]);
2145 2145
 
2146
-		}
2146
+        }
2147 2147
 
2148
-		$rows = $sth->rowCount();
2148
+        $rows = $sth->rowCount();
2149 2149
 
2150
-		CCache::update($feed_id, $owner_uid);
2150
+        CCache::update($feed_id, $owner_uid);
2151 2151
 
2152
-		Debug::log("Purged feed $feed_id ($purge_interval): deleted $rows articles");
2152
+        Debug::log("Purged feed $feed_id ($purge_interval): deleted $rows articles");
2153 2153
 
2154
-		return $rows;
2155
-	}
2154
+        return $rows;
2155
+    }
2156 2156
 
2157
-	public static function feed_purge_interval($feed_id) {
2157
+    public static function feed_purge_interval($feed_id) {
2158 2158
 
2159
-		$pdo = DB::pdo();
2159
+        $pdo = DB::pdo();
2160 2160
 
2161
-		$sth = $pdo->prepare("SELECT purge_interval, owner_uid FROM ttrss_feeds
2161
+        $sth = $pdo->prepare("SELECT purge_interval, owner_uid FROM ttrss_feeds
2162 2162
 			WHERE id = ?");
2163
-		$sth->execute([$feed_id]);
2164
-
2165
-		if ($row = $sth->fetch()) {
2166
-			$purge_interval = $row["purge_interval"];
2167
-			$owner_uid = $row["owner_uid"];
2168
-
2169
-			if ($purge_interval == 0) $purge_interval = get_pref(
2170
-				'PURGE_OLD_DAYS', $owner_uid);
2171
-
2172
-			return $purge_interval;
2173
-
2174
-		} else {
2175
-			return -1;
2176
-		}
2177
-	}
2163
+        $sth->execute([$feed_id]);
2178 2164
 
2179
-	public static function search_to_sql($search, $search_language) {
2165
+        if ($row = $sth->fetch()) {
2166
+            $purge_interval = $row["purge_interval"];
2167
+            $owner_uid = $row["owner_uid"];
2180 2168
 
2181
-		$keywords = str_getcsv(trim($search), " ");
2182
-		$query_keywords = array();
2183
-		$search_words = array();
2184
-		$search_query_leftover = array();
2169
+            if ($purge_interval == 0) $purge_interval = get_pref(
2170
+                'PURGE_OLD_DAYS', $owner_uid);
2185 2171
 
2186
-		$pdo = Db::pdo();
2172
+            return $purge_interval;
2187 2173
 
2188
-		if ($search_language)
2189
-			$search_language = $pdo->quote(mb_strtolower($search_language));
2190
-		else
2191
-			$search_language = $pdo->quote("english");
2192
-
2193
-		foreach ($keywords as $k) {
2194
-			if (strpos($k, "-") === 0) {
2195
-				$k = substr($k, 1);
2196
-				$not = "NOT";
2197
-			} else {
2198
-				$not = "";
2199
-			}
2200
-
2201
-			$commandpair = explode(":", mb_strtolower($k), 2);
2202
-
2203
-			switch ($commandpair[0]) {
2204
-				case "title":
2205
-					if ($commandpair[1]) {
2206
-						array_push($query_keywords, "($not (LOWER(ttrss_entries.title) LIKE ".
2207
-							$pdo->quote('%' . mb_strtolower($commandpair[1]) . '%') ."))");
2208
-					} else {
2209
-						array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER('%$k%')
2174
+        } else {
2175
+            return -1;
2176
+        }
2177
+    }
2178
+
2179
+    public static function search_to_sql($search, $search_language) {
2180
+
2181
+        $keywords = str_getcsv(trim($search), " ");
2182
+        $query_keywords = array();
2183
+        $search_words = array();
2184
+        $search_query_leftover = array();
2185
+
2186
+        $pdo = Db::pdo();
2187
+
2188
+        if ($search_language)
2189
+            $search_language = $pdo->quote(mb_strtolower($search_language));
2190
+        else
2191
+            $search_language = $pdo->quote("english");
2192
+
2193
+        foreach ($keywords as $k) {
2194
+            if (strpos($k, "-") === 0) {
2195
+                $k = substr($k, 1);
2196
+                $not = "NOT";
2197
+            } else {
2198
+                $not = "";
2199
+            }
2200
+
2201
+            $commandpair = explode(":", mb_strtolower($k), 2);
2202
+
2203
+            switch ($commandpair[0]) {
2204
+                case "title":
2205
+                    if ($commandpair[1]) {
2206
+                        array_push($query_keywords, "($not (LOWER(ttrss_entries.title) LIKE ".
2207
+                            $pdo->quote('%' . mb_strtolower($commandpair[1]) . '%') ."))");
2208
+                    } else {
2209
+                        array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER('%$k%')
2210 2210
 								OR UPPER(ttrss_entries.content) $not LIKE UPPER(".$pdo->quote("%$k%")."))");
2211
-						array_push($search_words, $k);
2212
-					}
2213
-					break;
2214
-				case "author":
2215
-					if ($commandpair[1]) {
2216
-						array_push($query_keywords, "($not (LOWER(author) LIKE ".
2217
-							$pdo->quote('%' . mb_strtolower($commandpair[1]) . '%')."))");
2218
-					} else {
2219
-						array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER('%$k%')
2211
+                        array_push($search_words, $k);
2212
+                    }
2213
+                    break;
2214
+                case "author":
2215
+                    if ($commandpair[1]) {
2216
+                        array_push($query_keywords, "($not (LOWER(author) LIKE ".
2217
+                            $pdo->quote('%' . mb_strtolower($commandpair[1]) . '%')."))");
2218
+                    } else {
2219
+                        array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER('%$k%')
2220 2220
 								OR UPPER(ttrss_entries.content) $not LIKE UPPER(".$pdo->quote("%$k%")."))");
2221
-						array_push($search_words, $k);
2222
-					}
2223
-					break;
2224
-				case "note":
2225
-					if ($commandpair[1]) {
2226
-						if ($commandpair[1] == "true")
2227
-							array_push($query_keywords, "($not (note IS NOT NULL AND note != ''))");
2228
-						else if ($commandpair[1] == "false")
2229
-							array_push($query_keywords, "($not (note IS NULL OR note = ''))");
2230
-						else
2231
-							array_push($query_keywords, "($not (LOWER(note) LIKE ".
2232
-								$pdo->quote('%' . mb_strtolower($commandpair[1]) . '%')."))");
2233
-					} else {
2234
-						array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER(".$pdo->quote("%$k%").")
2221
+                        array_push($search_words, $k);
2222
+                    }
2223
+                    break;
2224
+                case "note":
2225
+                    if ($commandpair[1]) {
2226
+                        if ($commandpair[1] == "true")
2227
+                            array_push($query_keywords, "($not (note IS NOT NULL AND note != ''))");
2228
+                        else if ($commandpair[1] == "false")
2229
+                            array_push($query_keywords, "($not (note IS NULL OR note = ''))");
2230
+                        else
2231
+                            array_push($query_keywords, "($not (LOWER(note) LIKE ".
2232
+                                $pdo->quote('%' . mb_strtolower($commandpair[1]) . '%')."))");
2233
+                    } else {
2234
+                        array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER(".$pdo->quote("%$k%").")
2235 2235
 								OR UPPER(ttrss_entries.content) $not LIKE UPPER(".$pdo->quote("%$k%")."))");
2236
-						if (!$not) array_push($search_words, $k);
2237
-					}
2238
-					break;
2239
-				case "star":
2240
-
2241
-					if ($commandpair[1]) {
2242
-						if ($commandpair[1] == "true")
2243
-							array_push($query_keywords, "($not (marked = true))");
2244
-						else
2245
-							array_push($query_keywords, "($not (marked = false))");
2246
-					} else {
2247
-						array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER(".$pdo->quote("%$k%").")
2236
+                        if (!$not) array_push($search_words, $k);
2237
+                    }
2238
+                    break;
2239
+                case "star":
2240
+
2241
+                    if ($commandpair[1]) {
2242
+                        if ($commandpair[1] == "true")
2243
+                            array_push($query_keywords, "($not (marked = true))");
2244
+                        else
2245
+                            array_push($query_keywords, "($not (marked = false))");
2246
+                    } else {
2247
+                        array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER(".$pdo->quote("%$k%").")
2248 2248
 								OR UPPER(ttrss_entries.content) $not LIKE UPPER(".$pdo->quote("%$k%")."))");
2249
-						if (!$not) array_push($search_words, $k);
2250
-					}
2251
-					break;
2252
-				case "pub":
2253
-					if ($commandpair[1]) {
2254
-						if ($commandpair[1] == "true")
2255
-							array_push($query_keywords, "($not (published = true))");
2256
-						else
2257
-							array_push($query_keywords, "($not (published = false))");
2258
-
2259
-					} else {
2260
-						array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER('%$k%')
2249
+                        if (!$not) array_push($search_words, $k);
2250
+                    }
2251
+                    break;
2252
+                case "pub":
2253
+                    if ($commandpair[1]) {
2254
+                        if ($commandpair[1] == "true")
2255
+                            array_push($query_keywords, "($not (published = true))");
2256
+                        else
2257
+                            array_push($query_keywords, "($not (published = false))");
2258
+
2259
+                    } else {
2260
+                        array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER('%$k%')
2261 2261
 								OR UPPER(ttrss_entries.content) $not LIKE UPPER(".$pdo->quote("%$k%")."))");
2262
-						if (!$not) array_push($search_words, $k);
2263
-					}
2264
-					break;
2265
-				case "unread":
2266
-					if ($commandpair[1]) {
2267
-						if ($commandpair[1] == "true")
2268
-							array_push($query_keywords, "($not (unread = true))");
2269
-						else
2270
-							array_push($query_keywords, "($not (unread = false))");
2271
-
2272
-					} else {
2273
-						array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER(".$pdo->quote("%$k%").")
2262
+                        if (!$not) array_push($search_words, $k);
2263
+                    }
2264
+                    break;
2265
+                case "unread":
2266
+                    if ($commandpair[1]) {
2267
+                        if ($commandpair[1] == "true")
2268
+                            array_push($query_keywords, "($not (unread = true))");
2269
+                        else
2270
+                            array_push($query_keywords, "($not (unread = false))");
2271
+
2272
+                    } else {
2273
+                        array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER(".$pdo->quote("%$k%").")
2274 2274
 								OR UPPER(ttrss_entries.content) $not LIKE UPPER(".$pdo->quote("%$k%")."))");
2275
-						if (!$not) array_push($search_words, $k);
2276
-					}
2277
-					break;
2278
-				default:
2279
-					if (strpos($k, "@") === 0) {
2280
-
2281
-						$user_tz_string = get_pref('USER_TIMEZONE', $_SESSION['uid']);
2282
-						$orig_ts = strtotime(substr($k, 1));
2283
-						$k = date("Y-m-d", convert_timestamp($orig_ts, $user_tz_string, 'UTC'));
2284
-
2285
-						//$k = date("Y-m-d", strtotime(substr($k, 1)));
2286
-
2287
-						array_push($query_keywords, "(".SUBSTRING_FOR_DATE."(updated,1,LENGTH('$k')) $not = '$k')");
2288
-					} else {
2289
-
2290
-						if (DB_TYPE == "pgsql") {
2291
-							$k = mb_strtolower($k);
2292
-							array_push($search_query_leftover, $not ? "!$k" : $k);
2293
-						} else {
2294
-							array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER(".$pdo->quote("%$k%").")
2275
+                        if (!$not) array_push($search_words, $k);
2276
+                    }
2277
+                    break;
2278
+                default:
2279
+                    if (strpos($k, "@") === 0) {
2280
+
2281
+                        $user_tz_string = get_pref('USER_TIMEZONE', $_SESSION['uid']);
2282
+                        $orig_ts = strtotime(substr($k, 1));
2283
+                        $k = date("Y-m-d", convert_timestamp($orig_ts, $user_tz_string, 'UTC'));
2284
+
2285
+                        //$k = date("Y-m-d", strtotime(substr($k, 1)));
2286
+
2287
+                        array_push($query_keywords, "(".SUBSTRING_FOR_DATE."(updated,1,LENGTH('$k')) $not = '$k')");
2288
+                    } else {
2289
+
2290
+                        if (DB_TYPE == "pgsql") {
2291
+                            $k = mb_strtolower($k);
2292
+                            array_push($search_query_leftover, $not ? "!$k" : $k);
2293
+                        } else {
2294
+                            array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER(".$pdo->quote("%$k%").")
2295 2295
 								OR UPPER(ttrss_entries.content) $not LIKE UPPER(".$pdo->quote("%$k%")."))");
2296
-						}
2296
+                        }
2297 2297
 
2298
-						if (!$not) array_push($search_words, $k);
2299
-					}
2300
-			}
2301
-		}
2298
+                        if (!$not) array_push($search_words, $k);
2299
+                    }
2300
+            }
2301
+        }
2302 2302
 
2303
-		if (count($search_query_leftover) > 0) {
2303
+        if (count($search_query_leftover) > 0) {
2304 2304
 
2305
-			if (DB_TYPE == "pgsql") {
2305
+            if (DB_TYPE == "pgsql") {
2306 2306
 
2307
-				// if there's no joiners consider this a "simple" search and
2308
-				// concatenate everything with &, otherwise don't try to mess with tsquery syntax
2309
-				if (preg_match("/[&|]/", implode(" " , $search_query_leftover))) {
2310
-					$tsquery = $pdo->quote(implode(" ", $search_query_leftover));
2311
-				} else {
2312
-					$tsquery = $pdo->quote(implode(" & ", $search_query_leftover));
2313
-				}
2307
+                // if there's no joiners consider this a "simple" search and
2308
+                // concatenate everything with &, otherwise don't try to mess with tsquery syntax
2309
+                if (preg_match("/[&|]/", implode(" " , $search_query_leftover))) {
2310
+                    $tsquery = $pdo->quote(implode(" ", $search_query_leftover));
2311
+                } else {
2312
+                    $tsquery = $pdo->quote(implode(" & ", $search_query_leftover));
2313
+                }
2314 2314
 
2315
-				array_push($query_keywords,
2316
-					"(tsvector_combined @@ to_tsquery($search_language, $tsquery))");
2317
-			}
2315
+                array_push($query_keywords,
2316
+                    "(tsvector_combined @@ to_tsquery($search_language, $tsquery))");
2317
+            }
2318 2318
 
2319
-		}
2319
+        }
2320 2320
 
2321
-		$search_query_part = implode("AND", $query_keywords);
2321
+        $search_query_part = implode("AND", $query_keywords);
2322 2322
 
2323
-		return array($search_query_part, $search_words);
2324
-	}
2323
+        return array($search_query_part, $search_words);
2324
+    }
2325 2325
 }
2326 2326
 
Please login to merge, or discard this patch.
classes/pluginhandler.php 1 patch
Indentation   +18 added lines, -18 removed lines patch added patch discarded remove patch
@@ -1,23 +1,23 @@
 block discarded – undo
1 1
 <?php
2 2
 class PluginHandler extends Handler_Protected {
3
-	public function csrf_ignore($method) {
4
-		return true;
5
-	}
3
+    public function csrf_ignore($method) {
4
+        return true;
5
+    }
6 6
 
7
-	public function catchall($method) {
8
-		$plugin_name = clean($_REQUEST["plugin"]);
9
-		$plugin = PluginHost::getInstance()->get_plugin($plugin_name);
7
+    public function catchall($method) {
8
+        $plugin_name = clean($_REQUEST["plugin"]);
9
+        $plugin = PluginHost::getInstance()->get_plugin($plugin_name);
10 10
 
11
-		if ($plugin) {
12
-			if (method_exists($plugin, $method)) {
13
-				$plugin->$method();
14
-			} else {
15
-				user_error("PluginHandler: Requested unknown method '$method' of plugin '$plugin_name'.", E_USER_WARNING);
16
-				print error_json(13);
17
-			}
18
-		} else {
19
-			user_error("PluginHandler: Requested method '$method' of unknown plugin '$plugin_name'.", E_USER_WARNING);
20
-			print error_json(14);
21
-		}
22
-	}
11
+        if ($plugin) {
12
+            if (method_exists($plugin, $method)) {
13
+                $plugin->$method();
14
+            } else {
15
+                user_error("PluginHandler: Requested unknown method '$method' of plugin '$plugin_name'.", E_USER_WARNING);
16
+                print error_json(13);
17
+            }
18
+        } else {
19
+            user_error("PluginHandler: Requested method '$method' of unknown plugin '$plugin_name'.", E_USER_WARNING);
20
+            print error_json(14);
21
+        }
22
+    }
23 23
 }
Please login to merge, or discard this patch.
classes/db.php 1 patch
Indentation   +82 added lines, -82 removed lines patch added patch discarded remove patch
@@ -2,115 +2,115 @@
 block discarded – undo
2 2
 class Db
3 3
 {
4 4
 
5
-	/* @var Db $instance */
6
-	private static $instance;
5
+    /* @var Db $instance */
6
+    private static $instance;
7 7
 
8
-	/* @var IDb $adapter */
9
-	private $adapter;
8
+    /* @var IDb $adapter */
9
+    private $adapter;
10 10
 
11
-	private $link;
11
+    private $link;
12 12
 
13
-	/* @var PDO $pdo */
14
-	private $pdo;
13
+    /* @var PDO $pdo */
14
+    private $pdo;
15 15
 
16
-	private function __clone() {
17
-		//
18
-	}
16
+    private function __clone() {
17
+        //
18
+    }
19 19
 
20
-	private function legacy_connect() {
20
+    private function legacy_connect() {
21 21
 
22
-		user_error("Legacy connect requested to " . DB_TYPE, E_USER_NOTICE);
22
+        user_error("Legacy connect requested to " . DB_TYPE, E_USER_NOTICE);
23 23
 
24
-		$er = error_reporting(E_ALL);
24
+        $er = error_reporting(E_ALL);
25 25
 
26
-		switch (DB_TYPE) {
27
-			case "mysql":
28
-				$this->adapter = new Db_Mysqli();
29
-				break;
30
-			case "pgsql":
31
-				$this->adapter = new Db_Pgsql();
32
-				break;
33
-			default:
34
-				die("Unknown DB_TYPE: " . DB_TYPE);
35
-		}
26
+        switch (DB_TYPE) {
27
+            case "mysql":
28
+                $this->adapter = new Db_Mysqli();
29
+                break;
30
+            case "pgsql":
31
+                $this->adapter = new Db_Pgsql();
32
+                break;
33
+            default:
34
+                die("Unknown DB_TYPE: " . DB_TYPE);
35
+        }
36 36
 
37
-		if (!$this->adapter) {
38
-			print("Error initializing database adapter for " . DB_TYPE);
39
-			exit(100);
40
-		}
37
+        if (!$this->adapter) {
38
+            print("Error initializing database adapter for " . DB_TYPE);
39
+            exit(100);
40
+        }
41 41
 
42
-		$this->link = $this->adapter->connect(DB_HOST, DB_USER, DB_PASS, DB_NAME, defined('DB_PORT') ? DB_PORT : "");
42
+        $this->link = $this->adapter->connect(DB_HOST, DB_USER, DB_PASS, DB_NAME, defined('DB_PORT') ? DB_PORT : "");
43 43
 
44
-		if (!$this->link) {
45
-			print("Error connecting through adapter: " . $this->adapter->last_error());
46
-			exit(101);
47
-		}
44
+        if (!$this->link) {
45
+            print("Error connecting through adapter: " . $this->adapter->last_error());
46
+            exit(101);
47
+        }
48 48
 
49
-		error_reporting($er);
50
-	}
49
+        error_reporting($er);
50
+    }
51 51
 
52
-	// this really shouldn't be used unless a separate PDO connection is needed
53
-	// normal usage is Db::pdo()->prepare(...) etc
54
-	public function pdo_connect() {
52
+    // this really shouldn't be used unless a separate PDO connection is needed
53
+    // normal usage is Db::pdo()->prepare(...) etc
54
+    public function pdo_connect() {
55 55
 
56
-		$db_port = defined('DB_PORT') && DB_PORT ? ';port=' . DB_PORT : '';
57
-		$db_host = defined('DB_HOST') && DB_HOST ? ';host=' . DB_HOST : '';
56
+        $db_port = defined('DB_PORT') && DB_PORT ? ';port=' . DB_PORT : '';
57
+        $db_host = defined('DB_HOST') && DB_HOST ? ';host=' . DB_HOST : '';
58 58
 
59
-		try {
60
-			$pdo = new PDO(DB_TYPE . ':dbname=' . DB_NAME . $db_host . $db_port,
61
-				DB_USER,
62
-				DB_PASS);
63
-		} catch (Exception $e) {
64
-			print "<pre>Exception while creating PDO object:" . $e->getMessage() . "</pre>";
65
-			exit(101);
66
-		}
59
+        try {
60
+            $pdo = new PDO(DB_TYPE . ':dbname=' . DB_NAME . $db_host . $db_port,
61
+                DB_USER,
62
+                DB_PASS);
63
+        } catch (Exception $e) {
64
+            print "<pre>Exception while creating PDO object:" . $e->getMessage() . "</pre>";
65
+            exit(101);
66
+        }
67 67
 
68
-		$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
68
+        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
69 69
 
70
-		if (DB_TYPE == "pgsql") {
70
+        if (DB_TYPE == "pgsql") {
71 71
 
72
-			$pdo->query("set client_encoding = 'UTF-8'");
73
-			$pdo->query("set datestyle = 'ISO, european'");
74
-			$pdo->query("set TIME ZONE 0");
75
-			$pdo->query("set cpu_tuple_cost = 0.5");
72
+            $pdo->query("set client_encoding = 'UTF-8'");
73
+            $pdo->query("set datestyle = 'ISO, european'");
74
+            $pdo->query("set TIME ZONE 0");
75
+            $pdo->query("set cpu_tuple_cost = 0.5");
76 76
 
77
-		} else if (DB_TYPE == "mysql") {
78
-			$pdo->query("SET time_zone = '+0:0'");
77
+        } else if (DB_TYPE == "mysql") {
78
+            $pdo->query("SET time_zone = '+0:0'");
79 79
 
80
-			if (defined('MYSQL_CHARSET') && MYSQL_CHARSET) {
81
-				$pdo->query("SET NAMES " . MYSQL_CHARSET);
82
-			}
83
-		}
80
+            if (defined('MYSQL_CHARSET') && MYSQL_CHARSET) {
81
+                $pdo->query("SET NAMES " . MYSQL_CHARSET);
82
+            }
83
+        }
84 84
 
85
-		return $pdo;
86
-	}
85
+        return $pdo;
86
+    }
87 87
 
88
-	public static function instance() {
89
-		if (self::$instance == null)
90
-			self::$instance = new self();
88
+    public static function instance() {
89
+        if (self::$instance == null)
90
+            self::$instance = new self();
91 91
 
92
-		return self::$instance;
93
-	}
92
+        return self::$instance;
93
+    }
94 94
 
95
-	public static function get() {
96
-		if (self::$instance == null)
97
-			self::$instance = new self();
95
+    public static function get() {
96
+        if (self::$instance == null)
97
+            self::$instance = new self();
98 98
 
99
-		if (!self::$instance->adapter) {
100
-			self::$instance->legacy_connect();
101
-		}
99
+        if (!self::$instance->adapter) {
100
+            self::$instance->legacy_connect();
101
+        }
102 102
 
103
-		return self::$instance->adapter;
104
-	}
103
+        return self::$instance->adapter;
104
+    }
105 105
 
106
-	public static function pdo() {
107
-		if (self::$instance == null)
108
-			self::$instance = new self();
106
+    public static function pdo() {
107
+        if (self::$instance == null)
108
+            self::$instance = new self();
109 109
 
110
-		if (!self::$instance->pdo) {
111
-			self::$instance->pdo = self::$instance->pdo_connect();
112
-		}
110
+        if (!self::$instance->pdo) {
111
+            self::$instance->pdo = self::$instance->pdo_connect();
112
+        }
113 113
 
114
-		return self::$instance->pdo;
115
-	}
114
+        return self::$instance->pdo;
115
+    }
116 116
 }
Please login to merge, or discard this patch.
classes/pref/feeds.php 1 patch
Indentation   +1153 added lines, -1153 removed lines patch added patch discarded remove patch
@@ -1,87 +1,87 @@  discard block
 block discarded – undo
1 1
 <?php
2 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");
3
+    public function csrf_ignore($method) {
4
+        $csrf_ignored = array("index", "getfeedtree", "add", "editcats", "editfeed",
5
+            "savefeedorder", "uploadicon", "feedswitherrors", "inactivefeeds",
6
+            "batchsubscribe");
7 7
 
8
-		return array_search($method, $csrf_ignored) !== false;
9
-	}
8
+        return array_search($method, $csrf_ignored) !== false;
9
+    }
10 10
 
11
-	public static function get_ts_languages() {
12
-		$rv = [];
11
+    public static function get_ts_languages() {
12
+        $rv = [];
13 13
 
14
-		if (DB_TYPE == "pgsql") {
15
-			$dbh = Db::pdo();
14
+        if (DB_TYPE == "pgsql") {
15
+            $dbh = Db::pdo();
16 16
 
17
-			$res = $dbh->query("SELECT cfgname FROM pg_ts_config");
17
+            $res = $dbh->query("SELECT cfgname FROM pg_ts_config");
18 18
 
19
-			while ($row = $res->fetch()) {
20
-				array_push($rv, ucfirst($row['cfgname']));
21
-			}
22
-		}
19
+            while ($row = $res->fetch()) {
20
+                array_push($rv, ucfirst($row['cfgname']));
21
+            }
22
+        }
23 23
 
24
-		return $rv;
25
-	}
24
+        return $rv;
25
+    }
26 26
 
27
-	public function batch_edit_cbox($elem, $label = false) {
28
-		print "<input type=\"checkbox\" title=\"".__("Check to enable field")."\"
27
+    public function batch_edit_cbox($elem, $label = false) {
28
+        print "<input type=\"checkbox\" title=\"".__("Check to enable field")."\"
29 29
 			onchange=\"dijit.byId('feedEditDlg').toggleField(this, '$elem', '$label')\">";
30
-	}
30
+    }
31 31
 
32
-	public function renamecat() {
33
-		$title = clean($_REQUEST['title']);
34
-		$id = clean($_REQUEST['id']);
32
+    public function renamecat() {
33
+        $title = clean($_REQUEST['title']);
34
+        $id = clean($_REQUEST['id']);
35 35
 
36
-		if ($title) {
37
-			$sth = $this->pdo->prepare("UPDATE ttrss_feed_categories SET
36
+        if ($title) {
37
+            $sth = $this->pdo->prepare("UPDATE ttrss_feed_categories SET
38 38
 				title = ? WHERE id = ? AND owner_uid = ?");
39
-			$sth->execute([$title, $id, $_SESSION['uid']]);
40
-		}
41
-	}
39
+            $sth->execute([$title, $id, $_SESSION['uid']]);
40
+        }
41
+    }
42 42
 
43
-	private function get_category_items($cat_id) {
43
+    private function get_category_items($cat_id) {
44 44
 
45
-		if (clean($_REQUEST['mode']) != 2)
46
-			$search = $_SESSION["prefs_feed_search"];
47
-		else
48
-			$search = "";
45
+        if (clean($_REQUEST['mode']) != 2)
46
+            $search = $_SESSION["prefs_feed_search"];
47
+        else
48
+            $search = "";
49 49
 
50
-		// first one is set by API
51
-		$show_empty_cats = clean($_REQUEST['force_show_empty']) ||
52
-			(clean($_REQUEST['mode']) != 2 && !$search);
50
+        // first one is set by API
51
+        $show_empty_cats = clean($_REQUEST['force_show_empty']) ||
52
+            (clean($_REQUEST['mode']) != 2 && !$search);
53 53
 
54
-		$items = array();
54
+        $items = array();
55 55
 
56
-		$sth = $this->pdo->prepare("SELECT id, title FROM ttrss_feed_categories
56
+        $sth = $this->pdo->prepare("SELECT id, title FROM ttrss_feed_categories
57 57
 				WHERE owner_uid = ? AND parent_cat = ? ORDER BY order_id, title");
58
-		$sth->execute([$_SESSION['uid'], $cat_id]);
58
+        $sth->execute([$_SESSION['uid'], $cat_id]);
59 59
 
60
-		while ($line = $sth->fetch()) {
60
+        while ($line = $sth->fetch()) {
61 61
 
62
-			$cat = array();
63
-			$cat['id'] = 'CAT:' . $line['id'];
64
-			$cat['bare_id'] = (int)$line['id'];
65
-			$cat['name'] = $line['title'];
66
-			$cat['items'] = array();
67
-			$cat['checkbox'] = false;
68
-			$cat['type'] = 'category';
69
-			$cat['unread'] = -1;
70
-			$cat['child_unread'] = -1;
71
-			$cat['auxcounter'] = -1;
72
-			$cat['parent_id'] = $cat_id;
62
+            $cat = array();
63
+            $cat['id'] = 'CAT:' . $line['id'];
64
+            $cat['bare_id'] = (int)$line['id'];
65
+            $cat['name'] = $line['title'];
66
+            $cat['items'] = array();
67
+            $cat['checkbox'] = false;
68
+            $cat['type'] = 'category';
69
+            $cat['unread'] = -1;
70
+            $cat['child_unread'] = -1;
71
+            $cat['auxcounter'] = -1;
72
+            $cat['parent_id'] = $cat_id;
73 73
 
74
-			$cat['items'] = $this->get_category_items($line['id']);
74
+            $cat['items'] = $this->get_category_items($line['id']);
75 75
 
76
-			$num_children = $this->calculate_children_count($cat);
77
-			$cat['param'] = vsprintf(_ngettext('(%d feed)', '(%d feeds)', (int) $num_children), $num_children);
76
+            $num_children = $this->calculate_children_count($cat);
77
+            $cat['param'] = vsprintf(_ngettext('(%d feed)', '(%d feeds)', (int) $num_children), $num_children);
78 78
 
79
-			if ($num_children > 0 || $show_empty_cats)
80
-				array_push($items, $cat);
79
+            if ($num_children > 0 || $show_empty_cats)
80
+                array_push($items, $cat);
81 81
 
82
-		}
82
+        }
83 83
 
84
-		$fsth = $this->pdo->prepare("SELECT id, title, last_error,
84
+        $fsth = $this->pdo->prepare("SELECT id, title, last_error,
85 85
 			".SUBSTRING_FOR_DATE."(last_updated,1,19) AS last_updated, update_interval
86 86
 			FROM ttrss_feeds
87 87
 			WHERE cat_id = :cat AND
@@ -89,679 +89,679 @@  discard block
 block discarded – undo
89 89
 			(:search = '' OR (LOWER(title) LIKE :search OR LOWER(feed_url) LIKE :search))
90 90
 			ORDER BY order_id, title");
91 91
 
92
-		$fsth->execute([":cat" => $cat_id, ":uid" => $_SESSION['uid'], ":search" => $search ? "%$search%" : ""]);
93
-
94
-		while ($feed_line = $fsth->fetch()) {
95
-			$feed = array();
96
-			$feed['id'] = 'FEED:' . $feed_line['id'];
97
-			$feed['bare_id'] = (int)$feed_line['id'];
98
-			$feed['auxcounter'] = -1;
99
-			$feed['name'] = $feed_line['title'];
100
-			$feed['checkbox'] = false;
101
-			$feed['unread'] = -1;
102
-			$feed['error'] = $feed_line['last_error'];
103
-			$feed['icon'] = Feeds::getFeedIcon($feed_line['id']);
104
-			$feed['param'] = make_local_datetime(
105
-				$feed_line['last_updated'], true);
106
-			$feed['updates_disabled'] = (int)($feed_line['update_interval'] < 0);
107
-
108
-			array_push($items, $feed);
109
-		}
110
-
111
-		return $items;
112
-	}
113
-
114
-	public function getfeedtree() {
115
-		print json_encode($this->makefeedtree());
116
-	}
117
-
118
-	public function makefeedtree() {
119
-
120
-		if (clean($_REQUEST['mode']) != 2)
121
-			$search = $_SESSION["prefs_feed_search"];
122
-		else
123
-			$search = "";
124
-
125
-		$root = array();
126
-		$root['id'] = 'root';
127
-		$root['name'] = __('Feeds');
128
-		$root['items'] = array();
129
-		$root['type'] = 'category';
130
-
131
-		$enable_cats = get_pref('ENABLE_FEED_CATS');
132
-
133
-		if (clean($_REQUEST['mode']) == 2) {
134
-
135
-			if ($enable_cats) {
136
-				$cat = $this->feedlist_init_cat(-1);
137
-			} else {
138
-				$cat['items'] = array();
139
-			}
140
-
141
-			foreach (array(-4, -3, -1, -2, 0, -6) as $i) {
142
-				array_push($cat['items'], $this->feedlist_init_feed($i));
143
-			}
144
-
145
-			/* Plugin feeds for -1 */
146
-
147
-			$feeds = PluginHost::getInstance()->get_feeds(-1);
148
-
149
-			if ($feeds) {
150
-				foreach ($feeds as $feed) {
151
-					$feed_id = PluginHost::pfeed_to_feed_id($feed['id']);
152
-
153
-					$item = array();
154
-					$item['id'] = 'FEED:' . $feed_id;
155
-					$item['bare_id'] = (int)$feed_id;
156
-					$item['auxcounter'] = -1;
157
-					$item['name'] = $feed['title'];
158
-					$item['checkbox'] = false;
159
-					$item['error'] = '';
160
-					$item['icon'] = $feed['icon'];
161
-
162
-					$item['param'] = '';
163
-					$item['unread'] = -1;
164
-					$item['type'] = 'feed';
165
-
166
-					array_push($cat['items'], $item);
167
-				}
168
-			}
169
-
170
-			if ($enable_cats) {
171
-				array_push($root['items'], $cat);
172
-			} else {
173
-				$root['items'] = array_merge($root['items'], $cat['items']);
174
-			}
175
-
176
-			$sth = $this->pdo->prepare("SELECT * FROM
92
+        $fsth->execute([":cat" => $cat_id, ":uid" => $_SESSION['uid'], ":search" => $search ? "%$search%" : ""]);
93
+
94
+        while ($feed_line = $fsth->fetch()) {
95
+            $feed = array();
96
+            $feed['id'] = 'FEED:' . $feed_line['id'];
97
+            $feed['bare_id'] = (int)$feed_line['id'];
98
+            $feed['auxcounter'] = -1;
99
+            $feed['name'] = $feed_line['title'];
100
+            $feed['checkbox'] = false;
101
+            $feed['unread'] = -1;
102
+            $feed['error'] = $feed_line['last_error'];
103
+            $feed['icon'] = Feeds::getFeedIcon($feed_line['id']);
104
+            $feed['param'] = make_local_datetime(
105
+                $feed_line['last_updated'], true);
106
+            $feed['updates_disabled'] = (int)($feed_line['update_interval'] < 0);
107
+
108
+            array_push($items, $feed);
109
+        }
110
+
111
+        return $items;
112
+    }
113
+
114
+    public function getfeedtree() {
115
+        print json_encode($this->makefeedtree());
116
+    }
117
+
118
+    public function makefeedtree() {
119
+
120
+        if (clean($_REQUEST['mode']) != 2)
121
+            $search = $_SESSION["prefs_feed_search"];
122
+        else
123
+            $search = "";
124
+
125
+        $root = array();
126
+        $root['id'] = 'root';
127
+        $root['name'] = __('Feeds');
128
+        $root['items'] = array();
129
+        $root['type'] = 'category';
130
+
131
+        $enable_cats = get_pref('ENABLE_FEED_CATS');
132
+
133
+        if (clean($_REQUEST['mode']) == 2) {
134
+
135
+            if ($enable_cats) {
136
+                $cat = $this->feedlist_init_cat(-1);
137
+            } else {
138
+                $cat['items'] = array();
139
+            }
140
+
141
+            foreach (array(-4, -3, -1, -2, 0, -6) as $i) {
142
+                array_push($cat['items'], $this->feedlist_init_feed($i));
143
+            }
144
+
145
+            /* Plugin feeds for -1 */
146
+
147
+            $feeds = PluginHost::getInstance()->get_feeds(-1);
148
+
149
+            if ($feeds) {
150
+                foreach ($feeds as $feed) {
151
+                    $feed_id = PluginHost::pfeed_to_feed_id($feed['id']);
152
+
153
+                    $item = array();
154
+                    $item['id'] = 'FEED:' . $feed_id;
155
+                    $item['bare_id'] = (int)$feed_id;
156
+                    $item['auxcounter'] = -1;
157
+                    $item['name'] = $feed['title'];
158
+                    $item['checkbox'] = false;
159
+                    $item['error'] = '';
160
+                    $item['icon'] = $feed['icon'];
161
+
162
+                    $item['param'] = '';
163
+                    $item['unread'] = -1;
164
+                    $item['type'] = 'feed';
165
+
166
+                    array_push($cat['items'], $item);
167
+                }
168
+            }
169
+
170
+            if ($enable_cats) {
171
+                array_push($root['items'], $cat);
172
+            } else {
173
+                $root['items'] = array_merge($root['items'], $cat['items']);
174
+            }
175
+
176
+            $sth = $this->pdo->prepare("SELECT * FROM
177 177
 				ttrss_labels2 WHERE owner_uid = ? ORDER by caption");
178
-			$sth->execute([$_SESSION['uid']]);
178
+            $sth->execute([$_SESSION['uid']]);
179 179
 
180
-			if (get_pref('ENABLE_FEED_CATS')) {
181
-				$cat = $this->feedlist_init_cat(-2);
182
-			} else {
183
-				$cat['items'] = array();
184
-			}
180
+            if (get_pref('ENABLE_FEED_CATS')) {
181
+                $cat = $this->feedlist_init_cat(-2);
182
+            } else {
183
+                $cat['items'] = array();
184
+            }
185 185
 
186
-			$num_labels = 0;
187
-			while ($line = $sth->fetch()) {
188
-				++$num_labels;
186
+            $num_labels = 0;
187
+            while ($line = $sth->fetch()) {
188
+                ++$num_labels;
189 189
 
190
-				$label_id = Labels::label_to_feed_id($line['id']);
190
+                $label_id = Labels::label_to_feed_id($line['id']);
191 191
 
192
-				$feed = $this->feedlist_init_feed($label_id, false, 0);
192
+                $feed = $this->feedlist_init_feed($label_id, false, 0);
193 193
 
194
-				$feed['fg_color'] = $line['fg_color'];
195
-				$feed['bg_color'] = $line['bg_color'];
194
+                $feed['fg_color'] = $line['fg_color'];
195
+                $feed['bg_color'] = $line['bg_color'];
196 196
 
197
-				array_push($cat['items'], $feed);
198
-			}
197
+                array_push($cat['items'], $feed);
198
+            }
199 199
 
200
-			if ($num_labels) {
201
-				if ($enable_cats) {
202
-					array_push($root['items'], $cat);
203
-				} else {
204
-					$root['items'] = array_merge($root['items'], $cat['items']);
205
-				}
206
-			}
207
-		}
200
+            if ($num_labels) {
201
+                if ($enable_cats) {
202
+                    array_push($root['items'], $cat);
203
+                } else {
204
+                    $root['items'] = array_merge($root['items'], $cat['items']);
205
+                }
206
+            }
207
+        }
208 208
 
209
-		if ($enable_cats) {
210
-			$show_empty_cats = clean($_REQUEST['force_show_empty']) ||
211
-				(clean($_REQUEST['mode']) != 2 && !$search);
209
+        if ($enable_cats) {
210
+            $show_empty_cats = clean($_REQUEST['force_show_empty']) ||
211
+                (clean($_REQUEST['mode']) != 2 && !$search);
212 212
 
213
-			$sth = $this->pdo->prepare("SELECT id, title FROM ttrss_feed_categories
213
+            $sth = $this->pdo->prepare("SELECT id, title FROM ttrss_feed_categories
214 214
 				WHERE owner_uid = ? AND parent_cat IS NULL ORDER BY order_id, title");
215
-			$sth->execute([$_SESSION['uid']]);
216
-
217
-			while ($line = $sth->fetch()) {
218
-				$cat = array();
219
-				$cat['id'] = 'CAT:' . $line['id'];
220
-				$cat['bare_id'] = (int)$line['id'];
221
-				$cat['auxcounter'] = -1;
222
-				$cat['name'] = $line['title'];
223
-				$cat['items'] = array();
224
-				$cat['checkbox'] = false;
225
-				$cat['type'] = 'category';
226
-				$cat['unread'] = -1;
227
-				$cat['child_unread'] = -1;
228
-
229
-				$cat['items'] = $this->get_category_items($line['id']);
230
-
231
-				$num_children = $this->calculate_children_count($cat);
232
-				$cat['param'] = vsprintf(_ngettext('(%d feed)', '(%d feeds)', (int) $num_children), $num_children);
233
-
234
-				if ($num_children > 0 || $show_empty_cats)
235
-					array_push($root['items'], $cat);
236
-
237
-				$root['param'] += count($cat['items']);
238
-			}
239
-
240
-			/* Uncategorized is a special case */
241
-
242
-			$cat = array();
243
-			$cat['id'] = 'CAT:0';
244
-			$cat['bare_id'] = 0;
245
-			$cat['auxcounter'] = -1;
246
-			$cat['name'] = __("Uncategorized");
247
-			$cat['items'] = array();
248
-			$cat['type'] = 'category';
249
-			$cat['checkbox'] = false;
250
-			$cat['unread'] = -1;
251
-			$cat['child_unread'] = -1;
252
-
253
-			$fsth = $this->pdo->prepare("SELECT id, title,last_error,
215
+            $sth->execute([$_SESSION['uid']]);
216
+
217
+            while ($line = $sth->fetch()) {
218
+                $cat = array();
219
+                $cat['id'] = 'CAT:' . $line['id'];
220
+                $cat['bare_id'] = (int)$line['id'];
221
+                $cat['auxcounter'] = -1;
222
+                $cat['name'] = $line['title'];
223
+                $cat['items'] = array();
224
+                $cat['checkbox'] = false;
225
+                $cat['type'] = 'category';
226
+                $cat['unread'] = -1;
227
+                $cat['child_unread'] = -1;
228
+
229
+                $cat['items'] = $this->get_category_items($line['id']);
230
+
231
+                $num_children = $this->calculate_children_count($cat);
232
+                $cat['param'] = vsprintf(_ngettext('(%d feed)', '(%d feeds)', (int) $num_children), $num_children);
233
+
234
+                if ($num_children > 0 || $show_empty_cats)
235
+                    array_push($root['items'], $cat);
236
+
237
+                $root['param'] += count($cat['items']);
238
+            }
239
+
240
+            /* Uncategorized is a special case */
241
+
242
+            $cat = array();
243
+            $cat['id'] = 'CAT:0';
244
+            $cat['bare_id'] = 0;
245
+            $cat['auxcounter'] = -1;
246
+            $cat['name'] = __("Uncategorized");
247
+            $cat['items'] = array();
248
+            $cat['type'] = 'category';
249
+            $cat['checkbox'] = false;
250
+            $cat['unread'] = -1;
251
+            $cat['child_unread'] = -1;
252
+
253
+            $fsth = $this->pdo->prepare("SELECT id, title,last_error,
254 254
 				".SUBSTRING_FOR_DATE."(last_updated,1,19) AS last_updated, update_interval
255 255
 				FROM ttrss_feeds
256 256
 				WHERE cat_id IS NULL AND
257 257
 				owner_uid = :uid AND
258 258
 				(:search = '' OR (LOWER(title) LIKE :search OR LOWER(feed_url) LIKE :search))
259 259
 				ORDER BY order_id, title");
260
-			$fsth->execute([":uid" => $_SESSION['uid'], ":search" => $search ? "%$search%" : ""]);
261
-
262
-			while ($feed_line = $fsth->fetch()) {
263
-				$feed = array();
264
-				$feed['id'] = 'FEED:' . $feed_line['id'];
265
-				$feed['bare_id'] = (int)$feed_line['id'];
266
-				$feed['auxcounter'] = -1;
267
-				$feed['name'] = $feed_line['title'];
268
-				$feed['checkbox'] = false;
269
-				$feed['error'] = $feed_line['last_error'];
270
-				$feed['icon'] = Feeds::getFeedIcon($feed_line['id']);
271
-				$feed['param'] = make_local_datetime(
272
-					$feed_line['last_updated'], true);
273
-				$feed['unread'] = -1;
274
-				$feed['type'] = 'feed';
275
-				$feed['updates_disabled'] = (int)($feed_line['update_interval'] < 0);
276
-
277
-				array_push($cat['items'], $feed);
278
-			}
279
-
280
-			$cat['param'] = vsprintf(_ngettext('(%d feed)', '(%d feeds)', count($cat['items'])), count($cat['items']));
281
-
282
-			if (count($cat['items']) > 0 || $show_empty_cats)
283
-				array_push($root['items'], $cat);
284
-
285
-			$num_children = $this->calculate_children_count($root);
286
-			$root['param'] = vsprintf(_ngettext('(%d feed)', '(%d feeds)', (int) $num_children), $num_children);
287
-
288
-		} else {
289
-			$fsth = $this->pdo->prepare("SELECT id, title, last_error,
260
+            $fsth->execute([":uid" => $_SESSION['uid'], ":search" => $search ? "%$search%" : ""]);
261
+
262
+            while ($feed_line = $fsth->fetch()) {
263
+                $feed = array();
264
+                $feed['id'] = 'FEED:' . $feed_line['id'];
265
+                $feed['bare_id'] = (int)$feed_line['id'];
266
+                $feed['auxcounter'] = -1;
267
+                $feed['name'] = $feed_line['title'];
268
+                $feed['checkbox'] = false;
269
+                $feed['error'] = $feed_line['last_error'];
270
+                $feed['icon'] = Feeds::getFeedIcon($feed_line['id']);
271
+                $feed['param'] = make_local_datetime(
272
+                    $feed_line['last_updated'], true);
273
+                $feed['unread'] = -1;
274
+                $feed['type'] = 'feed';
275
+                $feed['updates_disabled'] = (int)($feed_line['update_interval'] < 0);
276
+
277
+                array_push($cat['items'], $feed);
278
+            }
279
+
280
+            $cat['param'] = vsprintf(_ngettext('(%d feed)', '(%d feeds)', count($cat['items'])), count($cat['items']));
281
+
282
+            if (count($cat['items']) > 0 || $show_empty_cats)
283
+                array_push($root['items'], $cat);
284
+
285
+            $num_children = $this->calculate_children_count($root);
286
+            $root['param'] = vsprintf(_ngettext('(%d feed)', '(%d feeds)', (int) $num_children), $num_children);
287
+
288
+        } else {
289
+            $fsth = $this->pdo->prepare("SELECT id, title, last_error,
290 290
 				".SUBSTRING_FOR_DATE."(last_updated,1,19) AS last_updated, update_interval
291 291
 				FROM ttrss_feeds
292 292
 				WHERE owner_uid = :uid AND
293 293
 				(:search = '' OR (LOWER(title) LIKE :search OR LOWER(feed_url) LIKE :search))
294 294
 				ORDER BY order_id, title");
295
-			$fsth->execute([":uid" => $_SESSION['uid'], ":search" => $search ? "%$search%" : ""]);
296
-
297
-			while ($feed_line = $fsth->fetch()) {
298
-				$feed = array();
299
-				$feed['id'] = 'FEED:' . $feed_line['id'];
300
-				$feed['bare_id'] = (int)$feed_line['id'];
301
-				$feed['auxcounter'] = -1;
302
-				$feed['name'] = $feed_line['title'];
303
-				$feed['checkbox'] = false;
304
-				$feed['error'] = $feed_line['last_error'];
305
-				$feed['icon'] = Feeds::getFeedIcon($feed_line['id']);
306
-				$feed['param'] = make_local_datetime(
307
-					$feed_line['last_updated'], true);
308
-				$feed['unread'] = -1;
309
-				$feed['type'] = 'feed';
310
-				$feed['updates_disabled'] = (int)($feed_line['update_interval'] < 0);
311
-
312
-				array_push($root['items'], $feed);
313
-			}
314
-
315
-			$root['param'] = vsprintf(_ngettext('(%d feed)', '(%d feeds)', count($root['items'])), count($root['items']));
316
-		}
317
-
318
-		$fl = array();
319
-		$fl['identifier'] = 'id';
320
-		$fl['label'] = 'name';
321
-
322
-		if (clean($_REQUEST['mode']) != 2) {
323
-			$fl['items'] = array($root);
324
-		} else {
325
-			$fl['items'] = $root['items'];
326
-		}
327
-
328
-		return $fl;
329
-	}
330
-
331
-	public function catsortreset() {
332
-		$sth = $this->pdo->prepare("UPDATE ttrss_feed_categories
295
+            $fsth->execute([":uid" => $_SESSION['uid'], ":search" => $search ? "%$search%" : ""]);
296
+
297
+            while ($feed_line = $fsth->fetch()) {
298
+                $feed = array();
299
+                $feed['id'] = 'FEED:' . $feed_line['id'];
300
+                $feed['bare_id'] = (int)$feed_line['id'];
301
+                $feed['auxcounter'] = -1;
302
+                $feed['name'] = $feed_line['title'];
303
+                $feed['checkbox'] = false;
304
+                $feed['error'] = $feed_line['last_error'];
305
+                $feed['icon'] = Feeds::getFeedIcon($feed_line['id']);
306
+                $feed['param'] = make_local_datetime(
307
+                    $feed_line['last_updated'], true);
308
+                $feed['unread'] = -1;
309
+                $feed['type'] = 'feed';
310
+                $feed['updates_disabled'] = (int)($feed_line['update_interval'] < 0);
311
+
312
+                array_push($root['items'], $feed);
313
+            }
314
+
315
+            $root['param'] = vsprintf(_ngettext('(%d feed)', '(%d feeds)', count($root['items'])), count($root['items']));
316
+        }
317
+
318
+        $fl = array();
319
+        $fl['identifier'] = 'id';
320
+        $fl['label'] = 'name';
321
+
322
+        if (clean($_REQUEST['mode']) != 2) {
323
+            $fl['items'] = array($root);
324
+        } else {
325
+            $fl['items'] = $root['items'];
326
+        }
327
+
328
+        return $fl;
329
+    }
330
+
331
+    public function catsortreset() {
332
+        $sth = $this->pdo->prepare("UPDATE ttrss_feed_categories
333 333
 				SET order_id = 0 WHERE owner_uid = ?");
334
-		$sth->execute([$_SESSION['uid']]);
335
-	}
334
+        $sth->execute([$_SESSION['uid']]);
335
+    }
336 336
 
337
-	public function feedsortreset() {
338
-		$sth = $this->pdo->prepare("UPDATE ttrss_feeds
337
+    public function feedsortreset() {
338
+        $sth = $this->pdo->prepare("UPDATE ttrss_feeds
339 339
 				SET order_id = 0 WHERE owner_uid = ?");
340
-		$sth->execute([$_SESSION['uid']]);
341
-	}
340
+        $sth->execute([$_SESSION['uid']]);
341
+    }
342 342
 
343
-	private function process_category_order(&$data_map, $item_id, $parent_id = false, $nest_level = 0) {
343
+    private function process_category_order(&$data_map, $item_id, $parent_id = false, $nest_level = 0) {
344 344
 
345
-		$prefix = "";
346
-		for ($i = 0; $i < $nest_level; $i++)
347
-			$prefix .= "   ";
345
+        $prefix = "";
346
+        for ($i = 0; $i < $nest_level; $i++)
347
+            $prefix .= "   ";
348 348
 
349
-		Debug::log("$prefix C: $item_id P: $parent_id");
349
+        Debug::log("$prefix C: $item_id P: $parent_id");
350 350
 
351
-		$bare_item_id = substr($item_id, strpos($item_id, ':')+1);
351
+        $bare_item_id = substr($item_id, strpos($item_id, ':')+1);
352 352
 
353
-		if ($item_id != 'root') {
354
-			if ($parent_id && $parent_id != 'root') {
355
-				$parent_bare_id = substr($parent_id, strpos($parent_id, ':')+1);
356
-				$parent_qpart = $parent_bare_id;
357
-			} else {
358
-				$parent_qpart = null;
359
-			}
353
+        if ($item_id != 'root') {
354
+            if ($parent_id && $parent_id != 'root') {
355
+                $parent_bare_id = substr($parent_id, strpos($parent_id, ':')+1);
356
+                $parent_qpart = $parent_bare_id;
357
+            } else {
358
+                $parent_qpart = null;
359
+            }
360 360
 
361
-			$sth = $this->pdo->prepare("UPDATE ttrss_feed_categories
361
+            $sth = $this->pdo->prepare("UPDATE ttrss_feed_categories
362 362
 				SET parent_cat = ? WHERE id = ? AND
363 363
 				owner_uid = ?");
364
-			$sth->execute([$parent_qpart, $bare_item_id, $_SESSION['uid']]);
365
-		}
364
+            $sth->execute([$parent_qpart, $bare_item_id, $_SESSION['uid']]);
365
+        }
366 366
 
367
-		$order_id = 1;
367
+        $order_id = 1;
368 368
 
369
-		$cat = $data_map[$item_id];
369
+        $cat = $data_map[$item_id];
370 370
 
371
-		if ($cat && is_array($cat)) {
372
-			foreach ($cat as $item) {
373
-				$id = $item['_reference'];
374
-				$bare_id = substr($id, strpos($id, ':')+1);
371
+        if ($cat && is_array($cat)) {
372
+            foreach ($cat as $item) {
373
+                $id = $item['_reference'];
374
+                $bare_id = substr($id, strpos($id, ':')+1);
375 375
 
376
-				Debug::log("$prefix [$order_id] $id/$bare_id");
376
+                Debug::log("$prefix [$order_id] $id/$bare_id");
377 377
 
378
-				if ($item['_reference']) {
378
+                if ($item['_reference']) {
379 379
 
380
-					if (strpos($id, "FEED") === 0) {
380
+                    if (strpos($id, "FEED") === 0) {
381 381
 
382
-						$cat_id = ($item_id != "root") ? $bare_item_id : null;
382
+                        $cat_id = ($item_id != "root") ? $bare_item_id : null;
383 383
 
384
-						$sth = $this->pdo->prepare("UPDATE ttrss_feeds
384
+                        $sth = $this->pdo->prepare("UPDATE ttrss_feeds
385 385
 							SET order_id = ?, cat_id = ?
386 386
 							WHERE id = ? AND owner_uid = ?");
387 387
 
388
-						$sth->execute([$order_id, $cat_id ? $cat_id : null, $bare_id, $_SESSION['uid']]);
388
+                        $sth->execute([$order_id, $cat_id ? $cat_id : null, $bare_id, $_SESSION['uid']]);
389 389
 
390
-					} else if (strpos($id, "CAT:") === 0) {
391
-						$this->process_category_order($data_map, $item['_reference'], $item_id,
392
-							$nest_level+1);
390
+                    } else if (strpos($id, "CAT:") === 0) {
391
+                        $this->process_category_order($data_map, $item['_reference'], $item_id,
392
+                            $nest_level+1);
393 393
 
394
-						$sth = $this->pdo->prepare("UPDATE ttrss_feed_categories
394
+                        $sth = $this->pdo->prepare("UPDATE ttrss_feed_categories
395 395
 								SET order_id = ? WHERE id = ? AND
396 396
 								owner_uid = ?");
397
-						$sth->execute([$order_id, $bare_id, $_SESSION['uid']]);
398
-					}
399
-				}
397
+                        $sth->execute([$order_id, $bare_id, $_SESSION['uid']]);
398
+                    }
399
+                }
400 400
 
401
-				++$order_id;
402
-			}
403
-		}
404
-	}
401
+                ++$order_id;
402
+            }
403
+        }
404
+    }
405 405
 
406
-	public function savefeedorder() {
407
-		$data = json_decode($_POST['payload'], true);
406
+    public function savefeedorder() {
407
+        $data = json_decode($_POST['payload'], true);
408 408
 
409
-		#file_put_contents("/tmp/saveorder.json", clean($_POST['payload']));
410
-		#$data = json_decode(file_get_contents("/tmp/saveorder.json"), true);
409
+        #file_put_contents("/tmp/saveorder.json", clean($_POST['payload']));
410
+        #$data = json_decode(file_get_contents("/tmp/saveorder.json"), true);
411 411
 
412
-		if (!is_array($data['items']))
413
-			$data['items'] = json_decode($data['items'], true);
412
+        if (!is_array($data['items']))
413
+            $data['items'] = json_decode($data['items'], true);
414 414
 
415 415
 #		print_r($data['items']);
416 416
 
417
-		if (is_array($data) && is_array($data['items'])) {
417
+        if (is_array($data) && is_array($data['items'])) {
418 418
 #			$cat_order_id = 0;
419 419
 
420
-			$data_map = array();
421
-			$root_item = false;
420
+            $data_map = array();
421
+            $root_item = false;
422 422
 
423
-			foreach ($data['items'] as $item) {
423
+            foreach ($data['items'] as $item) {
424 424
 
425 425
 #				if ($item['id'] != 'root') {
426
-					if (is_array($item['items'])) {
427
-						if (isset($item['items']['_reference'])) {
428
-							$data_map[$item['id']] = array($item['items']);
429
-						} else {
430
-							$data_map[$item['id']] = $item['items'];
431
-						}
432
-					}
433
-				if ($item['id'] == 'root') {
434
-					$root_item = $item['id'];
435
-				}
436
-			}
437
-
438
-			$this->process_category_order($data_map, $root_item);
439
-		}
440
-	}
441
-
442
-	public function removeicon() {
443
-		$feed_id = clean($_REQUEST["feed_id"]);
444
-
445
-		$sth = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE id = ? AND owner_uid = ?");
446
-		$sth->execute([$feed_id, $_SESSION['uid']]);
447
-
448
-		if ($sth->fetch()) {
449
-			@unlink(ICONS_DIR . "/$feed_id.ico");
450
-
451
-			$sth = $this->pdo->prepare("UPDATE ttrss_feeds SET favicon_avg_color = NULL where id = ?");
452
-			$sth->execute([$feed_id]);
453
-		}
454
-	}
455
-
456
-	public function uploadicon() {
457
-		header("Content-type: text/html");
458
-
459
-		if (is_uploaded_file($_FILES['icon_file']['tmp_name'])) {
460
-			$tmp_file = tempnam(CACHE_DIR . '/upload', 'icon');
461
-
462
-			$result = move_uploaded_file($_FILES['icon_file']['tmp_name'],
463
-				$tmp_file);
464
-
465
-			if (!$result) {
466
-				return;
467
-			}
468
-		} else {
469
-			return;
470
-		}
426
+                    if (is_array($item['items'])) {
427
+                        if (isset($item['items']['_reference'])) {
428
+                            $data_map[$item['id']] = array($item['items']);
429
+                        } else {
430
+                            $data_map[$item['id']] = $item['items'];
431
+                        }
432
+                    }
433
+                if ($item['id'] == 'root') {
434
+                    $root_item = $item['id'];
435
+                }
436
+            }
437
+
438
+            $this->process_category_order($data_map, $root_item);
439
+        }
440
+    }
441
+
442
+    public function removeicon() {
443
+        $feed_id = clean($_REQUEST["feed_id"]);
444
+
445
+        $sth = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE id = ? AND owner_uid = ?");
446
+        $sth->execute([$feed_id, $_SESSION['uid']]);
447
+
448
+        if ($sth->fetch()) {
449
+            @unlink(ICONS_DIR . "/$feed_id.ico");
450
+
451
+            $sth = $this->pdo->prepare("UPDATE ttrss_feeds SET favicon_avg_color = NULL where id = ?");
452
+            $sth->execute([$feed_id]);
453
+        }
454
+    }
455
+
456
+    public function uploadicon() {
457
+        header("Content-type: text/html");
458
+
459
+        if (is_uploaded_file($_FILES['icon_file']['tmp_name'])) {
460
+            $tmp_file = tempnam(CACHE_DIR . '/upload', 'icon');
461
+
462
+            $result = move_uploaded_file($_FILES['icon_file']['tmp_name'],
463
+                $tmp_file);
464
+
465
+            if (!$result) {
466
+                return;
467
+            }
468
+        } else {
469
+            return;
470
+        }
471 471
 
472
-		$icon_file = $tmp_file;
473
-		$feed_id = clean($_REQUEST["feed_id"]);
474
-		$rc = 2; // failed
472
+        $icon_file = $tmp_file;
473
+        $feed_id = clean($_REQUEST["feed_id"]);
474
+        $rc = 2; // failed
475 475
 
476
-		if (is_file($icon_file) && $feed_id) {
477
-			if (filesize($icon_file) < 65535) {
476
+        if (is_file($icon_file) && $feed_id) {
477
+            if (filesize($icon_file) < 65535) {
478 478
 
479
-				$sth = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE id = ? AND owner_uid = ?");
480
-				$sth->execute([$feed_id, $_SESSION['uid']]);
479
+                $sth = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE id = ? AND owner_uid = ?");
480
+                $sth->execute([$feed_id, $_SESSION['uid']]);
481 481
 
482
-				if ($sth->fetch()) {
483
-					@unlink(ICONS_DIR . "/$feed_id.ico");
484
-					if (rename($icon_file, ICONS_DIR . "/$feed_id.ico")) {
482
+                if ($sth->fetch()) {
483
+                    @unlink(ICONS_DIR . "/$feed_id.ico");
484
+                    if (rename($icon_file, ICONS_DIR . "/$feed_id.ico")) {
485 485
 
486
-						$sth = $this->pdo->prepare("UPDATE ttrss_feeds SET favicon_avg_color = '' WHERE id = ?");
487
-						$sth->execute([$feed_id]);
486
+                        $sth = $this->pdo->prepare("UPDATE ttrss_feeds SET favicon_avg_color = '' WHERE id = ?");
487
+                        $sth->execute([$feed_id]);
488 488
 
489
-						$rc = 0;
490
-					}
491
-				}
492
-			} else {
493
-				$rc = 1;
494
-			}
495
-		}
489
+                        $rc = 0;
490
+                    }
491
+                }
492
+            } else {
493
+                $rc = 1;
494
+            }
495
+        }
496 496
 
497
-		if (is_file($icon_file)) @unlink($icon_file);
497
+        if (is_file($icon_file)) @unlink($icon_file);
498 498
 
499
-		print $rc;
500
-		return;
501
-	}
499
+        print $rc;
500
+        return;
501
+    }
502 502
 
503
-	public function editfeed() {
504
-		global $purge_intervals;
505
-		global $update_intervals;
503
+    public function editfeed() {
504
+        global $purge_intervals;
505
+        global $update_intervals;
506 506
 
507 507
 
508
-		$feed_id = clean($_REQUEST["id"]);
508
+        $feed_id = clean($_REQUEST["id"]);
509 509
 
510
-		$sth = $this->pdo->prepare("SELECT * FROM ttrss_feeds WHERE id = ? AND
510
+        $sth = $this->pdo->prepare("SELECT * FROM ttrss_feeds WHERE id = ? AND
511 511
 				owner_uid = ?");
512
-		$sth->execute([$feed_id, $_SESSION['uid']]);
512
+        $sth->execute([$feed_id, $_SESSION['uid']]);
513 513
 
514
-		if ($row = $sth->fetch()) {
515
-			print '<div dojoType="dijit.layout.TabContainer" style="height : 450px">
514
+        if ($row = $sth->fetch()) {
515
+            print '<div dojoType="dijit.layout.TabContainer" style="height : 450px">
516 516
         		<div dojoType="dijit.layout.ContentPane" title="'.__('General').'">';
517 517
 
518
-			$title = htmlspecialchars($row["title"]);
518
+            $title = htmlspecialchars($row["title"]);
519 519
 
520
-			print_hidden("id", "$feed_id");
521
-			print_hidden("op", "pref-feeds");
522
-			print_hidden("method", "editSave");
520
+            print_hidden("id", "$feed_id");
521
+            print_hidden("op", "pref-feeds");
522
+            print_hidden("method", "editSave");
523 523
 
524
-			print "<header>".__("Feed")."</header>";
525
-			print "<section>";
524
+            print "<header>".__("Feed")."</header>";
525
+            print "<section>";
526 526
 
527
-			/* Title */
527
+            /* Title */
528 528
 
529
-			print "<fieldset>";
529
+            print "<fieldset>";
530 530
 
531
-			print "<input dojoType='dijit.form.ValidationTextBox' required='1'
531
+            print "<input dojoType='dijit.form.ValidationTextBox' required='1'
532 532
 				placeHolder=\"".__("Feed Title")."\"
533 533
 				style='font-size : 16px; width: 500px' name='title' value=\"$title\">";
534 534
 
535
-			print "</fieldset>";
535
+            print "</fieldset>";
536 536
 
537
-			/* Feed URL */
537
+            /* Feed URL */
538 538
 
539
-			$feed_url = htmlspecialchars($row["feed_url"]);
539
+            $feed_url = htmlspecialchars($row["feed_url"]);
540 540
 
541
-			print "<fieldset>";
541
+            print "<fieldset>";
542 542
 
543
-			print "<label>" . __('URL:') . "</label> ";
544
-			print "<input dojoType='dijit.form.ValidationTextBox' required='1'
543
+            print "<label>" . __('URL:') . "</label> ";
544
+            print "<input dojoType='dijit.form.ValidationTextBox' required='1'
545 545
 				placeHolder=\"".__("Feed URL")."\"
546 546
 				regExp='^(http|https)://.*' style='width : 300px'
547 547
 				name='feed_url' value=\"$feed_url\">";
548 548
 
549
-			$last_error = $row["last_error"];
549
+            $last_error = $row["last_error"];
550 550
 
551
-			if ($last_error) {
552
-				print "&nbsp;<i class=\"material-icons\"
551
+            if ($last_error) {
552
+                print "&nbsp;<i class=\"material-icons\"
553 553
 					title=\"".htmlspecialchars($last_error)."\">error</i>";
554
-			}
554
+            }
555 555
 
556
-			print "</fieldset>";
556
+            print "</fieldset>";
557 557
 
558
-			/* Category */
558
+            /* Category */
559 559
 
560
-			if (get_pref('ENABLE_FEED_CATS')) {
560
+            if (get_pref('ENABLE_FEED_CATS')) {
561 561
 
562
-				$cat_id = $row["cat_id"];
562
+                $cat_id = $row["cat_id"];
563 563
 
564
-				print "<fieldset>";
564
+                print "<fieldset>";
565 565
 
566
-				print "<label>" . __('Place in category:') . "</label> ";
566
+                print "<label>" . __('Place in category:') . "</label> ";
567 567
 
568
-				print_feed_cat_select("cat_id", $cat_id,
569
-					'dojoType="fox.form.Select"');
568
+                print_feed_cat_select("cat_id", $cat_id,
569
+                    'dojoType="fox.form.Select"');
570 570
 
571
-				print "</fieldset>";
572
-			}
571
+                print "</fieldset>";
572
+            }
573 573
 
574
-			/* Site URL  */
574
+            /* Site URL  */
575 575
 
576
-			$site_url = htmlspecialchars($row["site_url"]);
576
+            $site_url = htmlspecialchars($row["site_url"]);
577 577
 
578
-			print "<fieldset>";
578
+            print "<fieldset>";
579 579
 
580
-			print "<label>" . __('Site URL:') . "</label> ";
581
-			print "<input dojoType='dijit.form.ValidationTextBox' required='1'
580
+            print "<label>" . __('Site URL:') . "</label> ";
581
+            print "<input dojoType='dijit.form.ValidationTextBox' required='1'
582 582
 				placeHolder=\"".__("Site URL")."\"
583 583
 				regExp='^(http|https)://.*' style='width : 300px'
584 584
 				name='site_url' value=\"$site_url\">";
585 585
 
586
-			print "</fieldset>";
586
+            print "</fieldset>";
587 587
 
588
-			/* FTS Stemming Language */
588
+            /* FTS Stemming Language */
589 589
 
590
-			if (DB_TYPE == "pgsql") {
591
-				$feed_language = $row["feed_language"];
590
+            if (DB_TYPE == "pgsql") {
591
+                $feed_language = $row["feed_language"];
592 592
 
593
-				if (!$feed_language)
594
-					$feed_language = get_pref('DEFAULT_SEARCH_LANGUAGE');
593
+                if (!$feed_language)
594
+                    $feed_language = get_pref('DEFAULT_SEARCH_LANGUAGE');
595 595
 
596
-				print "<fieldset>";
596
+                print "<fieldset>";
597 597
 
598
-				print "<label>" . __('Language:') . "</label> ";
599
-				print_select("feed_language", $feed_language, $this::get_ts_languages(),
600
-					'dojoType="fox.form.Select"');
598
+                print "<label>" . __('Language:') . "</label> ";
599
+                print_select("feed_language", $feed_language, $this::get_ts_languages(),
600
+                    'dojoType="fox.form.Select"');
601 601
 
602
-				print "</fieldset>";
603
-			}
602
+                print "</fieldset>";
603
+            }
604 604
 
605
-			print "</section>";
605
+            print "</section>";
606 606
 
607
-			print "<header>".__("Update")."</header>";
608
-			print "<section>";
607
+            print "<header>".__("Update")."</header>";
608
+            print "<section>";
609 609
 
610
-			/* Update Interval */
610
+            /* Update Interval */
611 611
 
612
-			$update_interval = $row["update_interval"];
612
+            $update_interval = $row["update_interval"];
613 613
 
614
-			print "<fieldset>";
614
+            print "<fieldset>";
615 615
 
616
-			print "<label>".__("Interval:")."</label> ";
616
+            print "<label>".__("Interval:")."</label> ";
617 617
 
618
-			print_select_hash("update_interval", $update_interval, $update_intervals,
619
-				'dojoType="fox.form.Select"');
618
+            print_select_hash("update_interval", $update_interval, $update_intervals,
619
+                'dojoType="fox.form.Select"');
620 620
 
621
-			print "</fieldset>";
621
+            print "</fieldset>";
622 622
 
623
-			/* Purge intl */
623
+            /* Purge intl */
624 624
 
625
-			$purge_interval = $row["purge_interval"];
625
+            $purge_interval = $row["purge_interval"];
626 626
 
627
-			print "<fieldset>";
627
+            print "<fieldset>";
628 628
 
629
-			print "<label>" . __('Article purging:') . "</label> ";
629
+            print "<label>" . __('Article purging:') . "</label> ";
630 630
 
631
-			print_select_hash("purge_interval", $purge_interval, $purge_intervals,
632
-				'dojoType="fox.form.Select" ' .
633
-				((FORCE_ARTICLE_PURGE == 0) ? "" : 'disabled="1"'));
631
+            print_select_hash("purge_interval", $purge_interval, $purge_intervals,
632
+                'dojoType="fox.form.Select" ' .
633
+                ((FORCE_ARTICLE_PURGE == 0) ? "" : 'disabled="1"'));
634 634
 
635
-			print "</fieldset>";
635
+            print "</fieldset>";
636 636
 
637
-			print "</section>";
637
+            print "</section>";
638 638
 
639
-			$auth_login = htmlspecialchars($row["auth_login"]);
640
-			$auth_pass = htmlspecialchars($row["auth_pass"]);
639
+            $auth_login = htmlspecialchars($row["auth_login"]);
640
+            $auth_pass = htmlspecialchars($row["auth_pass"]);
641 641
 
642
-			$auth_enabled = $auth_login !== '' || $auth_pass !== '';
642
+            $auth_enabled = $auth_login !== '' || $auth_pass !== '';
643 643
 
644
-			$auth_style = $auth_enabled ? '' : 'display: none';
645
-			print "<div id='feedEditDlg_loginContainer' style='$auth_style'>";
646
-			print "<header>".__("Authentication")."</header>";
647
-			print "<section>";
644
+            $auth_style = $auth_enabled ? '' : 'display: none';
645
+            print "<div id='feedEditDlg_loginContainer' style='$auth_style'>";
646
+            print "<header>".__("Authentication")."</header>";
647
+            print "<section>";
648 648
 
649
-			print "<fieldset>";
649
+            print "<fieldset>";
650 650
 
651
-			print "<input dojoType='dijit.form.TextBox' id='feedEditDlg_login'
651
+            print "<input dojoType='dijit.form.TextBox' id='feedEditDlg_login'
652 652
 				placeHolder='".__("Login")."'
653 653
 				autocomplete='new-password'
654 654
 				name='auth_login' value=\"$auth_login\">";
655 655
 
656
-			print "</fieldset><fieldset>";
656
+            print "</fieldset><fieldset>";
657 657
 
658
-			print "<input dojoType='dijit.form.TextBox' type='password' name='auth_pass'
658
+            print "<input dojoType='dijit.form.TextBox' type='password' name='auth_pass'
659 659
 				autocomplete='new-password'
660 660
 				placeHolder='".__("Password")."'
661 661
 				value=\"$auth_pass\">";
662 662
 
663
-			print "<div dojoType='dijit.Tooltip' connectId='feedEditDlg_login' position='below'>
663
+            print "<div dojoType='dijit.Tooltip' connectId='feedEditDlg_login' position='below'>
664 664
 				".__('<b>Hint:</b> you need to fill in your login information if your feed requires authentication, except for Twitter feeds.')."
665 665
 				</div>";
666 666
 
667
-			print "</fieldset>";
667
+            print "</fieldset>";
668 668
 
669
-			print "</section></div>";
669
+            print "</section></div>";
670 670
 
671
-			$auth_checked = $auth_enabled ? 'checked' : '';
672
-			print "<label class='checkbox'>
671
+            $auth_checked = $auth_enabled ? 'checked' : '';
672
+            print "<label class='checkbox'>
673 673
 				<input type='checkbox' $auth_checked name='need_auth' dojoType='dijit.form.CheckBox' id='feedEditDlg_loginCheck'
674 674
 						onclick='displayIfChecked(this, \"feedEditDlg_loginContainer\")'>
675 675
 					".__('This feed requires authentication.')."</label>";
676 676
 
677
-			print '</div><div dojoType="dijit.layout.ContentPane" title="'.__('Options').'">';
677
+            print '</div><div dojoType="dijit.layout.ContentPane" title="'.__('Options').'">';
678 678
 
679
-			print "<section class='narrow'>";
679
+            print "<section class='narrow'>";
680 680
 
681
-			$include_in_digest = $row["include_in_digest"];
681
+            $include_in_digest = $row["include_in_digest"];
682 682
 
683
-			if ($include_in_digest) {
684
-				$checked = "checked=\"1\"";
685
-			} else {
686
-				$checked = "";
687
-			}
683
+            if ($include_in_digest) {
684
+                $checked = "checked=\"1\"";
685
+            } else {
686
+                $checked = "";
687
+            }
688 688
 
689
-			print "<fieldset class='narrow'>";
689
+            print "<fieldset class='narrow'>";
690 690
 
691
-			print "<label class='checkbox'><input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" id=\"include_in_digest\"
691
+            print "<label class='checkbox'><input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" id=\"include_in_digest\"
692 692
 				name=\"include_in_digest\"
693 693
 				$checked> ".__('Include in e-mail digest')."</label>";
694 694
 
695
-			print "</fieldset>";
695
+            print "</fieldset>";
696 696
 
697
-			$always_display_enclosures = $row["always_display_enclosures"];
697
+            $always_display_enclosures = $row["always_display_enclosures"];
698 698
 
699
-			if ($always_display_enclosures) {
700
-				$checked = "checked";
701
-			} else {
702
-				$checked = "";
703
-			}
699
+            if ($always_display_enclosures) {
700
+                $checked = "checked";
701
+            } else {
702
+                $checked = "";
703
+            }
704 704
 
705
-			print "<fieldset class='narrow'>";
705
+            print "<fieldset class='narrow'>";
706 706
 
707
-			print "<label class='checkbox'><input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" id=\"always_display_enclosures\"
707
+            print "<label class='checkbox'><input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" id=\"always_display_enclosures\"
708 708
 				name=\"always_display_enclosures\"
709 709
 				$checked> ".__('Always display image attachments')."</label>";
710 710
 
711
-			print "</fieldset>";
711
+            print "</fieldset>";
712 712
 
713
-			$hide_images = $row["hide_images"];
713
+            $hide_images = $row["hide_images"];
714 714
 
715
-			if ($hide_images) {
716
-				$checked = "checked=\"1\"";
717
-			} else {
718
-				$checked = "";
719
-			}
715
+            if ($hide_images) {
716
+                $checked = "checked=\"1\"";
717
+            } else {
718
+                $checked = "";
719
+            }
720 720
 
721
-			print "<fieldset class='narrow'>";
721
+            print "<fieldset class='narrow'>";
722 722
 
723
-			print "<label class='checkbox'><input dojoType='dijit.form.CheckBox' type='checkbox' id='hide_images'
723
+            print "<label class='checkbox'><input dojoType='dijit.form.CheckBox' type='checkbox' id='hide_images'
724 724
 				name='hide_images' $checked> ".__('Do not embed media')."</label>";
725 725
 
726
-			print "</fieldset>";
726
+            print "</fieldset>";
727 727
 
728
-			$cache_images = $row["cache_images"];
728
+            $cache_images = $row["cache_images"];
729 729
 
730
-			if ($cache_images) {
731
-				$checked = "checked=\"1\"";
732
-			} else {
733
-				$checked = "";
734
-			}
730
+            if ($cache_images) {
731
+                $checked = "checked=\"1\"";
732
+            } else {
733
+                $checked = "";
734
+            }
735 735
 
736
-			print "<fieldset class='narrow'>";
736
+            print "<fieldset class='narrow'>";
737 737
 
738
-			print "<label class='checkbox'><input dojoType='dijit.form.CheckBox' type='checkbox' id='cache_images'
738
+            print "<label class='checkbox'><input dojoType='dijit.form.CheckBox' type='checkbox' id='cache_images'
739 739
 				name='cache_images' $checked> ". __('Cache media')."</label>";
740 740
 
741
-			print "</fieldset>";
741
+            print "</fieldset>";
742 742
 
743
-			$mark_unread_on_update = $row["mark_unread_on_update"];
743
+            $mark_unread_on_update = $row["mark_unread_on_update"];
744 744
 
745
-			if ($mark_unread_on_update) {
746
-				$checked = "checked";
747
-			} else {
748
-				$checked = "";
749
-			}
745
+            if ($mark_unread_on_update) {
746
+                $checked = "checked";
747
+            } else {
748
+                $checked = "";
749
+            }
750 750
 
751
-			print "<fieldset class='narrow'>";
751
+            print "<fieldset class='narrow'>";
752 752
 
753
-			print "<label class='checkbox'><input dojoType='dijit.form.CheckBox' type='checkbox' id='mark_unread_on_update'
753
+            print "<label class='checkbox'><input dojoType='dijit.form.CheckBox' type='checkbox' id='mark_unread_on_update'
754 754
 				name='mark_unread_on_update' $checked> ".__('Mark updated articles as unread')."</label>";
755 755
 
756
-			print "</fieldset>";
756
+            print "</fieldset>";
757 757
 
758
-			print '</div><div dojoType="dijit.layout.ContentPane" title="'.__('Icon').'">';
758
+            print '</div><div dojoType="dijit.layout.ContentPane" title="'.__('Icon').'">';
759 759
 
760
-			/* Icon */
760
+            /* Icon */
761 761
 
762
-			print "<img class='feedIcon feed-editor-icon' src=\"".Feeds::getFeedIcon($feed_id)."\">";
762
+            print "<img class='feedIcon feed-editor-icon' src=\"".Feeds::getFeedIcon($feed_id)."\">";
763 763
 
764
-			print "<form onsubmit='return false;' id='feed_icon_upload_form'
764
+            print "<form onsubmit='return false;' id='feed_icon_upload_form'
765 765
 				enctype='multipart/form-data' method='POST'>
766 766
 			<label class='dijitButton'>".__("Choose file...")."
767 767
 				<input style='display: none' id='icon_file' size='10' name='icon_file' type='file'>
@@ -775,231 +775,231 @@  discard block
 block discarded – undo
775 775
 				type='submit'>".__('Remove')."</button>
776 776
 			</form>";
777 777
 
778
-			print "</section>";
778
+            print "</section>";
779 779
 
780
-			print '</div><div dojoType="dijit.layout.ContentPane" title="'.__('Plugins').'">';
780
+            print '</div><div dojoType="dijit.layout.ContentPane" title="'.__('Plugins').'">';
781 781
 
782
-			PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_EDIT_FEED,
783
-				"hook_prefs_edit_feed", $feed_id);
782
+            PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_EDIT_FEED,
783
+                "hook_prefs_edit_feed", $feed_id);
784 784
 
785
-			print "</div></div>";
785
+            print "</div></div>";
786 786
 
787
-			$title = htmlspecialchars($title, ENT_QUOTES);
787
+            $title = htmlspecialchars($title, ENT_QUOTES);
788 788
 
789
-			print "<footer>
789
+            print "<footer>
790 790
 				<button style='float : left' class='alt-danger' dojoType='dijit.form.Button' onclick='return CommonDialogs.unsubscribeFeed($feed_id, \"$title\")'>".
791
-					__('Unsubscribe')."</button>
791
+                    __('Unsubscribe')."</button>
792 792
 				<button dojoType='dijit.form.Button' class='alt-primary' onclick=\"return dijit.byId('feedEditDlg').execute()\">".__('Save')."</button>
793 793
 				<button dojoType='dijit.form.Button' onclick=\"return dijit.byId('feedEditDlg').hide()\">".__('Cancel')."</button>
794 794
 				</footer>";
795
-		}
796
-	}
795
+        }
796
+    }
797 797
 
798
-	public function editfeeds() {
799
-		global $purge_intervals;
800
-		global $update_intervals;
798
+    public function editfeeds() {
799
+        global $purge_intervals;
800
+        global $update_intervals;
801 801
 
802
-		$feed_ids = clean($_REQUEST["ids"]);
802
+        $feed_ids = clean($_REQUEST["ids"]);
803 803
 
804
-		print_notice("Enable the options you wish to apply using checkboxes on the right:");
804
+        print_notice("Enable the options you wish to apply using checkboxes on the right:");
805 805
 
806
-		print "<p>";
806
+        print "<p>";
807 807
 
808
-		print_hidden("ids", "$feed_ids");
809
-		print_hidden("op", "pref-feeds");
810
-		print_hidden("method", "batchEditSave");
808
+        print_hidden("ids", "$feed_ids");
809
+        print_hidden("op", "pref-feeds");
810
+        print_hidden("method", "batchEditSave");
811 811
 
812
-		print "<header>".__("Feed")."</header>";
813
-		print "<section>";
812
+        print "<header>".__("Feed")."</header>";
813
+        print "<section>";
814 814
 
815
-		/* Category */
815
+        /* Category */
816 816
 
817
-		if (get_pref('ENABLE_FEED_CATS')) {
817
+        if (get_pref('ENABLE_FEED_CATS')) {
818 818
 
819
-			print "<fieldset>";
819
+            print "<fieldset>";
820 820
 
821
-			print "<label>" . __('Place in category:') . "</label> ";
821
+            print "<label>" . __('Place in category:') . "</label> ";
822 822
 
823
-			print_feed_cat_select("cat_id", false,
824
-				'disabled="1" dojoType="fox.form.Select"');
823
+            print_feed_cat_select("cat_id", false,
824
+                'disabled="1" dojoType="fox.form.Select"');
825 825
 
826
-			$this->batch_edit_cbox("cat_id");
826
+            $this->batch_edit_cbox("cat_id");
827 827
 
828
-			print "</fieldset>";
829
-		}
828
+            print "</fieldset>";
829
+        }
830 830
 
831
-		/* FTS Stemming Language */
831
+        /* FTS Stemming Language */
832 832
 
833
-		if (DB_TYPE == "pgsql") {
834
-			print "<fieldset>";
833
+        if (DB_TYPE == "pgsql") {
834
+            print "<fieldset>";
835 835
 
836
-			print "<label>" . __('Language:') . "</label> ";
837
-			print_select("feed_language", "", $this::get_ts_languages(),
838
-				'disabled="1" dojoType="fox.form.Select"');
836
+            print "<label>" . __('Language:') . "</label> ";
837
+            print_select("feed_language", "", $this::get_ts_languages(),
838
+                'disabled="1" dojoType="fox.form.Select"');
839 839
 
840
-			$this->batch_edit_cbox("feed_language");
840
+            $this->batch_edit_cbox("feed_language");
841 841
 
842
-			print "</fieldset>";
843
-		}
842
+            print "</fieldset>";
843
+        }
844 844
 
845
-		print "</section>";
845
+        print "</section>";
846 846
 
847
-		print "<header>".__("Update")."</header>";
848
-		print "<section>";
847
+        print "<header>".__("Update")."</header>";
848
+        print "<section>";
849 849
 
850
-		/* Update Interval */
850
+        /* Update Interval */
851 851
 
852
-		print "<fieldset>";
852
+        print "<fieldset>";
853 853
 
854
-		print "<label>".__("Interval:")."</label> ";
854
+        print "<label>".__("Interval:")."</label> ";
855 855
 
856
-		print_select_hash("update_interval", "", $update_intervals,
857
-			'disabled="1" dojoType="fox.form.Select"');
856
+        print_select_hash("update_interval", "", $update_intervals,
857
+            'disabled="1" dojoType="fox.form.Select"');
858 858
 
859
-		$this->batch_edit_cbox("update_interval");
859
+        $this->batch_edit_cbox("update_interval");
860 860
 
861
-		print "</fieldset>";
861
+        print "</fieldset>";
862 862
 
863
-		/* Purge intl */
863
+        /* Purge intl */
864 864
 
865
-		if (FORCE_ARTICLE_PURGE == 0) {
865
+        if (FORCE_ARTICLE_PURGE == 0) {
866 866
 
867
-			print "<fieldset>";
867
+            print "<fieldset>";
868 868
 
869
-			print "<label>" . __('Article purging:') . "</label> ";
869
+            print "<label>" . __('Article purging:') . "</label> ";
870 870
 
871
-			print_select_hash("purge_interval", "", $purge_intervals,
872
-				'disabled="1" dojoType="fox.form.Select"');
871
+            print_select_hash("purge_interval", "", $purge_intervals,
872
+                'disabled="1" dojoType="fox.form.Select"');
873 873
 
874
-			$this->batch_edit_cbox("purge_interval");
874
+            $this->batch_edit_cbox("purge_interval");
875 875
 
876
-			print "</fieldset>";
877
-		}
876
+            print "</fieldset>";
877
+        }
878 878
 
879
-		print "</section>";
880
-		print "<header>".__("Authentication")."</header>";
881
-		print "<section>";
879
+        print "</section>";
880
+        print "<header>".__("Authentication")."</header>";
881
+        print "<section>";
882 882
 
883
-		print "<fieldset>";
883
+        print "<fieldset>";
884 884
 
885
-		print "<input dojoType='dijit.form.TextBox'
885
+        print "<input dojoType='dijit.form.TextBox'
886 886
 			placeHolder=\"".__("Login")."\" disabled='1'
887 887
 			autocomplete='new-password'
888 888
 			name='auth_login' value=''>";
889 889
 
890
-		$this->batch_edit_cbox("auth_login");
890
+        $this->batch_edit_cbox("auth_login");
891 891
 
892
-		print "<input dojoType='dijit.form.TextBox' type='password' name='auth_pass'
892
+        print "<input dojoType='dijit.form.TextBox' type='password' name='auth_pass'
893 893
 			autocomplete='new-password'
894 894
 			placeHolder=\"".__("Password")."\" disabled='1'
895 895
 			value=''>";
896 896
 
897
-		$this->batch_edit_cbox("auth_pass");
897
+        $this->batch_edit_cbox("auth_pass");
898 898
 
899
-		print "</fieldset>";
899
+        print "</fieldset>";
900 900
 
901
-		print "</section>";
902
-		print "<header>".__("Options")."</header>";
903
-		print "<section>";
901
+        print "</section>";
902
+        print "<header>".__("Options")."</header>";
903
+        print "<section>";
904 904
 
905
-		print "<fieldset class='narrow'>";
906
-		print "<label class='checkbox'><input disabled='1' type='checkbox' id='include_in_digest'
905
+        print "<fieldset class='narrow'>";
906
+        print "<label class='checkbox'><input disabled='1' type='checkbox' id='include_in_digest'
907 907
 			name='include_in_digest' dojoType='dijit.form.CheckBox'>&nbsp;".__('Include in e-mail digest')."</label>";
908 908
 
909
-		print "&nbsp;"; $this->batch_edit_cbox("include_in_digest", "include_in_digest_l");
909
+        print "&nbsp;"; $this->batch_edit_cbox("include_in_digest", "include_in_digest_l");
910 910
 
911
-		print "</fieldset><fieldset class='narrow'>";
911
+        print "</fieldset><fieldset class='narrow'>";
912 912
 
913
-		print "<label class='checkbox'><input disabled='1' type='checkbox' id='always_display_enclosures'
913
+        print "<label class='checkbox'><input disabled='1' type='checkbox' id='always_display_enclosures'
914 914
 			name='always_display_enclosures' dojoType='dijit.form.CheckBox'>&nbsp;".__('Always display image attachments')."</label>";
915 915
 
916
-		print "&nbsp;"; $this->batch_edit_cbox("always_display_enclosures", "always_display_enclosures_l");
916
+        print "&nbsp;"; $this->batch_edit_cbox("always_display_enclosures", "always_display_enclosures_l");
917 917
 
918
-		print "</fieldset><fieldset class='narrow'>";
918
+        print "</fieldset><fieldset class='narrow'>";
919 919
 
920
-		print "<label class='checkbox'><input disabled='1' type='checkbox' id='hide_images'
920
+        print "<label class='checkbox'><input disabled='1' type='checkbox' id='hide_images'
921 921
 			name='hide_images' dojoType='dijit.form.CheckBox'>&nbsp;". __('Do not embed media')."</label>";
922 922
 
923
-		print "&nbsp;"; $this->batch_edit_cbox("hide_images", "hide_images_l");
923
+        print "&nbsp;"; $this->batch_edit_cbox("hide_images", "hide_images_l");
924 924
 
925
-		print "</fieldset><fieldset class='narrow'>";
925
+        print "</fieldset><fieldset class='narrow'>";
926 926
 
927
-		print "<label class='checkbox'><input disabled='1' type='checkbox' id='cache_images'
927
+        print "<label class='checkbox'><input disabled='1' type='checkbox' id='cache_images'
928 928
 			name='cache_images' dojoType='dijit.form.CheckBox'>&nbsp;".__('Cache media')."</label>";
929 929
 
930
-		print "&nbsp;"; $this->batch_edit_cbox("cache_images", "cache_images_l");
930
+        print "&nbsp;"; $this->batch_edit_cbox("cache_images", "cache_images_l");
931 931
 
932
-		print "</fieldset><fieldset class='narrow'>";
932
+        print "</fieldset><fieldset class='narrow'>";
933 933
 
934
-		print "<label class='checkbox'><input disabled='1' type='checkbox' id='mark_unread_on_update'
934
+        print "<label class='checkbox'><input disabled='1' type='checkbox' id='mark_unread_on_update'
935 935
 			name='mark_unread_on_update' dojoType='dijit.form.CheckBox'>&nbsp;".__('Mark updated articles as unread')."</label>";
936 936
 
937
-		print "&nbsp;"; $this->batch_edit_cbox("mark_unread_on_update", "mark_unread_on_update_l");
937
+        print "&nbsp;"; $this->batch_edit_cbox("mark_unread_on_update", "mark_unread_on_update_l");
938 938
 
939
-		print "</fieldset>";
939
+        print "</fieldset>";
940 940
 
941
-		print "</section>";
941
+        print "</section>";
942 942
 
943
-		print "<footer>
943
+        print "<footer>
944 944
 			<button dojoType='dijit.form.Button' type='submit' class='alt-primary'
945 945
 				onclick=\"return dijit.byId('feedEditDlg').execute()\">".
946
-				__('Save')."</button>
946
+                __('Save')."</button>
947 947
 			<button dojoType='dijit.form.Button'
948 948
 			onclick=\"return dijit.byId('feedEditDlg').hide()\">".
949
-				__('Cancel')."</button>
949
+                __('Cancel')."</button>
950 950
 			</footer>";
951 951
 
952
-		return;
953
-	}
954
-
955
-	public function batchEditSave() {
956
-		return $this->editsaveops(true);
957
-	}
958
-
959
-	public function editSave() {
960
-		return $this->editsaveops(false);
961
-	}
962
-
963
-	public function editsaveops($batch) {
964
-
965
-		$feed_title = trim(clean($_POST["title"]));
966
-		$feed_url = trim(clean($_POST["feed_url"]));
967
-		$site_url = trim(clean($_POST["site_url"]));
968
-		$upd_intl = (int) clean($_POST["update_interval"]);
969
-		$purge_intl = (int) clean($_POST["purge_interval"]);
970
-		$feed_id = (int) clean($_POST["id"]); /* editSave */
971
-		$feed_ids = explode(",", clean($_POST["ids"])); /* batchEditSave */
972
-		$cat_id = (int) clean($_POST["cat_id"]);
973
-		$auth_login = trim(clean($_POST["auth_login"]));
974
-		$auth_pass = trim(clean($_POST["auth_pass"]));
975
-		$private = checkbox_to_sql_bool(clean($_POST["private"]));
976
-		$include_in_digest = checkbox_to_sql_bool(
977
-			clean($_POST["include_in_digest"]));
978
-		$cache_images = checkbox_to_sql_bool(
979
-			clean($_POST["cache_images"]));
980
-		$hide_images = checkbox_to_sql_bool(
981
-			clean($_POST["hide_images"]));
982
-		$always_display_enclosures = checkbox_to_sql_bool(
983
-			clean($_POST["always_display_enclosures"]));
984
-
985
-		$mark_unread_on_update = checkbox_to_sql_bool(
986
-			clean($_POST["mark_unread_on_update"]));
987
-
988
-		$feed_language = trim(clean($_POST["feed_language"]));
989
-
990
-		if (!$batch) {
991
-			if (clean($_POST["need_auth"]) !== 'on') {
992
-				$auth_login = '';
993
-				$auth_pass = '';
994
-			}
995
-
996
-			/* $sth = $this->pdo->prepare("SELECT feed_url FROM ttrss_feeds WHERE id = ?");
952
+        return;
953
+    }
954
+
955
+    public function batchEditSave() {
956
+        return $this->editsaveops(true);
957
+    }
958
+
959
+    public function editSave() {
960
+        return $this->editsaveops(false);
961
+    }
962
+
963
+    public function editsaveops($batch) {
964
+
965
+        $feed_title = trim(clean($_POST["title"]));
966
+        $feed_url = trim(clean($_POST["feed_url"]));
967
+        $site_url = trim(clean($_POST["site_url"]));
968
+        $upd_intl = (int) clean($_POST["update_interval"]);
969
+        $purge_intl = (int) clean($_POST["purge_interval"]);
970
+        $feed_id = (int) clean($_POST["id"]); /* editSave */
971
+        $feed_ids = explode(",", clean($_POST["ids"])); /* batchEditSave */
972
+        $cat_id = (int) clean($_POST["cat_id"]);
973
+        $auth_login = trim(clean($_POST["auth_login"]));
974
+        $auth_pass = trim(clean($_POST["auth_pass"]));
975
+        $private = checkbox_to_sql_bool(clean($_POST["private"]));
976
+        $include_in_digest = checkbox_to_sql_bool(
977
+            clean($_POST["include_in_digest"]));
978
+        $cache_images = checkbox_to_sql_bool(
979
+            clean($_POST["cache_images"]));
980
+        $hide_images = checkbox_to_sql_bool(
981
+            clean($_POST["hide_images"]));
982
+        $always_display_enclosures = checkbox_to_sql_bool(
983
+            clean($_POST["always_display_enclosures"]));
984
+
985
+        $mark_unread_on_update = checkbox_to_sql_bool(
986
+            clean($_POST["mark_unread_on_update"]));
987
+
988
+        $feed_language = trim(clean($_POST["feed_language"]));
989
+
990
+        if (!$batch) {
991
+            if (clean($_POST["need_auth"]) !== 'on') {
992
+                $auth_login = '';
993
+                $auth_pass = '';
994
+            }
995
+
996
+            /* $sth = $this->pdo->prepare("SELECT feed_url FROM ttrss_feeds WHERE id = ?");
997 997
 			$sth->execute([$feed_id]);
998 998
 			$row = $sth->fetch();$orig_feed_url = $row["feed_url"];
999 999
 
1000 1000
 			$reset_basic_info = $orig_feed_url != $feed_url; */
1001 1001
 
1002
-			$sth = $this->pdo->prepare("UPDATE ttrss_feeds SET
1002
+            $sth = $this->pdo->prepare("UPDATE ttrss_feeds SET
1003 1003
 				cat_id = :cat_id,
1004 1004
 				title = :title,
1005 1005
 				feed_url = :feed_url,
@@ -1018,253 +1018,253 @@  discard block
 block discarded – undo
1018 1018
 				feed_language = :feed_language
1019 1019
 			WHERE id = :id AND owner_uid = :uid");
1020 1020
 
1021
-			$sth->execute([":title" => $feed_title,
1022
-					":cat_id" => $cat_id ? $cat_id : null,
1023
-					":feed_url" => $feed_url,
1024
-					":site_url" => $site_url,
1025
-					":upd_intl" => $upd_intl,
1026
-					":purge_intl" => $purge_intl,
1027
-					":auth_login" => $auth_login,
1028
-					":auth_pass" => $auth_pass,
1029
-					":private" => (int)$private,
1030
-					":cache_images" => (int)$cache_images,
1031
-					":hide_images" => (int)$hide_images,
1032
-					":include_in_digest" => (int)$include_in_digest,
1033
-					":always_display_enclosures" => (int)$always_display_enclosures,
1034
-					":mark_unread_on_update" => (int)$mark_unread_on_update,
1035
-					":feed_language" => $feed_language,
1036
-					":id" => $feed_id,
1037
-					":uid" => $_SESSION['uid']]);
1021
+            $sth->execute([":title" => $feed_title,
1022
+                    ":cat_id" => $cat_id ? $cat_id : null,
1023
+                    ":feed_url" => $feed_url,
1024
+                    ":site_url" => $site_url,
1025
+                    ":upd_intl" => $upd_intl,
1026
+                    ":purge_intl" => $purge_intl,
1027
+                    ":auth_login" => $auth_login,
1028
+                    ":auth_pass" => $auth_pass,
1029
+                    ":private" => (int)$private,
1030
+                    ":cache_images" => (int)$cache_images,
1031
+                    ":hide_images" => (int)$hide_images,
1032
+                    ":include_in_digest" => (int)$include_in_digest,
1033
+                    ":always_display_enclosures" => (int)$always_display_enclosures,
1034
+                    ":mark_unread_on_update" => (int)$mark_unread_on_update,
1035
+                    ":feed_language" => $feed_language,
1036
+                    ":id" => $feed_id,
1037
+                    ":uid" => $_SESSION['uid']]);
1038 1038
 
1039 1039
 /*			if ($reset_basic_info) {
1040 1040
 				RSSUtils::set_basic_feed_info($feed_id);
1041 1041
 			} */
1042 1042
 
1043
-			PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_SAVE_FEED,
1044
-				"hook_prefs_save_feed", $feed_id);
1043
+            PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_SAVE_FEED,
1044
+                "hook_prefs_save_feed", $feed_id);
1045 1045
 
1046
-		} else {
1047
-			$feed_data = array();
1046
+        } else {
1047
+            $feed_data = array();
1048 1048
 
1049
-			foreach (array_keys($_POST) as $k) {
1050
-				if ($k != "op" && $k != "method" && $k != "ids") {
1051
-					$feed_data[$k] = clean($_POST[$k]);
1052
-				}
1053
-			}
1049
+            foreach (array_keys($_POST) as $k) {
1050
+                if ($k != "op" && $k != "method" && $k != "ids") {
1051
+                    $feed_data[$k] = clean($_POST[$k]);
1052
+                }
1053
+            }
1054 1054
 
1055
-			$this->pdo->beginTransaction();
1055
+            $this->pdo->beginTransaction();
1056 1056
 
1057
-			$feed_ids_qmarks = arr_qmarks($feed_ids);
1057
+            $feed_ids_qmarks = arr_qmarks($feed_ids);
1058 1058
 
1059
-			foreach (array_keys($feed_data) as $k) {
1059
+            foreach (array_keys($feed_data) as $k) {
1060 1060
 
1061
-				$qpart = "";
1061
+                $qpart = "";
1062 1062
 
1063
-				switch ($k) {
1064
-					case "title":
1065
-						$qpart = "title = " . $this->pdo->quote($feed_title);
1066
-						break;
1063
+                switch ($k) {
1064
+                    case "title":
1065
+                        $qpart = "title = " . $this->pdo->quote($feed_title);
1066
+                        break;
1067 1067
 
1068
-					case "feed_url":
1069
-						$qpart = "feed_url = " . $this->pdo->quote($feed_url);
1070
-						break;
1068
+                    case "feed_url":
1069
+                        $qpart = "feed_url = " . $this->pdo->quote($feed_url);
1070
+                        break;
1071 1071
 
1072
-					case "update_interval":
1073
-						$qpart = "update_interval = " . $this->pdo->quote($upd_intl);
1074
-						break;
1072
+                    case "update_interval":
1073
+                        $qpart = "update_interval = " . $this->pdo->quote($upd_intl);
1074
+                        break;
1075 1075
 
1076
-					case "purge_interval":
1077
-						$qpart = "purge_interval =" . $this->pdo->quote($purge_intl);
1078
-						break;
1076
+                    case "purge_interval":
1077
+                        $qpart = "purge_interval =" . $this->pdo->quote($purge_intl);
1078
+                        break;
1079 1079
 
1080
-					case "auth_login":
1081
-						$qpart = "auth_login = " . $this->pdo->quote($auth_login);
1082
-						break;
1080
+                    case "auth_login":
1081
+                        $qpart = "auth_login = " . $this->pdo->quote($auth_login);
1082
+                        break;
1083 1083
 
1084
-					case "auth_pass":
1085
-						$qpart = "auth_pass =" . $this->pdo->quote($auth_pass). ", auth_pass_encrypted = false";
1086
-						break;
1084
+                    case "auth_pass":
1085
+                        $qpart = "auth_pass =" . $this->pdo->quote($auth_pass). ", auth_pass_encrypted = false";
1086
+                        break;
1087 1087
 
1088
-					case "private":
1089
-						$qpart = "private = " . $this->pdo->quote($private);
1090
-						break;
1088
+                    case "private":
1089
+                        $qpart = "private = " . $this->pdo->quote($private);
1090
+                        break;
1091 1091
 
1092
-					case "include_in_digest":
1093
-						$qpart = "include_in_digest = " . $this->pdo->quote($include_in_digest);
1094
-						break;
1092
+                    case "include_in_digest":
1093
+                        $qpart = "include_in_digest = " . $this->pdo->quote($include_in_digest);
1094
+                        break;
1095 1095
 
1096
-					case "always_display_enclosures":
1097
-						$qpart = "always_display_enclosures = " . $this->pdo->quote($always_display_enclosures);
1098
-						break;
1096
+                    case "always_display_enclosures":
1097
+                        $qpart = "always_display_enclosures = " . $this->pdo->quote($always_display_enclosures);
1098
+                        break;
1099 1099
 
1100
-					case "mark_unread_on_update":
1101
-						$qpart = "mark_unread_on_update = " . $this->pdo->quote($mark_unread_on_update);
1102
-						break;
1100
+                    case "mark_unread_on_update":
1101
+                        $qpart = "mark_unread_on_update = " . $this->pdo->quote($mark_unread_on_update);
1102
+                        break;
1103 1103
 
1104
-					case "cache_images":
1105
-						$qpart = "cache_images = " . $this->pdo->quote($cache_images);
1106
-						break;
1104
+                    case "cache_images":
1105
+                        $qpart = "cache_images = " . $this->pdo->quote($cache_images);
1106
+                        break;
1107 1107
 
1108
-					case "hide_images":
1109
-						$qpart = "hide_images = " . $this->pdo->quote($hide_images);
1110
-						break;
1108
+                    case "hide_images":
1109
+                        $qpart = "hide_images = " . $this->pdo->quote($hide_images);
1110
+                        break;
1111 1111
 
1112
-					case "cat_id":
1113
-						if (get_pref('ENABLE_FEED_CATS')) {
1114
-							if ($cat_id) {
1115
-								$qpart = "cat_id = " . $this->pdo->quote($cat_id);
1116
-							} else {
1117
-								$qpart = 'cat_id = NULL';
1118
-							}
1119
-						} else {
1120
-							$qpart = "";
1121
-						}
1112
+                    case "cat_id":
1113
+                        if (get_pref('ENABLE_FEED_CATS')) {
1114
+                            if ($cat_id) {
1115
+                                $qpart = "cat_id = " . $this->pdo->quote($cat_id);
1116
+                            } else {
1117
+                                $qpart = 'cat_id = NULL';
1118
+                            }
1119
+                        } else {
1120
+                            $qpart = "";
1121
+                        }
1122 1122
 
1123
-						break;
1123
+                        break;
1124 1124
 
1125
-					case "feed_language":
1126
-						$qpart = "feed_language = " . $this->pdo->quote($feed_language);
1127
-						break;
1125
+                    case "feed_language":
1126
+                        $qpart = "feed_language = " . $this->pdo->quote($feed_language);
1127
+                        break;
1128 1128
 
1129
-				}
1129
+                }
1130 1130
 
1131
-				if ($qpart) {
1132
-					$sth = $this->pdo->prepare("UPDATE ttrss_feeds SET $qpart WHERE id IN ($feed_ids_qmarks)
1131
+                if ($qpart) {
1132
+                    $sth = $this->pdo->prepare("UPDATE ttrss_feeds SET $qpart WHERE id IN ($feed_ids_qmarks)
1133 1133
 						AND owner_uid = ?");
1134
-					$sth->execute(array_merge($feed_ids, [$_SESSION['uid']]));
1135
-				}
1136
-			}
1134
+                    $sth->execute(array_merge($feed_ids, [$_SESSION['uid']]));
1135
+                }
1136
+            }
1137 1137
 
1138
-			$this->pdo->commit();
1139
-		}
1140
-		return;
1141
-	}
1138
+            $this->pdo->commit();
1139
+        }
1140
+        return;
1141
+    }
1142 1142
 
1143
-	public function remove() {
1143
+    public function remove() {
1144 1144
 
1145
-		$ids = explode(",", clean($_REQUEST["ids"]));
1145
+        $ids = explode(",", clean($_REQUEST["ids"]));
1146 1146
 
1147
-		foreach ($ids as $id) {
1148
-			Pref_Feeds::remove_feed($id, $_SESSION["uid"]);
1149
-		}
1147
+        foreach ($ids as $id) {
1148
+            Pref_Feeds::remove_feed($id, $_SESSION["uid"]);
1149
+        }
1150 1150
 
1151
-		return;
1152
-	}
1151
+        return;
1152
+    }
1153 1153
 
1154
-	public function removeCat() {
1155
-		$ids = explode(",", clean($_REQUEST["ids"]));
1156
-		foreach ($ids as $id) {
1157
-			$this->remove_feed_category($id, $_SESSION["uid"]);
1158
-		}
1159
-	}
1154
+    public function removeCat() {
1155
+        $ids = explode(",", clean($_REQUEST["ids"]));
1156
+        foreach ($ids as $id) {
1157
+            $this->remove_feed_category($id, $_SESSION["uid"]);
1158
+        }
1159
+    }
1160 1160
 
1161
-	public function addCat() {
1162
-		$feed_cat = trim(clean($_REQUEST["cat"]));
1161
+    public function addCat() {
1162
+        $feed_cat = trim(clean($_REQUEST["cat"]));
1163 1163
 
1164
-		Feeds::add_feed_category($feed_cat);
1165
-	}
1164
+        Feeds::add_feed_category($feed_cat);
1165
+    }
1166 1166
 
1167
-	public function index() {
1167
+    public function index() {
1168 1168
 
1169
-		print "<div dojoType='dijit.layout.AccordionContainer' region='center'>";
1170
-		print "<div style='padding : 0px' dojoType='dijit.layout.AccordionPane'
1169
+        print "<div dojoType='dijit.layout.AccordionContainer' region='center'>";
1170
+        print "<div style='padding : 0px' dojoType='dijit.layout.AccordionPane'
1171 1171
 			title=\"<i class='material-icons'>rss_feed</i> ".__('Feeds')."\">";
1172 1172
 
1173
-		$sth = $this->pdo->prepare("SELECT COUNT(id) AS num_errors
1173
+        $sth = $this->pdo->prepare("SELECT COUNT(id) AS num_errors
1174 1174
 			FROM ttrss_feeds WHERE last_error != '' AND owner_uid = ?");
1175
-		$sth->execute([$_SESSION['uid']]);
1175
+        $sth->execute([$_SESSION['uid']]);
1176 1176
 
1177
-		if ($row = $sth->fetch()) {
1178
-			$num_errors = $row["num_errors"];
1179
-		} else {
1180
-			$num_errors = 0;
1181
-		}
1177
+        if ($row = $sth->fetch()) {
1178
+            $num_errors = $row["num_errors"];
1179
+        } else {
1180
+            $num_errors = 0;
1181
+        }
1182 1182
 
1183
-		if ($num_errors > 0) {
1183
+        if ($num_errors > 0) {
1184 1184
 
1185
-			$error_button = "<button dojoType=\"dijit.form.Button\"
1185
+            $error_button = "<button dojoType=\"dijit.form.Button\"
1186 1186
 			  		onclick=\"CommonDialogs.showFeedsWithErrors()\" id=\"errorButton\">" .
1187
-				__("Feeds with errors") . "</button>";
1188
-		}
1187
+                __("Feeds with errors") . "</button>";
1188
+        }
1189 1189
 
1190
-		$inactive_button = "<button dojoType=\"dijit.form.Button\"
1190
+        $inactive_button = "<button dojoType=\"dijit.form.Button\"
1191 1191
 				id=\"pref_feeds_inactive_btn\"
1192 1192
 				style=\"display : none\"
1193 1193
 				onclick=\"dijit.byId('feedTree').showInactiveFeeds()\">" .
1194
-				__("Inactive feeds") . "</button>";
1194
+                __("Inactive feeds") . "</button>";
1195 1195
 
1196
-		$feed_search = clean($_REQUEST["search"]);
1196
+        $feed_search = clean($_REQUEST["search"]);
1197 1197
 
1198
-		if (array_key_exists("search", $_REQUEST)) {
1199
-			$_SESSION["prefs_feed_search"] = $feed_search;
1200
-		} else {
1201
-			$feed_search = $_SESSION["prefs_feed_search"];
1202
-		}
1198
+        if (array_key_exists("search", $_REQUEST)) {
1199
+            $_SESSION["prefs_feed_search"] = $feed_search;
1200
+        } else {
1201
+            $feed_search = $_SESSION["prefs_feed_search"];
1202
+        }
1203 1203
 
1204
-		print '<div dojoType="dijit.layout.BorderContainer" gutters="false">';
1204
+        print '<div dojoType="dijit.layout.BorderContainer" gutters="false">';
1205 1205
 
1206
-		print "<div region='top' dojoType=\"fox.Toolbar\">"; #toolbar
1206
+        print "<div region='top' dojoType=\"fox.Toolbar\">"; #toolbar
1207 1207
 
1208
-		print "<div style='float : right; padding-right : 4px;'>
1208
+        print "<div style='float : right; padding-right : 4px;'>
1209 1209
 			<input dojoType=\"dijit.form.TextBox\" id=\"feed_search\" size=\"20\" type=\"search\"
1210 1210
 				value=\"$feed_search\">
1211 1211
 			<button dojoType=\"dijit.form.Button\" onclick=\"dijit.byId('feedTree').reload()\">".
1212
-				__('Search')."</button>
1212
+                __('Search')."</button>
1213 1213
 			</div>";
1214 1214
 
1215
-		print "<div dojoType=\"fox.form.DropDownButton\">".
1216
-				"<span>" . __('Select')."</span>";
1217
-		print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
1218
-		print "<div onclick=\"dijit.byId('feedTree').model.setAllChecked(true)\"
1215
+        print "<div dojoType=\"fox.form.DropDownButton\">".
1216
+                "<span>" . __('Select')."</span>";
1217
+        print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
1218
+        print "<div onclick=\"dijit.byId('feedTree').model.setAllChecked(true)\"
1219 1219
 			dojoType=\"dijit.MenuItem\">".__('All')."</div>";
1220
-		print "<div onclick=\"dijit.byId('feedTree').model.setAllChecked(false)\"
1220
+        print "<div onclick=\"dijit.byId('feedTree').model.setAllChecked(false)\"
1221 1221
 			dojoType=\"dijit.MenuItem\">".__('None')."</div>";
1222
-		print "</div></div>";
1222
+        print "</div></div>";
1223 1223
 
1224
-		print "<div dojoType=\"fox.form.DropDownButton\">".
1225
-				"<span>" . __('Feeds')."</span>";
1226
-		print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
1227
-		print "<div onclick=\"CommonDialogs.quickAddFeed()\"
1224
+        print "<div dojoType=\"fox.form.DropDownButton\">".
1225
+                "<span>" . __('Feeds')."</span>";
1226
+        print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
1227
+        print "<div onclick=\"CommonDialogs.quickAddFeed()\"
1228 1228
 			dojoType=\"dijit.MenuItem\">".__('Subscribe to feed')."</div>";
1229
-		print "<div onclick=\"dijit.byId('feedTree').editSelectedFeed()\"
1229
+        print "<div onclick=\"dijit.byId('feedTree').editSelectedFeed()\"
1230 1230
 			dojoType=\"dijit.MenuItem\">".__('Edit selected feeds')."</div>";
1231
-		print "<div onclick=\"dijit.byId('feedTree').resetFeedOrder()\"
1231
+        print "<div onclick=\"dijit.byId('feedTree').resetFeedOrder()\"
1232 1232
 			dojoType=\"dijit.MenuItem\">".__('Reset sort order')."</div>";
1233
-		print "<div onclick=\"dijit.byId('feedTree').batchSubscribe()\"
1233
+        print "<div onclick=\"dijit.byId('feedTree').batchSubscribe()\"
1234 1234
 			dojoType=\"dijit.MenuItem\">".__('Batch subscribe')."</div>";
1235
-		print "<div dojoType=\"dijit.MenuItem\" onclick=\"dijit.byId('feedTree').removeSelectedFeeds()\">"
1236
-			.__('Unsubscribe')."</div> ";
1237
-		print "</div></div>";
1238
-
1239
-		if (get_pref('ENABLE_FEED_CATS')) {
1240
-			print "<div dojoType=\"fox.form.DropDownButton\">".
1241
-					"<span>" . __('Categories')."</span>";
1242
-			print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
1243
-			print "<div onclick=\"dijit.byId('feedTree').createCategory()\"
1235
+        print "<div dojoType=\"dijit.MenuItem\" onclick=\"dijit.byId('feedTree').removeSelectedFeeds()\">"
1236
+            .__('Unsubscribe')."</div> ";
1237
+        print "</div></div>";
1238
+
1239
+        if (get_pref('ENABLE_FEED_CATS')) {
1240
+            print "<div dojoType=\"fox.form.DropDownButton\">".
1241
+                    "<span>" . __('Categories')."</span>";
1242
+            print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
1243
+            print "<div onclick=\"dijit.byId('feedTree').createCategory()\"
1244 1244
 				dojoType=\"dijit.MenuItem\">".__('Add category')."</div>";
1245
-			print "<div onclick=\"dijit.byId('feedTree').resetCatOrder()\"
1245
+            print "<div onclick=\"dijit.byId('feedTree').resetCatOrder()\"
1246 1246
 				dojoType=\"dijit.MenuItem\">".__('Reset sort order')."</div>";
1247
-			print "<div onclick=\"dijit.byId('feedTree').removeSelectedCategories()\"
1247
+            print "<div onclick=\"dijit.byId('feedTree').removeSelectedCategories()\"
1248 1248
 				dojoType=\"dijit.MenuItem\">".__('Remove selected')."</div>";
1249
-			print "</div></div>";
1249
+            print "</div></div>";
1250 1250
 
1251
-		}
1251
+        }
1252 1252
 
1253
-		print $error_button;
1254
-		print $inactive_button;
1253
+        print $error_button;
1254
+        print $inactive_button;
1255 1255
 
1256
-		print "</div>"; # toolbar
1256
+        print "</div>"; # toolbar
1257 1257
 
1258
-		//print '</div>';
1259
-		print '<div style="padding : 0px" dojoType="dijit.layout.ContentPane" region="center">';
1258
+        //print '</div>';
1259
+        print '<div style="padding : 0px" dojoType="dijit.layout.ContentPane" region="center">';
1260 1260
 
1261
-		print "<div id=\"feedlistLoading\">
1261
+        print "<div id=\"feedlistLoading\">
1262 1262
 		<img src='images/indicator_tiny.gif'>".
1263
-		 __("Loading, please wait...")."</div>";
1263
+            __("Loading, please wait...")."</div>";
1264 1264
 
1265
-		$auto_expand = $feed_search != "" ? "true" : "false";
1265
+        $auto_expand = $feed_search != "" ? "true" : "false";
1266 1266
 
1267
-		print "<div dojoType=\"fox.PrefFeedStore\" jsId=\"feedStore\"
1267
+        print "<div dojoType=\"fox.PrefFeedStore\" jsId=\"feedStore\"
1268 1268
 			url=\"backend.php?op=pref-feeds&method=getfeedtree\">
1269 1269
 		</div>
1270 1270
 		<div dojoType=\"lib.CheckBoxStoreModel\" jsId=\"feedModel\" store=\"feedStore\"
@@ -1297,23 +1297,23 @@  discard block
 block discarded – undo
1297 1297
 #			".__('<b>Hint:</b> you can drag feeds and categories around.')."
1298 1298
 #			</div>";
1299 1299
 
1300
-		print '</div>';
1301
-		print '</div>';
1300
+        print '</div>';
1301
+        print '</div>';
1302 1302
 
1303
-		print "</div>"; # feeds pane
1303
+        print "</div>"; # feeds pane
1304 1304
 
1305
-		print "<div dojoType='dijit.layout.AccordionPane'
1305
+        print "<div dojoType='dijit.layout.AccordionPane'
1306 1306
 			title='<i class=\"material-icons\">import_export</i> ".__('OPML')."'>";
1307 1307
 
1308
-		print "<h3>" . __("Using OPML you can export and import your feeds, filters, labels and Tiny Tiny RSS settings.") . "</h3>";
1308
+        print "<h3>" . __("Using OPML you can export and import your feeds, filters, labels and Tiny Tiny RSS settings.") . "</h3>";
1309 1309
 
1310
-		print_notice("Only main settings profile can be migrated using OPML.");
1310
+        print_notice("Only main settings profile can be migrated using OPML.");
1311 1311
 
1312
-		print "<iframe id=\"upload_iframe\"
1312
+        print "<iframe id=\"upload_iframe\"
1313 1313
 			name=\"upload_iframe\" onload=\"Helpers.OPML.onImportComplete(this)\"
1314 1314
 			style=\"width: 400px; height: 100px; display: none;\"></iframe>";
1315 1315
 
1316
-		print "<form  name='opml_form' style='display : inline-block' target='upload_iframe'
1316
+        print "<form  name='opml_form' style='display : inline-block' target='upload_iframe'
1317 1317
 			enctype='multipart/form-data' method='POST'
1318 1318
 			action='backend.php'>
1319 1319
 			<label class='dijitButton'>".__("Choose file...")."
@@ -1322,116 +1322,116 @@  discard block
 block discarded – undo
1322 1322
 			<input type='hidden' name='op' value='dlg'>
1323 1323
 			<input type='hidden' name='method' value='importOpml'>
1324 1324
 			<button dojoType='dijit.form.Button' class='alt-primary' onclick=\"return Helpers.OPML.import();\" type=\"submit\">" .
1325
-			__('Import OPML') . "</button>";
1325
+            __('Import OPML') . "</button>";
1326 1326
 
1327
-		print "</form>";
1327
+        print "</form>";
1328 1328
 
1329
-		print "<form dojoType='dijit.form.Form' id='opmlExportForm' style='display : inline-block'>";
1329
+        print "<form dojoType='dijit.form.Form' id='opmlExportForm' style='display : inline-block'>";
1330 1330
 
1331
-		print "<button dojoType='dijit.form.Button'
1331
+        print "<button dojoType='dijit.form.Button'
1332 1332
 			onclick='Helpers.OPML.export()' >" .
1333
-			__('Export OPML') . "</button>";
1333
+            __('Export OPML') . "</button>";
1334 1334
 
1335
-		print " <label class='checkbox'>";
1336
-		print_checkbox("include_settings", true, "1", "");
1337
-		print " " . __("Include settings");
1338
-		print "</label>";
1335
+        print " <label class='checkbox'>";
1336
+        print_checkbox("include_settings", true, "1", "");
1337
+        print " " . __("Include settings");
1338
+        print "</label>";
1339 1339
 
1340
-		print "</form>";
1340
+        print "</form>";
1341 1341
 
1342
-		print "<p/>";
1342
+        print "<p/>";
1343 1343
 
1344
-		print "<h2>" . __("Published OPML") . "</h2>";
1344
+        print "<h2>" . __("Published OPML") . "</h2>";
1345 1345
 
1346
-		print "<p>" . __('Your OPML can be published publicly and can be subscribed by anyone who knows the URL below.') .
1347
-			" " .
1348
-			__("Published OPML does not include your Tiny Tiny RSS settings, feeds that require authentication or feeds hidden from Popular feeds.") . "</p>";
1346
+        print "<p>" . __('Your OPML can be published publicly and can be subscribed by anyone who knows the URL below.') .
1347
+            " " .
1348
+            __("Published OPML does not include your Tiny Tiny RSS settings, feeds that require authentication or feeds hidden from Popular feeds.") . "</p>";
1349 1349
 
1350
-		print "<button dojoType='dijit.form.Button' class='alt-primary' onclick=\"return App.displayDlg('".__("Public OPML URL")."','pubOPMLUrl')\">".
1351
-			__('Display published OPML URL')."</button> ";
1350
+        print "<button dojoType='dijit.form.Button' class='alt-primary' onclick=\"return App.displayDlg('".__("Public OPML URL")."','pubOPMLUrl')\">".
1351
+            __('Display published OPML URL')."</button> ";
1352 1352
 
1353
-		PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION,
1354
-			"hook_prefs_tab_section", "prefFeedsOPML");
1353
+        PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION,
1354
+            "hook_prefs_tab_section", "prefFeedsOPML");
1355 1355
 
1356
-		print "</div>"; # pane
1356
+        print "</div>"; # pane
1357 1357
 
1358
-		print "<div dojoType=\"dijit.layout.AccordionPane\"
1358
+        print "<div dojoType=\"dijit.layout.AccordionPane\"
1359 1359
 			title=\"<i class='material-icons'>share</i> ".__('Published & shared articles / Generated feeds')."\">";
1360 1360
 
1361
-		print "<h3>" . __('Published articles can be subscribed by anyone who knows the following URL:') . "</h3>";
1361
+        print "<h3>" . __('Published articles can be subscribed by anyone who knows the following URL:') . "</h3>";
1362 1362
 
1363
-		$rss_url = '-2::' . htmlspecialchars(get_self_url_prefix() .
1364
-				"/public.php?op=rss&id=-2&view-mode=all_articles");;
1363
+        $rss_url = '-2::' . htmlspecialchars(get_self_url_prefix() .
1364
+                "/public.php?op=rss&id=-2&view-mode=all_articles");;
1365 1365
 
1366
-		print "<button dojoType='dijit.form.Button' class='alt-primary' onclick=\"return App.displayDlg('".__("Show as feed")."','generatedFeed', '$rss_url')\">".
1367
-			__('Display URL')."</button> ";
1366
+        print "<button dojoType='dijit.form.Button' class='alt-primary' onclick=\"return App.displayDlg('".__("Show as feed")."','generatedFeed', '$rss_url')\">".
1367
+            __('Display URL')."</button> ";
1368 1368
 
1369
-		print "<button class=\"alt-danger\" dojoType=\"dijit.form.Button\" onclick=\"return Helpers.clearFeedAccessKeys()\">".
1370
-			__('Clear all generated URLs')."</button> ";
1369
+        print "<button class=\"alt-danger\" dojoType=\"dijit.form.Button\" onclick=\"return Helpers.clearFeedAccessKeys()\">".
1370
+            __('Clear all generated URLs')."</button> ";
1371 1371
 
1372
-		PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION,
1373
-			"hook_prefs_tab_section", "prefFeedsPublishedGenerated");
1372
+        PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION,
1373
+            "hook_prefs_tab_section", "prefFeedsPublishedGenerated");
1374 1374
 
1375
-		print "</div>"; #pane
1375
+        print "</div>"; #pane
1376 1376
 
1377
-		PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB,
1378
-			"hook_prefs_tab", "prefFeeds");
1377
+        PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB,
1378
+            "hook_prefs_tab", "prefFeeds");
1379 1379
 
1380
-		print "</div>"; #container
1381
-	}
1380
+        print "</div>"; #container
1381
+    }
1382 1382
 
1383
-	private function feedlist_init_cat($cat_id) {
1384
-		$obj = array();
1385
-		$cat_id = (int) $cat_id;
1383
+    private function feedlist_init_cat($cat_id) {
1384
+        $obj = array();
1385
+        $cat_id = (int) $cat_id;
1386 1386
 
1387
-		if ($cat_id > 0) {
1388
-			$cat_unread = CCache::find($cat_id, $_SESSION["uid"], true);
1389
-		} else if ($cat_id == 0 || $cat_id == -2) {
1390
-			$cat_unread = Feeds::getCategoryUnread($cat_id);
1391
-		}
1387
+        if ($cat_id > 0) {
1388
+            $cat_unread = CCache::find($cat_id, $_SESSION["uid"], true);
1389
+        } else if ($cat_id == 0 || $cat_id == -2) {
1390
+            $cat_unread = Feeds::getCategoryUnread($cat_id);
1391
+        }
1392 1392
 
1393
-		$obj['id'] = 'CAT:' . $cat_id;
1394
-		$obj['items'] = array();
1395
-		$obj['name'] = Feeds::getCategoryTitle($cat_id);
1396
-		$obj['type'] = 'category';
1397
-		$obj['unread'] = (int) $cat_unread;
1398
-		$obj['bare_id'] = $cat_id;
1393
+        $obj['id'] = 'CAT:' . $cat_id;
1394
+        $obj['items'] = array();
1395
+        $obj['name'] = Feeds::getCategoryTitle($cat_id);
1396
+        $obj['type'] = 'category';
1397
+        $obj['unread'] = (int) $cat_unread;
1398
+        $obj['bare_id'] = $cat_id;
1399 1399
 
1400
-		return $obj;
1401
-	}
1400
+        return $obj;
1401
+    }
1402 1402
 
1403
-	private function feedlist_init_feed($feed_id, $title = false, $unread = false, $error = '', $updated = '') {
1404
-		$obj = array();
1405
-		$feed_id = (int) $feed_id;
1403
+    private function feedlist_init_feed($feed_id, $title = false, $unread = false, $error = '', $updated = '') {
1404
+        $obj = array();
1405
+        $feed_id = (int) $feed_id;
1406 1406
 
1407
-		if (!$title)
1408
-			$title = Feeds::getFeedTitle($feed_id, false);
1407
+        if (!$title)
1408
+            $title = Feeds::getFeedTitle($feed_id, false);
1409 1409
 
1410
-		if ($unread === false)
1411
-			$unread = getFeedUnread($feed_id, false);
1410
+        if ($unread === false)
1411
+            $unread = getFeedUnread($feed_id, false);
1412 1412
 
1413
-		$obj['id'] = 'FEED:' . $feed_id;
1414
-		$obj['name'] = $title;
1415
-		$obj['unread'] = (int) $unread;
1416
-		$obj['type'] = 'feed';
1417
-		$obj['error'] = $error;
1418
-		$obj['updated'] = $updated;
1419
-		$obj['icon'] = Feeds::getFeedIcon($feed_id);
1420
-		$obj['bare_id'] = $feed_id;
1421
-		$obj['auxcounter'] = 0;
1413
+        $obj['id'] = 'FEED:' . $feed_id;
1414
+        $obj['name'] = $title;
1415
+        $obj['unread'] = (int) $unread;
1416
+        $obj['type'] = 'feed';
1417
+        $obj['error'] = $error;
1418
+        $obj['updated'] = $updated;
1419
+        $obj['icon'] = Feeds::getFeedIcon($feed_id);
1420
+        $obj['bare_id'] = $feed_id;
1421
+        $obj['auxcounter'] = 0;
1422 1422
 
1423
-		return $obj;
1424
-	}
1423
+        return $obj;
1424
+    }
1425 1425
 
1426
-	public function inactiveFeeds() {
1426
+    public function inactiveFeeds() {
1427 1427
 
1428
-		if (DB_TYPE == "pgsql") {
1429
-			$interval_qpart = "NOW() - INTERVAL '3 months'";
1430
-		} else {
1431
-			$interval_qpart = "DATE_SUB(NOW(), INTERVAL 3 MONTH)";
1432
-		}
1428
+        if (DB_TYPE == "pgsql") {
1429
+            $interval_qpart = "NOW() - INTERVAL '3 months'";
1430
+        } else {
1431
+            $interval_qpart = "DATE_SUB(NOW(), INTERVAL 3 MONTH)";
1432
+        }
1433 1433
 
1434
-		$sth = $this->pdo->prepare("SELECT ttrss_feeds.title, ttrss_feeds.site_url,
1434
+        $sth = $this->pdo->prepare("SELECT ttrss_feeds.title, ttrss_feeds.site_url,
1435 1435
 		  		ttrss_feeds.feed_url, ttrss_feeds.id, MAX(updated) AS last_article
1436 1436
 			FROM ttrss_feeds, ttrss_entries, ttrss_user_entries WHERE
1437 1437
 				(SELECT MAX(updated) FROM ttrss_entries, ttrss_user_entries WHERE
@@ -1442,356 +1442,356 @@  discard block
 block discarded – undo
1442 1442
 				ttrss_entries.id = ref_id
1443 1443
 			GROUP BY ttrss_feeds.title, ttrss_feeds.id, ttrss_feeds.site_url, ttrss_feeds.feed_url
1444 1444
 			ORDER BY last_article");
1445
-		$sth->execute([$_SESSION['uid']]);
1445
+        $sth->execute([$_SESSION['uid']]);
1446 1446
 
1447
-		print "<div dojoType='fox.Toolbar'>";
1448
-		print "<div dojoType='fox.form.DropDownButton'>".
1449
-				"<span>" . __('Select')."</span>";
1450
-		print "<div dojoType='dijit.Menu' style='display: none'>";
1451
-		print "<div onclick=\"Tables.select('inactive-feeds-list', true)\"
1447
+        print "<div dojoType='fox.Toolbar'>";
1448
+        print "<div dojoType='fox.form.DropDownButton'>".
1449
+                "<span>" . __('Select')."</span>";
1450
+        print "<div dojoType='dijit.Menu' style='display: none'>";
1451
+        print "<div onclick=\"Tables.select('inactive-feeds-list', true)\"
1452 1452
 			dojoType='dijit.MenuItem'>".__('All')."</div>";
1453
-		print "<div onclick=\"Tables.select('inactive-feeds-list', false)\"
1453
+        print "<div onclick=\"Tables.select('inactive-feeds-list', false)\"
1454 1454
 			dojoType='dijit.MenuItem'>".__('None')."</div>";
1455
-		print "</div></div>";
1456
-		print "</div>"; #toolbar
1455
+        print "</div></div>";
1456
+        print "</div>"; #toolbar
1457 1457
 
1458
-		print "<div class='panel panel-scrollable'>";
1459
-		print "<table width='100%' id='inactive-feeds-list'>";
1458
+        print "<div class='panel panel-scrollable'>";
1459
+        print "<table width='100%' id='inactive-feeds-list'>";
1460 1460
 
1461
-		$lnum = 1;
1461
+        $lnum = 1;
1462 1462
 
1463
-		while ($line = $sth->fetch()) {
1463
+        while ($line = $sth->fetch()) {
1464 1464
 
1465
-			$feed_id = $line["id"];
1465
+            $feed_id = $line["id"];
1466 1466
 
1467
-			print "<tr data-row-id='$feed_id'>";
1467
+            print "<tr data-row-id='$feed_id'>";
1468 1468
 
1469
-			print "<td width='5%' align='center'><input
1469
+            print "<td width='5%' align='center'><input
1470 1470
 				onclick='Tables.onRowChecked(this);' dojoType='dijit.form.CheckBox'
1471 1471
 				type='checkbox'></td>";
1472
-			print "<td>";
1472
+            print "<td>";
1473 1473
 
1474
-			print "<a href='#' ".
1475
-				"title=\"".__("Click to edit feed")."\" ".
1476
-				"onclick=\"CommonDialogs.editFeed(".$line["id"].")\">".
1477
-				htmlspecialchars($line["title"])."</a>";
1474
+            print "<a href='#' ".
1475
+                "title=\"".__("Click to edit feed")."\" ".
1476
+                "onclick=\"CommonDialogs.editFeed(".$line["id"].")\">".
1477
+                htmlspecialchars($line["title"])."</a>";
1478 1478
 
1479
-			print "</td><td class='text-muted' align='right'>";
1480
-			print make_local_datetime($line['last_article'], false);
1481
-			print "</td>";
1482
-			print "</tr>";
1479
+            print "</td><td class='text-muted' align='right'>";
1480
+            print make_local_datetime($line['last_article'], false);
1481
+            print "</td>";
1482
+            print "</tr>";
1483 1483
 
1484
-			++$lnum;
1485
-		}
1484
+            ++$lnum;
1485
+        }
1486 1486
 
1487
-		print "</table>";
1488
-		print "</div>";
1487
+        print "</table>";
1488
+        print "</div>";
1489 1489
 
1490
-		print "<footer>
1490
+        print "<footer>
1491 1491
 			<button style='float : left' class=\"alt-danger\" dojoType='dijit.form.Button' onclick=\"dijit.byId('inactiveFeedsDlg').removeSelected()\">"
1492
-			.__('Unsubscribe from selected feeds')."</button>
1492
+            .__('Unsubscribe from selected feeds')."</button>
1493 1493
 			<button dojoType='dijit.form.Button' onclick=\"dijit.byId('inactiveFeedsDlg').hide()\">"
1494
-			.__('Close this window')."</button>
1494
+            .__('Close this window')."</button>
1495 1495
 			</footer>";
1496 1496
 
1497
-	}
1497
+    }
1498 1498
 
1499
-	public function feedsWithErrors() {
1500
-		$sth = $this->pdo->prepare("SELECT id,title,feed_url,last_error,site_url
1499
+    public function feedsWithErrors() {
1500
+        $sth = $this->pdo->prepare("SELECT id,title,feed_url,last_error,site_url
1501 1501
 			FROM ttrss_feeds WHERE last_error != '' AND owner_uid = ?");
1502
-		$sth->execute([$_SESSION['uid']]);
1502
+        $sth->execute([$_SESSION['uid']]);
1503 1503
 
1504
-		print "<div dojoType=\"fox.Toolbar\">";
1505
-		print "<div dojoType=\"fox.form.DropDownButton\">".
1506
-				"<span>" . __('Select')."</span>";
1507
-		print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
1508
-		print "<div onclick=\"Tables.select('error-feeds-list', true)\"
1504
+        print "<div dojoType=\"fox.Toolbar\">";
1505
+        print "<div dojoType=\"fox.form.DropDownButton\">".
1506
+                "<span>" . __('Select')."</span>";
1507
+        print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
1508
+        print "<div onclick=\"Tables.select('error-feeds-list', true)\"
1509 1509
 			dojoType=\"dijit.MenuItem\">".__('All')."</div>";
1510
-		print "<div onclick=\"Tables.select('error-feeds-list', false)\"
1510
+        print "<div onclick=\"Tables.select('error-feeds-list', false)\"
1511 1511
 			dojoType=\"dijit.MenuItem\">".__('None')."</div>";
1512
-		print "</div></div>";
1513
-		print "</div>"; #toolbar
1512
+        print "</div></div>";
1513
+        print "</div>"; #toolbar
1514 1514
 
1515
-		print "<div class='panel panel-scrollable'>";
1516
-		print "<table width='100%' id='error-feeds-list'>";
1515
+        print "<div class='panel panel-scrollable'>";
1516
+        print "<table width='100%' id='error-feeds-list'>";
1517 1517
 
1518
-		$lnum = 1;
1518
+        $lnum = 1;
1519 1519
 
1520
-		while ($line = $sth->fetch()) {
1520
+        while ($line = $sth->fetch()) {
1521 1521
 
1522
-			$feed_id = $line["id"];
1522
+            $feed_id = $line["id"];
1523 1523
 
1524
-			print "<tr data-row-id='$feed_id'>";
1524
+            print "<tr data-row-id='$feed_id'>";
1525 1525
 
1526
-			print "<td width='5%' align='center'><input
1526
+            print "<td width='5%' align='center'><input
1527 1527
 				onclick='Tables.onRowChecked(this);' dojoType=\"dijit.form.CheckBox\"
1528 1528
 				type=\"checkbox\"></td>";
1529
-			print "<td>";
1529
+            print "<td>";
1530 1530
 
1531
-			print "<a class=\"visibleLink\" href=\"#\" ".
1532
-				"title=\"".__("Click to edit feed")."\" ".
1533
-				"onclick=\"CommonDialogs.editFeed(".$line["id"].")\">".
1534
-				htmlspecialchars($line["title"])."</a>: ";
1531
+            print "<a class=\"visibleLink\" href=\"#\" ".
1532
+                "title=\"".__("Click to edit feed")."\" ".
1533
+                "onclick=\"CommonDialogs.editFeed(".$line["id"].")\">".
1534
+                htmlspecialchars($line["title"])."</a>: ";
1535 1535
 
1536
-			print "<span class=\"text-muted\">";
1537
-			print htmlspecialchars($line["last_error"]);
1538
-			print "</span>";
1536
+            print "<span class=\"text-muted\">";
1537
+            print htmlspecialchars($line["last_error"]);
1538
+            print "</span>";
1539 1539
 
1540
-			print "</td>";
1541
-			print "</tr>";
1540
+            print "</td>";
1541
+            print "</tr>";
1542 1542
 
1543
-			++$lnum;
1544
-		}
1543
+            ++$lnum;
1544
+        }
1545 1545
 
1546
-		print "</table>";
1547
-		print "</div>";
1546
+        print "</table>";
1547
+        print "</div>";
1548 1548
 
1549
-		print "<footer>";
1550
-		print "<button style='float : left' class=\"alt-danger\" dojoType=\"dijit.form.Button\" onclick=\"dijit.byId('errorFeedsDlg').removeSelected()\">"
1551
-			.__('Unsubscribe from selected feeds')."</button> ";
1549
+        print "<footer>";
1550
+        print "<button style='float : left' class=\"alt-danger\" dojoType=\"dijit.form.Button\" onclick=\"dijit.byId('errorFeedsDlg').removeSelected()\">"
1551
+            .__('Unsubscribe from selected feeds')."</button> ";
1552 1552
 
1553
-		print "<button dojoType=\"dijit.form.Button\" onclick=\"dijit.byId('errorFeedsDlg').hide()\">".
1554
-			__('Close this window')."</button>";
1553
+        print "<button dojoType=\"dijit.form.Button\" onclick=\"dijit.byId('errorFeedsDlg').hide()\">".
1554
+            __('Close this window')."</button>";
1555 1555
 
1556
-		print "</footer>";
1557
-	}
1556
+        print "</footer>";
1557
+    }
1558 1558
 
1559
-	private function remove_feed_category($id, $owner_uid) {
1559
+    private function remove_feed_category($id, $owner_uid) {
1560 1560
 
1561
-		$sth = $this->pdo->prepare("DELETE FROM ttrss_feed_categories
1561
+        $sth = $this->pdo->prepare("DELETE FROM ttrss_feed_categories
1562 1562
 			WHERE id = ? AND owner_uid = ?");
1563
-		$sth->execute([$id, $owner_uid]);
1563
+        $sth->execute([$id, $owner_uid]);
1564 1564
 
1565
-		CCache::remove($id, $owner_uid, true);
1566
-	}
1565
+        CCache::remove($id, $owner_uid, true);
1566
+    }
1567 1567
 
1568
-	public static function remove_feed($id, $owner_uid) {
1569
-		foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_UNSUBSCRIBE_FEED) as $p) {
1570
-			if (! $p->hook_unsubscribe_feed($id, $owner_uid)) {
1568
+    public static function remove_feed($id, $owner_uid) {
1569
+        foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_UNSUBSCRIBE_FEED) as $p) {
1570
+            if (! $p->hook_unsubscribe_feed($id, $owner_uid)) {
1571 1571
                 user_error("Feed $id (owner: $owner_uid) not removed due to plugin error (HOOK_UNSUBSCRIBE_FEED).", E_USER_WARNING);
1572 1572
                 return;
1573
-			}
1574
-		}
1573
+            }
1574
+        }
1575 1575
 
1576
-		$pdo = Db::pdo();
1576
+        $pdo = Db::pdo();
1577 1577
 
1578
-		if ($id > 0) {
1579
-			$pdo->beginTransaction();
1578
+        if ($id > 0) {
1579
+            $pdo->beginTransaction();
1580 1580
 
1581
-			/* save starred articles in Archived feed */
1581
+            /* save starred articles in Archived feed */
1582 1582
 
1583
-			/* prepare feed if necessary */
1583
+            /* prepare feed if necessary */
1584 1584
 
1585
-			$sth = $pdo->prepare("SELECT feed_url FROM ttrss_feeds WHERE id = ?
1585
+            $sth = $pdo->prepare("SELECT feed_url FROM ttrss_feeds WHERE id = ?
1586 1586
 				AND owner_uid = ?");
1587
-			$sth->execute([$id, $owner_uid]);
1587
+            $sth->execute([$id, $owner_uid]);
1588 1588
 
1589
-			if ($row = $sth->fetch()) {
1590
-				$feed_url = $row["feed_url"];
1589
+            if ($row = $sth->fetch()) {
1590
+                $feed_url = $row["feed_url"];
1591 1591
 
1592
-				$sth = $pdo->prepare("SELECT id FROM ttrss_archived_feeds
1592
+                $sth = $pdo->prepare("SELECT id FROM ttrss_archived_feeds
1593 1593
 					WHERE feed_url = ? AND owner_uid = ?");
1594
-				$sth->execute([$feed_url, $owner_uid]);
1594
+                $sth->execute([$feed_url, $owner_uid]);
1595 1595
 
1596
-				if ($row = $sth->fetch()) {
1597
-					$archive_id = $row["id"];
1598
-				} else {
1599
-					$res = $pdo->query("SELECT MAX(id) AS id FROM ttrss_archived_feeds");
1600
-					$row = $res->fetch();
1596
+                if ($row = $sth->fetch()) {
1597
+                    $archive_id = $row["id"];
1598
+                } else {
1599
+                    $res = $pdo->query("SELECT MAX(id) AS id FROM ttrss_archived_feeds");
1600
+                    $row = $res->fetch();
1601 1601
 
1602
-					$new_feed_id = (int)$row['id'] + 1;
1602
+                    $new_feed_id = (int)$row['id'] + 1;
1603 1603
 
1604
-					$sth = $pdo->prepare("INSERT INTO ttrss_archived_feeds
1604
+                    $sth = $pdo->prepare("INSERT INTO ttrss_archived_feeds
1605 1605
 						(id, owner_uid, title, feed_url, site_url, created)
1606 1606
 							SELECT ?, owner_uid, title, feed_url, site_url, NOW() from ttrss_feeds
1607 1607
 							WHERE id = ?");
1608
-					$sth->execute([$new_feed_id, $id]);
1608
+                    $sth->execute([$new_feed_id, $id]);
1609 1609
 
1610
-					$archive_id = $new_feed_id;
1611
-				}
1610
+                    $archive_id = $new_feed_id;
1611
+                }
1612 1612
 
1613
-				$sth = $pdo->prepare("UPDATE ttrss_user_entries SET feed_id = NULL,
1613
+                $sth = $pdo->prepare("UPDATE ttrss_user_entries SET feed_id = NULL,
1614 1614
 					orig_feed_id = ? WHERE feed_id = ? AND
1615 1615
 						marked = true AND owner_uid = ?");
1616 1616
 
1617
-				$sth->execute([$archive_id, $id, $owner_uid]);
1617
+                $sth->execute([$archive_id, $id, $owner_uid]);
1618 1618
 
1619
-				/* Remove access key for the feed */
1619
+                /* Remove access key for the feed */
1620 1620
 
1621
-				$sth = $pdo->prepare("DELETE FROM ttrss_access_keys WHERE
1621
+                $sth = $pdo->prepare("DELETE FROM ttrss_access_keys WHERE
1622 1622
 					feed_id = ? AND owner_uid = ?");
1623
-				$sth->execute([$id, $owner_uid]);
1623
+                $sth->execute([$id, $owner_uid]);
1624 1624
 
1625
-				/* remove the feed */
1625
+                /* remove the feed */
1626 1626
 
1627
-				$sth = $pdo->prepare("DELETE FROM ttrss_feeds
1627
+                $sth = $pdo->prepare("DELETE FROM ttrss_feeds
1628 1628
 					WHERE id = ? AND owner_uid = ?");
1629
-				$sth->execute([$id, $owner_uid]);
1630
-			}
1629
+                $sth->execute([$id, $owner_uid]);
1630
+            }
1631 1631
 
1632
-			$pdo->commit();
1632
+            $pdo->commit();
1633 1633
 
1634
-			if (file_exists(ICONS_DIR . "/$id.ico")) {
1635
-				unlink(ICONS_DIR . "/$id.ico");
1636
-			}
1634
+            if (file_exists(ICONS_DIR . "/$id.ico")) {
1635
+                unlink(ICONS_DIR . "/$id.ico");
1636
+            }
1637 1637
 
1638
-			CCache::remove($id, $owner_uid);
1638
+            CCache::remove($id, $owner_uid);
1639 1639
 
1640
-		} else {
1641
-			Labels::remove(Labels::feed_to_label_id($id), $owner_uid);
1642
-			//CCache::remove($id, $owner_uid); don't think labels are cached
1643
-		}
1644
-	}
1640
+        } else {
1641
+            Labels::remove(Labels::feed_to_label_id($id), $owner_uid);
1642
+            //CCache::remove($id, $owner_uid); don't think labels are cached
1643
+        }
1644
+    }
1645 1645
 
1646
-	public function batchSubscribe() {
1647
-		print_hidden("op", "pref-feeds");
1648
-		print_hidden("method", "batchaddfeeds");
1646
+    public function batchSubscribe() {
1647
+        print_hidden("op", "pref-feeds");
1648
+        print_hidden("method", "batchaddfeeds");
1649 1649
 
1650
-		print "<header class='horizontal'>".__("One valid feed per line (no detection is done)")."</header>";
1651
-		print "<section>";
1650
+        print "<header class='horizontal'>".__("One valid feed per line (no detection is done)")."</header>";
1651
+        print "<section>";
1652 1652
 
1653
-		print "<textarea
1653
+        print "<textarea
1654 1654
 			style='font-size : 12px; width : 98%; height: 200px;'
1655 1655
 			dojoType='dijit.form.SimpleTextarea' name='feeds'></textarea>";
1656 1656
 
1657
-		if (get_pref('ENABLE_FEED_CATS')) {
1658
-			print "<fieldset>";
1659
-			print "<label>" . __('Place in category:') . "</label> ";
1660
-			print_feed_cat_select("cat", false, 'dojoType="fox.form.Select"');
1661
-			print "</fieldset>";
1662
-		}
1657
+        if (get_pref('ENABLE_FEED_CATS')) {
1658
+            print "<fieldset>";
1659
+            print "<label>" . __('Place in category:') . "</label> ";
1660
+            print_feed_cat_select("cat", false, 'dojoType="fox.form.Select"');
1661
+            print "</fieldset>";
1662
+        }
1663 1663
 
1664
-		print "</section>";
1664
+        print "</section>";
1665 1665
 
1666
-		print "<div id='feedDlg_loginContainer' style='display : none'>";
1666
+        print "<div id='feedDlg_loginContainer' style='display : none'>";
1667 1667
 
1668
-		print "<header>" . __("Authentication") . "</header>";
1669
-		print "<section>";
1668
+        print "<header>" . __("Authentication") . "</header>";
1669
+        print "<section>";
1670 1670
 
1671
-		print "<input dojoType='dijit.form.TextBox' name='login' placeHolder=\"".__("Login")."\">
1671
+        print "<input dojoType='dijit.form.TextBox' name='login' placeHolder=\"".__("Login")."\">
1672 1672
 			<input placeHolder=\"".__("Password")."\" dojoType=\"dijit.form.TextBox\" type='password'
1673 1673
 				autocomplete='new-password' name='pass''></div>";
1674 1674
 
1675
-		print "</section>";
1676
-		print "</div>";
1675
+        print "</section>";
1676
+        print "</div>";
1677 1677
 
1678
-		print "<fieldset class='narrow'>
1678
+        print "<fieldset class='narrow'>
1679 1679
 			<label class='checkbox'><input type='checkbox' name='need_auth' dojoType='dijit.form.CheckBox'
1680 1680
 					onclick='displayIfChecked(this, \"feedDlg_loginContainer\")'> ".
1681
-				__('Feeds require authentication.')."</label></div>";
1682
-		print "</fieldset>";
1681
+                __('Feeds require authentication.')."</label></div>";
1682
+        print "</fieldset>";
1683 1683
 
1684
-		print "<footer>
1684
+        print "<footer>
1685 1685
 			<button dojoType='dijit.form.Button' type='submit' class='alt-primary'>".__('Subscribe')."</button>
1686 1686
 			<button dojoType='dijit.form.Button' onclick=\"return dijit.byId('batchSubDlg').hide()\">".__('Cancel')."</button>
1687 1687
 			</footer>";
1688
-	}
1688
+    }
1689 1689
 
1690
-	public function batchAddFeeds() {
1691
-		$cat_id = clean($_REQUEST['cat']);
1692
-		$feeds = explode("\n", clean($_REQUEST['feeds']));
1693
-		$login = clean($_REQUEST['login']);
1694
-		$pass = trim(clean($_REQUEST['pass']));
1690
+    public function batchAddFeeds() {
1691
+        $cat_id = clean($_REQUEST['cat']);
1692
+        $feeds = explode("\n", clean($_REQUEST['feeds']));
1693
+        $login = clean($_REQUEST['login']);
1694
+        $pass = trim(clean($_REQUEST['pass']));
1695 1695
 
1696
-		$csth = $this->pdo->prepare("SELECT id FROM ttrss_feeds
1696
+        $csth = $this->pdo->prepare("SELECT id FROM ttrss_feeds
1697 1697
 						WHERE feed_url = ? AND owner_uid = ?");
1698 1698
 
1699
-		$isth = $this->pdo->prepare("INSERT INTO ttrss_feeds
1699
+        $isth = $this->pdo->prepare("INSERT INTO ttrss_feeds
1700 1700
 							(owner_uid,feed_url,title,cat_id,auth_login,auth_pass,update_method,auth_pass_encrypted)
1701 1701
 						VALUES (?, ?, '[Unknown]', ?, ?, ?, 0, false)");
1702 1702
 
1703
-		foreach ($feeds as $feed) {
1704
-			$feed = trim($feed);
1703
+        foreach ($feeds as $feed) {
1704
+            $feed = trim($feed);
1705 1705
 
1706
-			if (Feeds::validate_feed_url($feed)) {
1706
+            if (Feeds::validate_feed_url($feed)) {
1707 1707
 
1708
-				$this->pdo->beginTransaction();
1708
+                $this->pdo->beginTransaction();
1709 1709
 
1710
-				$csth->execute([$feed, $_SESSION['uid']]);
1710
+                $csth->execute([$feed, $_SESSION['uid']]);
1711 1711
 
1712
-				if (!$csth->fetch()) {
1713
-					$isth->execute([$_SESSION['uid'], $feed, $cat_id ? $cat_id : null, $login, $pass]);
1714
-				}
1712
+                if (!$csth->fetch()) {
1713
+                    $isth->execute([$_SESSION['uid'], $feed, $cat_id ? $cat_id : null, $login, $pass]);
1714
+                }
1715 1715
 
1716
-				$this->pdo->commit();
1717
-			}
1718
-		}
1719
-	}
1716
+                $this->pdo->commit();
1717
+            }
1718
+        }
1719
+    }
1720 1720
 
1721
-	public function regenOPMLKey() {
1722
-		$this->update_feed_access_key('OPML:Publish',
1723
-		false, $_SESSION["uid"]);
1721
+    public function regenOPMLKey() {
1722
+        $this->update_feed_access_key('OPML:Publish',
1723
+        false, $_SESSION["uid"]);
1724 1724
 
1725
-		$new_link = Opml::opml_publish_url();
1725
+        $new_link = Opml::opml_publish_url();
1726 1726
 
1727
-		print json_encode(array("link" => $new_link));
1728
-	}
1727
+        print json_encode(array("link" => $new_link));
1728
+    }
1729 1729
 
1730
-	public function regenFeedKey() {
1731
-		$feed_id = clean($_REQUEST['id']);
1732
-		$is_cat = clean($_REQUEST['is_cat']);
1730
+    public function regenFeedKey() {
1731
+        $feed_id = clean($_REQUEST['id']);
1732
+        $is_cat = clean($_REQUEST['is_cat']);
1733 1733
 
1734
-		$new_key = $this->update_feed_access_key($feed_id, $is_cat);
1734
+        $new_key = $this->update_feed_access_key($feed_id, $is_cat);
1735 1735
 
1736
-		print json_encode(["link" => $new_key]);
1737
-	}
1736
+        print json_encode(["link" => $new_key]);
1737
+    }
1738 1738
 
1739 1739
 
1740
-	private function update_feed_access_key($feed_id, $is_cat, $owner_uid = false) {
1741
-		if (!$owner_uid) $owner_uid = $_SESSION["uid"];
1740
+    private function update_feed_access_key($feed_id, $is_cat, $owner_uid = false) {
1741
+        if (!$owner_uid) $owner_uid = $_SESSION["uid"];
1742 1742
 
1743
-		// clear old value and generate new one
1744
-		$sth = $this->pdo->prepare("DELETE FROM ttrss_access_keys
1743
+        // clear old value and generate new one
1744
+        $sth = $this->pdo->prepare("DELETE FROM ttrss_access_keys
1745 1745
 			WHERE feed_id = ? AND is_cat = ? AND owner_uid = ?");
1746
-		$sth->execute([$feed_id, bool_to_sql_bool($is_cat), $owner_uid]);
1746
+        $sth->execute([$feed_id, bool_to_sql_bool($is_cat), $owner_uid]);
1747 1747
 
1748
-		return Feeds::get_feed_access_key($feed_id, $is_cat, $owner_uid);
1749
-	}
1748
+        return Feeds::get_feed_access_key($feed_id, $is_cat, $owner_uid);
1749
+    }
1750 1750
 
1751
-	// Silent
1752
-	public function clearKeys() {
1753
-		$sth = $this->pdo->prepare("DELETE FROM ttrss_access_keys WHERE
1751
+    // Silent
1752
+    public function clearKeys() {
1753
+        $sth = $this->pdo->prepare("DELETE FROM ttrss_access_keys WHERE
1754 1754
 			owner_uid = ?");
1755
-		$sth->execute([$_SESSION['uid']]);
1756
-	}
1757
-
1758
-	private function calculate_children_count($cat) {
1759
-		$c = 0;
1760
-
1761
-		foreach ($cat['items'] as $child) {
1762
-			if ($child['type'] == 'category') {
1763
-				$c += $this->calculate_children_count($child);
1764
-			} else {
1765
-				$c += 1;
1766
-			}
1767
-		}
1768
-
1769
-		return $c;
1770
-	}
1771
-
1772
-	public function getinactivefeeds() {
1773
-		if (DB_TYPE == "pgsql") {
1774
-			$interval_qpart = "NOW() - INTERVAL '3 months'";
1775
-		} else {
1776
-			$interval_qpart = "DATE_SUB(NOW(), INTERVAL 3 MONTH)";
1777
-		}
1778
-
1779
-		$sth = $this->pdo->prepare("SELECT COUNT(id) AS num_inactive FROM ttrss_feeds WHERE
1755
+        $sth->execute([$_SESSION['uid']]);
1756
+    }
1757
+
1758
+    private function calculate_children_count($cat) {
1759
+        $c = 0;
1760
+
1761
+        foreach ($cat['items'] as $child) {
1762
+            if ($child['type'] == 'category') {
1763
+                $c += $this->calculate_children_count($child);
1764
+            } else {
1765
+                $c += 1;
1766
+            }
1767
+        }
1768
+
1769
+        return $c;
1770
+    }
1771
+
1772
+    public function getinactivefeeds() {
1773
+        if (DB_TYPE == "pgsql") {
1774
+            $interval_qpart = "NOW() - INTERVAL '3 months'";
1775
+        } else {
1776
+            $interval_qpart = "DATE_SUB(NOW(), INTERVAL 3 MONTH)";
1777
+        }
1778
+
1779
+        $sth = $this->pdo->prepare("SELECT COUNT(id) AS num_inactive FROM ttrss_feeds WHERE
1780 1780
 				(SELECT MAX(updated) FROM ttrss_entries, ttrss_user_entries WHERE
1781 1781
 					ttrss_entries.id = ref_id AND
1782 1782
 						ttrss_user_entries.feed_id = ttrss_feeds.id) < $interval_qpart AND
1783 1783
 			  ttrss_feeds.owner_uid = ?");
1784
-		$sth->execute([$_SESSION['uid']]);
1785
-
1786
-		if ($row = $sth->fetch()) {
1787
-			print (int)$row["num_inactive"];
1788
-		}
1789
-	}
1790
-
1791
-	public static function subscribe_to_feed_url() {
1792
-		$url_path = get_self_url_prefix() .
1793
-			"/public.php?op=subscribe&feed_url=%s";
1794
-		return $url_path;
1795
-	}
1784
+        $sth->execute([$_SESSION['uid']]);
1785
+
1786
+        if ($row = $sth->fetch()) {
1787
+            print (int)$row["num_inactive"];
1788
+        }
1789
+    }
1790
+
1791
+    public static function subscribe_to_feed_url() {
1792
+        $url_path = get_self_url_prefix() .
1793
+            "/public.php?op=subscribe&feed_url=%s";
1794
+        return $url_path;
1795
+    }
1796 1796
 
1797 1797
 }
Please login to merge, or discard this patch.
classes/pref/prefs.php 1 patch
Indentation   +839 added lines, -839 removed lines patch added patch discarded remove patch
@@ -2,278 +2,278 @@  discard block
 block discarded – undo
2 2
 
3 3
 class Pref_Prefs extends Handler_Protected {
4 4
 
5
-	private $pref_help = [];
6
-	private $pref_item_map = [];
7
-	private $pref_blacklist = [];
8
-	private $profile_blacklist = [];
9
-
10
-	public function csrf_ignore($method) {
11
-		$csrf_ignored = array("index", "updateself", "customizecss", "editprefprofiles");
12
-
13
-		return array_search($method, $csrf_ignored) !== false;
14
-	}
15
-
16
-	public function __construct($args) {
17
-		parent::__construct($args);
18
-
19
-		$this->pref_item_map = [
20
-			__('General') => [
21
-				'USER_LANGUAGE',
22
-				'USER_TIMEZONE',
23
-				'BLOCK_SEPARATOR',
24
-				'USER_CSS_THEME',
25
-				'BLOCK_SEPARATOR',
26
-				'ENABLE_API_ACCESS',
27
-			],
28
-			__('Feeds') => [
29
-				'DEFAULT_UPDATE_INTERVAL',
30
-				'FRESH_ARTICLE_MAX_AGE',
31
-				'DEFAULT_SEARCH_LANGUAGE',
32
-				'BLOCK_SEPARATOR',
33
-				'ENABLE_FEED_CATS',
34
-				'BLOCK_SEPARATOR',
35
-				'CONFIRM_FEED_CATCHUP',
36
-				'ON_CATCHUP_SHOW_NEXT_FEED',
37
-				'BLOCK_SEPARATOR',
38
-				'HIDE_READ_FEEDS',
39
-				'HIDE_READ_SHOWS_SPECIAL',
40
-			],
41
-			__('Articles') => [
42
-				'PURGE_OLD_DAYS',
43
-				'PURGE_UNREAD_ARTICLES',
44
-				'BLOCK_SEPARATOR',
45
-				'COMBINED_DISPLAY_MODE',
46
-				'CDM_EXPANDED',
47
-				'BLOCK_SEPARATOR',
48
-				'CDM_AUTO_CATCHUP',
49
-				'VFEED_GROUP_BY_FEED',
50
-				'BLOCK_SEPARATOR',
51
-				'SHOW_CONTENT_PREVIEW',
52
-				'STRIP_IMAGES',
53
-			],
54
-			__('Digest') => [
55
-				'DIGEST_ENABLE',
56
-				'DIGEST_CATCHUP',
57
-				'DIGEST_PREFERRED_TIME',
58
-			],
59
-			__('Advanced') => [
60
-				'BLACKLISTED_TAGS',
61
-				'BLOCK_SEPARATOR',
62
-				'LONG_DATE_FORMAT',
63
-				'SHORT_DATE_FORMAT',
64
-				'BLOCK_SEPARATOR',
65
-				'SSL_CERT_SERIAL',
66
-			]
67
-		];
68
-
69
-		$this->pref_help = [
70
-			"ALLOW_DUPLICATE_POSTS" => array(__("Allow duplicate articles"), ""),
71
-			"BLACKLISTED_TAGS" => array(__("Blacklisted tags"), __("Never apply these tags automatically (comma-separated list).")),
72
-			"DEFAULT_SEARCH_LANGUAGE" => array(__("Default language"), __("Used for full-text search")),
73
-			"CDM_AUTO_CATCHUP" => array(__("Mark read on scroll"), __("Mark articles as read as you scroll past them")),
74
-			"CDM_EXPANDED" => array(__("Always expand articles")),
75
-			"COMBINED_DISPLAY_MODE" => array(__("Combined mode"), __("Show flat list of articles instead of separate panels")),
76
-			"CONFIRM_FEED_CATCHUP" => array(__("Confirm marking feeds as read")),
77
-			"DEFAULT_ARTICLE_LIMIT" => array(__("Amount of articles to display at once")),
78
-			"DEFAULT_UPDATE_INTERVAL" => array(__("Default update interval")),
79
-			"DIGEST_CATCHUP" => array(__("Mark sent articles as read")),
80
-			"DIGEST_ENABLE" => array(__("Enable digest"), __("Send daily digest of new (and unread) headlines to your e-mail address")),
81
-			"DIGEST_PREFERRED_TIME" => array(__("Try to send around this time"), __("Time in UTC")),
82
-			"ENABLE_API_ACCESS" => array(__("Enable API"), __("Allows accessing this account through the API")),
83
-			"ENABLE_FEED_CATS" => array(__("Enable categories")),
84
-			"FEEDS_SORT_BY_UNREAD" => array(__("Sort feeds by unread articles count"), ""),
85
-			"FRESH_ARTICLE_MAX_AGE" => array(__("Maximum age of fresh articles"), "<strong>" . __("hours") . "</strong>"),
86
-			"HIDE_READ_FEEDS" => array(__("Hide read feeds")),
87
-			"HIDE_READ_SHOWS_SPECIAL" => array(__("Always show special feeds"), __("While hiding read feeds")),
88
-			"LONG_DATE_FORMAT" => array(__("Long date format"), __("Syntax is identical to PHP <a href='http://php.net/manual/function.date.php'>date()</a> function.")),
89
-			"ON_CATCHUP_SHOW_NEXT_FEED" => array(__("Automatically show next feed"), __("After marking one as read")),
90
-			"PURGE_OLD_DAYS" => array(__("Purge articles older than"), __("<strong>days</strong> (0 disables)")),
91
-			"PURGE_UNREAD_ARTICLES" => array(__("Purge unread articles")),
92
-			"REVERSE_HEADLINES" => array(__("Reverse headline order (oldest first)")),
93
-			"SHORT_DATE_FORMAT" => array(__("Short date format")),
94
-			"SHOW_CONTENT_PREVIEW" => array(__("Show content preview in headlines")),
95
-			"SORT_HEADLINES_BY_FEED_DATE" => array(__("Sort headlines by feed date"), __("Use feed-specified date to sort headlines instead of local import date.")),
96
-			"SSL_CERT_SERIAL" => array(__("SSL client certificate")),
97
-			"STRIP_IMAGES" => array(__("Do not embed media")),
98
-			"STRIP_UNSAFE_TAGS" => array(__("Strip unsafe tags from articles"), __("Strip all but most common HTML tags when reading articles.")),
99
-			"USER_STYLESHEET" => array(__("Customize stylesheet")),
100
-			"USER_TIMEZONE" => array(__("Time zone")),
101
-			"VFEED_GROUP_BY_FEED" => array(__("Group by feed"), __("Group multiple-feed output by originating feed")),
102
-			"USER_LANGUAGE" => array(__("Language")),
103
-			"USER_CSS_THEME" => array(__("Theme"))
104
-		];
105
-
106
-		$this->pref_blacklist = ["ALLOW_DUPLICATE_POSTS", "STRIP_UNSAFE_TAGS", "REVERSE_HEADLINES",
107
-			"SORT_HEADLINES_BY_FEED_DATE", "DEFAULT_ARTICLE_LIMIT",
108
-			"FEEDS_SORT_BY_UNREAD", "USER_STYLESHEET"];
109
-
110
-		/* "FEEDS_SORT_BY_UNREAD", "HIDE_READ_FEEDS", "REVERSE_HEADLINES" */
111
-
112
-		$this->profile_blacklist = ["ALLOW_DUPLICATE_POSTS", "PURGE_OLD_DAYS",
113
-			"PURGE_UNREAD_ARTICLES", "DIGEST_ENABLE", "DIGEST_CATCHUP",
114
-			"BLACKLISTED_TAGS", "ENABLE_API_ACCESS", "UPDATE_POST_ON_CHECKSUM_CHANGE",
115
-			"DEFAULT_UPDATE_INTERVAL", "USER_TIMEZONE", "SORT_HEADLINES_BY_FEED_DATE",
116
-			"SSL_CERT_SERIAL", "DIGEST_PREFERRED_TIME"];
117
-	}
118
-
119
-	public function changepassword() {
120
-
121
-		if (defined('_TTRSS_DEMO_INSTANCE')) {
122
-			print "ERROR: ".format_error("Disabled in demo version.");
123
-			return;
124
-		}
125
-
126
-		$old_pw = clean($_POST["old_password"]);
127
-		$new_pw = clean($_POST["new_password"]);
128
-		$con_pw = clean($_POST["confirm_password"]);
129
-
130
-		if ($old_pw == $new_pw) {
131
-			print "ERROR: ".format_error("New password must be different from the old one.");
132
-			return;
133
-		}
134
-
135
-		if ($old_pw == "") {
136
-			print "ERROR: ".format_error("Old password cannot be blank.");
137
-			return;
138
-		}
139
-
140
-		if ($new_pw == "") {
141
-			print "ERROR: ".format_error("New password cannot be blank.");
142
-			return;
143
-		}
144
-
145
-		if ($new_pw != $con_pw) {
146
-			print "ERROR: ".format_error("Entered passwords do not match.");
147
-			return;
148
-		}
149
-
150
-		$authenticator = PluginHost::getInstance()->get_plugin($_SESSION["auth_module"]);
151
-
152
-		if (method_exists($authenticator, "change_password")) {
153
-			print format_notice($authenticator->change_password($_SESSION["uid"], $old_pw, $new_pw));
154
-		} else {
155
-			print "ERROR: ".format_error("Function not supported by authentication module.");
156
-		}
157
-	}
158
-
159
-	public function saveconfig() {
160
-		$boolean_prefs = explode(",", clean($_POST["boolean_prefs"]));
161
-
162
-		foreach ($boolean_prefs as $pref) {
163
-			if (!isset($_POST[$pref])) $_POST[$pref] = 'false';
164
-		}
165
-
166
-		$need_reload = false;
167
-
168
-		foreach (array_keys($_POST) as $pref_name) {
169
-
170
-			$value = $_POST[$pref_name];
171
-
172
-			switch ($pref_name) {
173
-				case 'DIGEST_PREFERRED_TIME':
174
-					if (get_pref('DIGEST_PREFERRED_TIME') != $value) {
175
-
176
-						$sth = $this->pdo->prepare("UPDATE ttrss_users SET
5
+    private $pref_help = [];
6
+    private $pref_item_map = [];
7
+    private $pref_blacklist = [];
8
+    private $profile_blacklist = [];
9
+
10
+    public function csrf_ignore($method) {
11
+        $csrf_ignored = array("index", "updateself", "customizecss", "editprefprofiles");
12
+
13
+        return array_search($method, $csrf_ignored) !== false;
14
+    }
15
+
16
+    public function __construct($args) {
17
+        parent::__construct($args);
18
+
19
+        $this->pref_item_map = [
20
+            __('General') => [
21
+                'USER_LANGUAGE',
22
+                'USER_TIMEZONE',
23
+                'BLOCK_SEPARATOR',
24
+                'USER_CSS_THEME',
25
+                'BLOCK_SEPARATOR',
26
+                'ENABLE_API_ACCESS',
27
+            ],
28
+            __('Feeds') => [
29
+                'DEFAULT_UPDATE_INTERVAL',
30
+                'FRESH_ARTICLE_MAX_AGE',
31
+                'DEFAULT_SEARCH_LANGUAGE',
32
+                'BLOCK_SEPARATOR',
33
+                'ENABLE_FEED_CATS',
34
+                'BLOCK_SEPARATOR',
35
+                'CONFIRM_FEED_CATCHUP',
36
+                'ON_CATCHUP_SHOW_NEXT_FEED',
37
+                'BLOCK_SEPARATOR',
38
+                'HIDE_READ_FEEDS',
39
+                'HIDE_READ_SHOWS_SPECIAL',
40
+            ],
41
+            __('Articles') => [
42
+                'PURGE_OLD_DAYS',
43
+                'PURGE_UNREAD_ARTICLES',
44
+                'BLOCK_SEPARATOR',
45
+                'COMBINED_DISPLAY_MODE',
46
+                'CDM_EXPANDED',
47
+                'BLOCK_SEPARATOR',
48
+                'CDM_AUTO_CATCHUP',
49
+                'VFEED_GROUP_BY_FEED',
50
+                'BLOCK_SEPARATOR',
51
+                'SHOW_CONTENT_PREVIEW',
52
+                'STRIP_IMAGES',
53
+            ],
54
+            __('Digest') => [
55
+                'DIGEST_ENABLE',
56
+                'DIGEST_CATCHUP',
57
+                'DIGEST_PREFERRED_TIME',
58
+            ],
59
+            __('Advanced') => [
60
+                'BLACKLISTED_TAGS',
61
+                'BLOCK_SEPARATOR',
62
+                'LONG_DATE_FORMAT',
63
+                'SHORT_DATE_FORMAT',
64
+                'BLOCK_SEPARATOR',
65
+                'SSL_CERT_SERIAL',
66
+            ]
67
+        ];
68
+
69
+        $this->pref_help = [
70
+            "ALLOW_DUPLICATE_POSTS" => array(__("Allow duplicate articles"), ""),
71
+            "BLACKLISTED_TAGS" => array(__("Blacklisted tags"), __("Never apply these tags automatically (comma-separated list).")),
72
+            "DEFAULT_SEARCH_LANGUAGE" => array(__("Default language"), __("Used for full-text search")),
73
+            "CDM_AUTO_CATCHUP" => array(__("Mark read on scroll"), __("Mark articles as read as you scroll past them")),
74
+            "CDM_EXPANDED" => array(__("Always expand articles")),
75
+            "COMBINED_DISPLAY_MODE" => array(__("Combined mode"), __("Show flat list of articles instead of separate panels")),
76
+            "CONFIRM_FEED_CATCHUP" => array(__("Confirm marking feeds as read")),
77
+            "DEFAULT_ARTICLE_LIMIT" => array(__("Amount of articles to display at once")),
78
+            "DEFAULT_UPDATE_INTERVAL" => array(__("Default update interval")),
79
+            "DIGEST_CATCHUP" => array(__("Mark sent articles as read")),
80
+            "DIGEST_ENABLE" => array(__("Enable digest"), __("Send daily digest of new (and unread) headlines to your e-mail address")),
81
+            "DIGEST_PREFERRED_TIME" => array(__("Try to send around this time"), __("Time in UTC")),
82
+            "ENABLE_API_ACCESS" => array(__("Enable API"), __("Allows accessing this account through the API")),
83
+            "ENABLE_FEED_CATS" => array(__("Enable categories")),
84
+            "FEEDS_SORT_BY_UNREAD" => array(__("Sort feeds by unread articles count"), ""),
85
+            "FRESH_ARTICLE_MAX_AGE" => array(__("Maximum age of fresh articles"), "<strong>" . __("hours") . "</strong>"),
86
+            "HIDE_READ_FEEDS" => array(__("Hide read feeds")),
87
+            "HIDE_READ_SHOWS_SPECIAL" => array(__("Always show special feeds"), __("While hiding read feeds")),
88
+            "LONG_DATE_FORMAT" => array(__("Long date format"), __("Syntax is identical to PHP <a href='http://php.net/manual/function.date.php'>date()</a> function.")),
89
+            "ON_CATCHUP_SHOW_NEXT_FEED" => array(__("Automatically show next feed"), __("After marking one as read")),
90
+            "PURGE_OLD_DAYS" => array(__("Purge articles older than"), __("<strong>days</strong> (0 disables)")),
91
+            "PURGE_UNREAD_ARTICLES" => array(__("Purge unread articles")),
92
+            "REVERSE_HEADLINES" => array(__("Reverse headline order (oldest first)")),
93
+            "SHORT_DATE_FORMAT" => array(__("Short date format")),
94
+            "SHOW_CONTENT_PREVIEW" => array(__("Show content preview in headlines")),
95
+            "SORT_HEADLINES_BY_FEED_DATE" => array(__("Sort headlines by feed date"), __("Use feed-specified date to sort headlines instead of local import date.")),
96
+            "SSL_CERT_SERIAL" => array(__("SSL client certificate")),
97
+            "STRIP_IMAGES" => array(__("Do not embed media")),
98
+            "STRIP_UNSAFE_TAGS" => array(__("Strip unsafe tags from articles"), __("Strip all but most common HTML tags when reading articles.")),
99
+            "USER_STYLESHEET" => array(__("Customize stylesheet")),
100
+            "USER_TIMEZONE" => array(__("Time zone")),
101
+            "VFEED_GROUP_BY_FEED" => array(__("Group by feed"), __("Group multiple-feed output by originating feed")),
102
+            "USER_LANGUAGE" => array(__("Language")),
103
+            "USER_CSS_THEME" => array(__("Theme"))
104
+        ];
105
+
106
+        $this->pref_blacklist = ["ALLOW_DUPLICATE_POSTS", "STRIP_UNSAFE_TAGS", "REVERSE_HEADLINES",
107
+            "SORT_HEADLINES_BY_FEED_DATE", "DEFAULT_ARTICLE_LIMIT",
108
+            "FEEDS_SORT_BY_UNREAD", "USER_STYLESHEET"];
109
+
110
+        /* "FEEDS_SORT_BY_UNREAD", "HIDE_READ_FEEDS", "REVERSE_HEADLINES" */
111
+
112
+        $this->profile_blacklist = ["ALLOW_DUPLICATE_POSTS", "PURGE_OLD_DAYS",
113
+            "PURGE_UNREAD_ARTICLES", "DIGEST_ENABLE", "DIGEST_CATCHUP",
114
+            "BLACKLISTED_TAGS", "ENABLE_API_ACCESS", "UPDATE_POST_ON_CHECKSUM_CHANGE",
115
+            "DEFAULT_UPDATE_INTERVAL", "USER_TIMEZONE", "SORT_HEADLINES_BY_FEED_DATE",
116
+            "SSL_CERT_SERIAL", "DIGEST_PREFERRED_TIME"];
117
+    }
118
+
119
+    public function changepassword() {
120
+
121
+        if (defined('_TTRSS_DEMO_INSTANCE')) {
122
+            print "ERROR: ".format_error("Disabled in demo version.");
123
+            return;
124
+        }
125
+
126
+        $old_pw = clean($_POST["old_password"]);
127
+        $new_pw = clean($_POST["new_password"]);
128
+        $con_pw = clean($_POST["confirm_password"]);
129
+
130
+        if ($old_pw == $new_pw) {
131
+            print "ERROR: ".format_error("New password must be different from the old one.");
132
+            return;
133
+        }
134
+
135
+        if ($old_pw == "") {
136
+            print "ERROR: ".format_error("Old password cannot be blank.");
137
+            return;
138
+        }
139
+
140
+        if ($new_pw == "") {
141
+            print "ERROR: ".format_error("New password cannot be blank.");
142
+            return;
143
+        }
144
+
145
+        if ($new_pw != $con_pw) {
146
+            print "ERROR: ".format_error("Entered passwords do not match.");
147
+            return;
148
+        }
149
+
150
+        $authenticator = PluginHost::getInstance()->get_plugin($_SESSION["auth_module"]);
151
+
152
+        if (method_exists($authenticator, "change_password")) {
153
+            print format_notice($authenticator->change_password($_SESSION["uid"], $old_pw, $new_pw));
154
+        } else {
155
+            print "ERROR: ".format_error("Function not supported by authentication module.");
156
+        }
157
+    }
158
+
159
+    public function saveconfig() {
160
+        $boolean_prefs = explode(",", clean($_POST["boolean_prefs"]));
161
+
162
+        foreach ($boolean_prefs as $pref) {
163
+            if (!isset($_POST[$pref])) $_POST[$pref] = 'false';
164
+        }
165
+
166
+        $need_reload = false;
167
+
168
+        foreach (array_keys($_POST) as $pref_name) {
169
+
170
+            $value = $_POST[$pref_name];
171
+
172
+            switch ($pref_name) {
173
+                case 'DIGEST_PREFERRED_TIME':
174
+                    if (get_pref('DIGEST_PREFERRED_TIME') != $value) {
175
+
176
+                        $sth = $this->pdo->prepare("UPDATE ttrss_users SET
177 177
 						last_digest_sent = NULL WHERE id = ?");
178
-						$sth->execute([$_SESSION['uid']]);
178
+                        $sth->execute([$_SESSION['uid']]);
179 179
 
180
-					}
181
-					break;
182
-				case 'USER_LANGUAGE':
183
-					if (!$need_reload) $need_reload = $_SESSION["language"] != $value;
184
-					break;
185
-
186
-				case 'USER_CSS_THEME':
187
-					if (!$need_reload) $need_reload = get_pref($pref_name) != $value;
188
-					break;
189
-			}
180
+                    }
181
+                    break;
182
+                case 'USER_LANGUAGE':
183
+                    if (!$need_reload) $need_reload = $_SESSION["language"] != $value;
184
+                    break;
190 185
 
191
-			set_pref($pref_name, $value);
192
-		}
186
+                case 'USER_CSS_THEME':
187
+                    if (!$need_reload) $need_reload = get_pref($pref_name) != $value;
188
+                    break;
189
+            }
193 190
 
194
-		if ($need_reload) {
195
-			print "PREFS_NEED_RELOAD";
196
-		} else {
197
-			print __("The configuration was saved.");
198
-		}
199
-	}
191
+            set_pref($pref_name, $value);
192
+        }
200 193
 
201
-	public function changeemail() {
194
+        if ($need_reload) {
195
+            print "PREFS_NEED_RELOAD";
196
+        } else {
197
+            print __("The configuration was saved.");
198
+        }
199
+    }
202 200
 
203
-		$email = clean($_POST["email"]);
204
-		$full_name = clean($_POST["full_name"]);
205
-		$active_uid = $_SESSION["uid"];
201
+    public function changeemail() {
206 202
 
207
-		$sth = $this->pdo->prepare("SELECT email, login, full_name FROM ttrss_users WHERE id = ?");
208
-		$sth->execute([$active_uid]);
203
+        $email = clean($_POST["email"]);
204
+        $full_name = clean($_POST["full_name"]);
205
+        $active_uid = $_SESSION["uid"];
209 206
 
210
-		if ($row = $sth->fetch()) {
211
-			$old_email = $row["email"];
207
+        $sth = $this->pdo->prepare("SELECT email, login, full_name FROM ttrss_users WHERE id = ?");
208
+        $sth->execute([$active_uid]);
212 209
 
213
-			if ($old_email != $email) {
214
-				$mailer = new Mailer();
210
+        if ($row = $sth->fetch()) {
211
+            $old_email = $row["email"];
215 212
 
216
-				require_once "lib/MiniTemplator.class.php";
213
+            if ($old_email != $email) {
214
+                $mailer = new Mailer();
217 215
 
218
-				$tpl = new MiniTemplator;
216
+                require_once "lib/MiniTemplator.class.php";
219 217
 
220
-				$tpl->readTemplateFromFile("templates/mail_change_template.txt");
218
+                $tpl = new MiniTemplator;
221 219
 
222
-				$tpl->setVariable('LOGIN', $row["login"]);
223
-				$tpl->setVariable('NEWMAIL', $email);
224
-				$tpl->setVariable('TTRSS_HOST', SELF_URL_PATH);
220
+                $tpl->readTemplateFromFile("templates/mail_change_template.txt");
225 221
 
226
-				$tpl->addBlock('message');
222
+                $tpl->setVariable('LOGIN', $row["login"]);
223
+                $tpl->setVariable('NEWMAIL', $email);
224
+                $tpl->setVariable('TTRSS_HOST', SELF_URL_PATH);
227 225
 
228
-				$tpl->generateOutputToString($message);
226
+                $tpl->addBlock('message');
229 227
 
230
-				$mailer->mail(["to_name" => $row["login"],
231
-					"to_address" => $row["email"],
232
-					"subject" => "[tt-rss] Mail address change notification",
233
-					"message" => $message]);
228
+                $tpl->generateOutputToString($message);
234 229
 
235
-			}
236
-		}
230
+                $mailer->mail(["to_name" => $row["login"],
231
+                    "to_address" => $row["email"],
232
+                    "subject" => "[tt-rss] Mail address change notification",
233
+                    "message" => $message]);
234
+
235
+            }
236
+        }
237 237
 
238
-		$sth = $this->pdo->prepare("UPDATE ttrss_users SET email = ?,
238
+        $sth = $this->pdo->prepare("UPDATE ttrss_users SET email = ?,
239 239
 			full_name = ? WHERE id = ?");
240
-		$sth->execute([$email, $full_name, $active_uid]);
240
+        $sth->execute([$email, $full_name, $active_uid]);
241 241
 
242
-		print __("Your personal data has been saved.");
242
+        print __("Your personal data has been saved.");
243 243
 
244
-		return;
245
-	}
244
+        return;
245
+    }
246 246
 
247
-	public function resetconfig() {
247
+    public function resetconfig() {
248 248
 
249
-		$_SESSION["prefs_op_result"] = "reset-to-defaults";
249
+        $_SESSION["prefs_op_result"] = "reset-to-defaults";
250 250
 
251
-		$sth = $this->pdo->prepare("DELETE FROM ttrss_user_prefs
251
+        $sth = $this->pdo->prepare("DELETE FROM ttrss_user_prefs
252 252
 			WHERE (profile = :profile OR (:profile IS NULL AND profile IS NULL))
253 253
 				AND owner_uid = :uid");
254
-		$sth->execute([":profile" => $_SESSION['profile'], ":uid" => $_SESSION['uid']]);
254
+        $sth->execute([":profile" => $_SESSION['profile'], ":uid" => $_SESSION['uid']]);
255 255
 
256
-		initialize_user_prefs($_SESSION["uid"], $_SESSION["profile"]);
256
+        initialize_user_prefs($_SESSION["uid"], $_SESSION["profile"]);
257 257
 
258
-		echo __("Your preferences are now set to default values.");
259
-	}
258
+        echo __("Your preferences are now set to default values.");
259
+    }
260 260
 
261
-	public function index() {
261
+    public function index() {
262 262
 
263
-		global $access_level_names;
263
+        global $access_level_names;
264 264
 
265
-		$_SESSION["prefs_op_result"] = "";
265
+        $_SESSION["prefs_op_result"] = "";
266 266
 
267
-		print "<div dojoType='dijit.layout.AccordionContainer' region='center'>";
268
-		print "<div dojoType='dijit.layout.AccordionPane'
267
+        print "<div dojoType='dijit.layout.AccordionContainer' region='center'>";
268
+        print "<div dojoType='dijit.layout.AccordionPane'
269 269
 			title=\"<i class='material-icons'>person</i> ".__('Personal data / Authentication')."\">";
270 270
 
271
-		print "<div dojoType='dijit.layout.TabContainer'>";
272
-		print "<div dojoType='dijit.layout.ContentPane' title=\"".__('Personal data')."\">";
271
+        print "<div dojoType='dijit.layout.TabContainer'>";
272
+        print "<div dojoType='dijit.layout.ContentPane' title=\"".__('Personal data')."\">";
273 273
 
274
-		print "<form dojoType='dijit.form.Form' id='changeUserdataForm'>";
274
+        print "<form dojoType='dijit.form.Form' id='changeUserdataForm'>";
275 275
 
276
-		print "<script type='dojo/method' event='onSubmit' args='evt'>
276
+        print "<script type='dojo/method' event='onSubmit' args='evt'>
277 277
 		evt.preventDefault();
278 278
 		if (this.validate()) {
279 279
 			Notify.progress('Saving data...', true);
@@ -287,61 +287,61 @@  discard block
 block discarded – undo
287 287
 		}
288 288
 		</script>";
289 289
 
290
-		$sth = $this->pdo->prepare("SELECT email,full_name,otp_enabled,
290
+        $sth = $this->pdo->prepare("SELECT email,full_name,otp_enabled,
291 291
 			access_level FROM ttrss_users
292 292
 			WHERE id = ?");
293
-		$sth->execute([$_SESSION["uid"]]);
294
-		$row = $sth->fetch();
295
-
296
-		$email = htmlspecialchars($row["email"]);
297
-		$full_name = htmlspecialchars($row["full_name"]);
298
-		$otp_enabled = sql_bool_to_bool($row["otp_enabled"]);
299
-
300
-		print "<fieldset>";
301
-		print "<label>".__('Full name:')."</label>";
302
-		print "<input dojoType='dijit.form.ValidationTextBox' name='full_name' required='1' value='$full_name'>";
303
-		print "</fieldset>";
304
-
305
-		print "<fieldset>";
306
-		print "<label>".__('E-mail:')."</label>";
307
-		print "<input dojoType='dijit.form.ValidationTextBox' name='email' required='1' value='$email'>";
308
-		print "</fieldset>";
309
-
310
-		if (!SINGLE_USER_MODE && !$_SESSION["hide_hello"]) {
311
-
312
-			$access_level = $row["access_level"];
313
-			print "<fieldset>";
314
-			print "<label>".__('Access level:')."</label>";
315
-			print $access_level_names[$access_level];
316
-			print "</fieldset>";
317
-		}
293
+        $sth->execute([$_SESSION["uid"]]);
294
+        $row = $sth->fetch();
318 295
 
319
-		print_hidden("op", "pref-prefs");
320
-		print_hidden("method", "changeemail");
296
+        $email = htmlspecialchars($row["email"]);
297
+        $full_name = htmlspecialchars($row["full_name"]);
298
+        $otp_enabled = sql_bool_to_bool($row["otp_enabled"]);
321 299
 
322
-		print "<hr/>";
300
+        print "<fieldset>";
301
+        print "<label>".__('Full name:')."</label>";
302
+        print "<input dojoType='dijit.form.ValidationTextBox' name='full_name' required='1' value='$full_name'>";
303
+        print "</fieldset>";
323 304
 
324
-		print "<button dojoType='dijit.form.Button' type='submit' class='alt-primary'>".
325
-			__("Save data")."</button>";
305
+        print "<fieldset>";
306
+        print "<label>".__('E-mail:')."</label>";
307
+        print "<input dojoType='dijit.form.ValidationTextBox' name='email' required='1' value='$email'>";
308
+        print "</fieldset>";
326 309
 
327
-		print "</form>";
310
+        if (!SINGLE_USER_MODE && !$_SESSION["hide_hello"]) {
328 311
 
329
-		print "</div>"; # content pane
330
-		print "<div dojoType='dijit.layout.ContentPane' title=\"".__('Password')."\">";
312
+            $access_level = $row["access_level"];
313
+            print "<fieldset>";
314
+            print "<label>".__('Access level:')."</label>";
315
+            print $access_level_names[$access_level];
316
+            print "</fieldset>";
317
+        }
331 318
 
332
-		if ($_SESSION["auth_module"]) {
333
-			$authenticator = PluginHost::getInstance()->get_plugin($_SESSION["auth_module"]);
334
-		} else {
335
-			$authenticator = false;
336
-		}
319
+        print_hidden("op", "pref-prefs");
320
+        print_hidden("method", "changeemail");
337 321
 
338
-		if ($authenticator && method_exists($authenticator, "change_password")) {
322
+        print "<hr/>";
339 323
 
340
-			print "<div style='display : none' id='pwd_change_infobox'></div>";
324
+        print "<button dojoType='dijit.form.Button' type='submit' class='alt-primary'>".
325
+            __("Save data")."</button>";
341 326
 
342
-			print "<form dojoType='dijit.form.Form'>";
327
+        print "</form>";
343 328
 
344
-			print "<script type='dojo/method' event='onSubmit' args='evt'>
329
+        print "</div>"; # content pane
330
+        print "<div dojoType='dijit.layout.ContentPane' title=\"".__('Password')."\">";
331
+
332
+        if ($_SESSION["auth_module"]) {
333
+            $authenticator = PluginHost::getInstance()->get_plugin($_SESSION["auth_module"]);
334
+        } else {
335
+            $authenticator = false;
336
+        }
337
+
338
+        if ($authenticator && method_exists($authenticator, "change_password")) {
339
+
340
+            print "<div style='display : none' id='pwd_change_infobox'></div>";
341
+
342
+            print "<form dojoType='dijit.form.Form'>";
343
+
344
+            print "<script type='dojo/method' event='onSubmit' args='evt'>
345 345
 			evt.preventDefault();
346 346
 			if (this.validate()) {
347 347
 				Notify.progress('Changing password...', true);
@@ -370,71 +370,71 @@  discard block
 block discarded – undo
370 370
 			}
371 371
 			</script>";
372 372
 
373
-			if ($otp_enabled) {
374
-				print_notice(__("Changing your current password will disable OTP."));
375
-			}
373
+            if ($otp_enabled) {
374
+                print_notice(__("Changing your current password will disable OTP."));
375
+            }
376 376
 
377
-			print "<fieldset>";
378
-			print "<label>".__("Old password:")."</label>";
379
-			print "<input dojoType='dijit.form.ValidationTextBox' type='password' required='1' name='old_password'>";
380
-			print "</fieldset>";
377
+            print "<fieldset>";
378
+            print "<label>".__("Old password:")."</label>";
379
+            print "<input dojoType='dijit.form.ValidationTextBox' type='password' required='1' name='old_password'>";
380
+            print "</fieldset>";
381 381
 
382
-			print "<fieldset>";
383
-			print "<label>".__("New password:")."</label>";
384
-			print "<input dojoType='dijit.form.ValidationTextBox' type='password' required='1' name='new_password'>";
385
-			print "</fieldset>";
382
+            print "<fieldset>";
383
+            print "<label>".__("New password:")."</label>";
384
+            print "<input dojoType='dijit.form.ValidationTextBox' type='password' required='1' name='new_password'>";
385
+            print "</fieldset>";
386 386
 
387
-			print "<fieldset>";
388
-			print "<label>".__("Confirm password:")."</label>";
389
-			print "<input dojoType='dijit.form.ValidationTextBox' type='password' required='1' name='confirm_password'>";
390
-			print "</fieldset>";
387
+            print "<fieldset>";
388
+            print "<label>".__("Confirm password:")."</label>";
389
+            print "<input dojoType='dijit.form.ValidationTextBox' type='password' required='1' name='confirm_password'>";
390
+            print "</fieldset>";
391 391
 
392
-			print_hidden("op", "pref-prefs");
393
-			print_hidden("method", "changepassword");
392
+            print_hidden("op", "pref-prefs");
393
+            print_hidden("method", "changepassword");
394 394
 
395
-			print "<hr/>";
395
+            print "<hr/>";
396 396
 
397
-			print "<button dojoType='dijit.form.Button' type='submit' class='alt-primary'>".
398
-				__("Change password")."</button>";
397
+            print "<button dojoType='dijit.form.Button' type='submit' class='alt-primary'>".
398
+                __("Change password")."</button>";
399 399
 
400
-			print "</form>";
400
+            print "</form>";
401 401
 
402
-			print "</div>"; # content pane
402
+            print "</div>"; # content pane
403 403
 
404
-			if ($_SESSION["auth_module"] == "auth_internal") {
404
+            if ($_SESSION["auth_module"] == "auth_internal") {
405 405
 
406
-				print "<div dojoType='dijit.layout.ContentPane' title=\"" . __('App passwords') . "\">";
406
+                print "<div dojoType='dijit.layout.ContentPane' title=\"" . __('App passwords') . "\">";
407 407
 
408
-				print_notice("You can create separate passwords for API clients. Using one is required if you enable OTP.");
408
+                print_notice("You can create separate passwords for API clients. Using one is required if you enable OTP.");
409 409
 
410
-				print "<div id='app_passwords_holder'>";
411
-				$this->appPasswordList();
412
-				print "</div>";
410
+                print "<div id='app_passwords_holder'>";
411
+                $this->appPasswordList();
412
+                print "</div>";
413 413
 
414
-				print "<hr>";
414
+                print "<hr>";
415 415
 
416
-				print "<button style='float : left' class='alt-primary' dojoType='dijit.form.Button'
416
+                print "<button style='float : left' class='alt-primary' dojoType='dijit.form.Button'
417 417
 					onclick=\"Helpers.AppPasswords.generate()\">" .
418
-					__('Generate new password') . "</button> ";
418
+                    __('Generate new password') . "</button> ";
419 419
 
420
-				print "<button style='float : left' class='alt-danger' dojoType='dijit.form.Button'
420
+                print "<button style='float : left' class='alt-danger' dojoType='dijit.form.Button'
421 421
 					onclick=\"Helpers.AppPasswords.removeSelected()\">" .
422
-					__('Remove selected passwords') . "</button>";
422
+                    __('Remove selected passwords') . "</button>";
423 423
 
424
-				print "</div>"; # content pane
425
-			}
424
+                print "</div>"; # content pane
425
+            }
426 426
 
427
-			print "<div dojoType='dijit.layout.ContentPane' title=\"".__('One time passwords / Authenticator')."\">";
427
+            print "<div dojoType='dijit.layout.ContentPane' title=\"".__('One time passwords / Authenticator')."\">";
428 428
 
429
-			if ($_SESSION["auth_module"] == "auth_internal") {
429
+            if ($_SESSION["auth_module"] == "auth_internal") {
430 430
 
431
-				if ($otp_enabled) {
431
+                if ($otp_enabled) {
432 432
 
433
-					print_warning("One time passwords are currently enabled. Enter your current password below to disable.");
433
+                    print_warning("One time passwords are currently enabled. Enter your current password below to disable.");
434 434
 
435
-					print "<form dojoType='dijit.form.Form'>";
435
+                    print "<form dojoType='dijit.form.Form'>";
436 436
 
437
-					print "<script type='dojo/method' event='onSubmit' args='evt'>
437
+                    print "<script type='dojo/method' event='onSubmit' args='evt'>
438 438
 					evt.preventDefault();
439 439
 					if (this.validate()) {
440 440
 						Notify.progress('Disabling OTP', true);
@@ -453,49 +453,49 @@  discard block
 block discarded – undo
453 453
 					}
454 454
 					</script>";
455 455
 
456
-					print "<fieldset>";
457
-					print "<label>".__("Your password:")."</label>";
458
-					print "<input dojoType='dijit.form.ValidationTextBox' type='password' required='1' name='password'>";
459
-					print "</fieldset>";
456
+                    print "<fieldset>";
457
+                    print "<label>".__("Your password:")."</label>";
458
+                    print "<input dojoType='dijit.form.ValidationTextBox' type='password' required='1' name='password'>";
459
+                    print "</fieldset>";
460 460
 
461
-					print_hidden("op", "pref-prefs");
462
-					print_hidden("method", "otpdisable");
461
+                    print_hidden("op", "pref-prefs");
462
+                    print_hidden("method", "otpdisable");
463 463
 
464
-					print "<hr/>";
464
+                    print "<hr/>";
465 465
 
466
-					print "<button dojoType='dijit.form.Button' type='submit'>".
467
-						__("Disable OTP")."</button>";
466
+                    print "<button dojoType='dijit.form.Button' type='submit'>".
467
+                        __("Disable OTP")."</button>";
468 468
 
469
-					print "</form>";
469
+                    print "</form>";
470 470
 
471
-				} else {
471
+                } else {
472 472
 
473
-					print_warning("You will need a compatible Authenticator to use this. Changing your password would automatically disable OTP.");
474
-					print_notice("You will need to generate app passwords for the API clients if you enable OTP.");
473
+                    print_warning("You will need a compatible Authenticator to use this. Changing your password would automatically disable OTP.");
474
+                    print_notice("You will need to generate app passwords for the API clients if you enable OTP.");
475 475
 
476
-					if (function_exists("imagecreatefromstring")) {
477
-						print "<h3>" . __("Scan the following code by the Authenticator application or copy the key manually") . "</h3>";
476
+                    if (function_exists("imagecreatefromstring")) {
477
+                        print "<h3>" . __("Scan the following code by the Authenticator application or copy the key manually") . "</h3>";
478 478
 
479
-						$csrf_token = $_SESSION["csrf_token"];
480
-						print "<img alt='otp qr-code' src='backend.php?op=pref-prefs&method=otpqrcode&csrf_token=$csrf_token'>";
481
-					} else {
482
-						print_error("PHP GD functions are required to generate QR codes.");
483
-						print "<h3>" . __("Use the following OTP key with a compatible Authenticator application") . "</h3>";
484
-					}
479
+                        $csrf_token = $_SESSION["csrf_token"];
480
+                        print "<img alt='otp qr-code' src='backend.php?op=pref-prefs&method=otpqrcode&csrf_token=$csrf_token'>";
481
+                    } else {
482
+                        print_error("PHP GD functions are required to generate QR codes.");
483
+                        print "<h3>" . __("Use the following OTP key with a compatible Authenticator application") . "</h3>";
484
+                    }
485 485
 
486
-					print "<form dojoType='dijit.form.Form' id='changeOtpForm'>";
486
+                    print "<form dojoType='dijit.form.Form' id='changeOtpForm'>";
487 487
 
488
-					$otp_secret = $this->otpsecret();
488
+                    $otp_secret = $this->otpsecret();
489 489
 
490
-					print "<fieldset>";
491
-					print "<label>".__("OTP Key:")."</label>";
492
-					print "<input dojoType='dijit.form.ValidationTextBox' disabled='disabled' value='$otp_secret' size='32'>";
493
-					print "</fieldset>";
490
+                    print "<fieldset>";
491
+                    print "<label>".__("OTP Key:")."</label>";
492
+                    print "<input dojoType='dijit.form.ValidationTextBox' disabled='disabled' value='$otp_secret' size='32'>";
493
+                    print "</fieldset>";
494 494
 
495
-					print_hidden("op", "pref-prefs");
496
-					print_hidden("method", "otpenable");
495
+                    print_hidden("op", "pref-prefs");
496
+                    print_hidden("method", "otpenable");
497 497
 
498
-					print "<script type='dojo/method' event='onSubmit' args='evt'>
498
+                    print "<script type='dojo/method' event='onSubmit' args='evt'>
499 499
 					evt.preventDefault();
500 500
 					if (this.validate()) {
501 501
 						Notify.progress('Saving data...', true);
@@ -514,43 +514,43 @@  discard block
 block discarded – undo
514 514
 					}
515 515
 					</script>";
516 516
 
517
-					print "<fieldset>";
518
-					print "<label>".__("Your password:")."</label>";
519
-					print "<input dojoType='dijit.form.ValidationTextBox' type='password' required='1'
517
+                    print "<fieldset>";
518
+                    print "<label>".__("Your password:")."</label>";
519
+                    print "<input dojoType='dijit.form.ValidationTextBox' type='password' required='1'
520 520
 						name='password'>";
521
-					print "</fieldset>";
521
+                    print "</fieldset>";
522 522
 
523
-					print "<fieldset>";
524
-					print "<label>".__("One time password:")."</label>";
525
-					print "<input dojoType='dijit.form.ValidationTextBox' autocomplete='off'
523
+                    print "<fieldset>";
524
+                    print "<label>".__("One time password:")."</label>";
525
+                    print "<input dojoType='dijit.form.ValidationTextBox' autocomplete='off'
526 526
 						required='1' name='otp'>";
527
-					print "</fieldset>";
527
+                    print "</fieldset>";
528 528
 
529
-					print "<hr/>";
530
-					print "<button dojoType='dijit.form.Button' type='submit' class='alt-primary'>".
531
-						__("Enable OTP")."</button>";
529
+                    print "<hr/>";
530
+                    print "<button dojoType='dijit.form.Button' type='submit' class='alt-primary'>".
531
+                        __("Enable OTP")."</button>";
532 532
 
533
-					print "</form>";
533
+                    print "</form>";
534 534
 
535
-				}
536
-			}
535
+                }
536
+            }
537 537
 
538
-			print "</div>"; # content pane
539
-			print "</div>"; # tab container
538
+            print "</div>"; # content pane
539
+            print "</div>"; # tab container
540 540
 
541
-		}
541
+        }
542 542
 
543
-		PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION,
544
-			"hook_prefs_tab_section", "prefPrefsAuth");
543
+        PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION,
544
+            "hook_prefs_tab_section", "prefPrefsAuth");
545 545
 
546
-		print "</div>"; #pane
546
+        print "</div>"; #pane
547 547
 
548
-		print "<div dojoType='dijit.layout.AccordionPane' selected='true'
548
+        print "<div dojoType='dijit.layout.AccordionPane' selected='true'
549 549
 			title=\"<i class='material-icons'>settings</i> ".__('Preferences')."\">";
550 550
 
551
-		print "<form dojoType='dijit.form.Form' id='changeSettingsForm'>";
551
+        print "<form dojoType='dijit.form.Form' id='changeSettingsForm'>";
552 552
 
553
-		print "<script type='dojo/method' event='onSubmit' args='evt, quit'>
553
+        print "<script type='dojo/method' event='onSubmit' args='evt, quit'>
554 554
 		if (evt) evt.preventDefault();
555 555
 		if (this.validate()) {
556 556
 			console.log(dojo.objectToQuery(this.getValues()));
@@ -572,23 +572,23 @@  discard block
 block discarded – undo
572 572
 		}
573 573
 		</script>";
574 574
 
575
-		print '<div dojoType="dijit.layout.BorderContainer" gutters="false">';
575
+        print '<div dojoType="dijit.layout.BorderContainer" gutters="false">';
576 576
 
577
-		print '<div dojoType="dijit.layout.ContentPane" region="center" style="overflow-y : auto">';
577
+        print '<div dojoType="dijit.layout.ContentPane" region="center" style="overflow-y : auto">';
578 578
 
579
-		$profile = $_SESSION["profile"];
579
+        $profile = $_SESSION["profile"];
580 580
 
581
-		if ($profile) {
582
-			print_notice(__("Some preferences are only available in default profile."));
581
+        if ($profile) {
582
+            print_notice(__("Some preferences are only available in default profile."));
583 583
 
584
-			initialize_user_prefs($_SESSION["uid"], $profile);
585
-		} else {
586
-			initialize_user_prefs($_SESSION["uid"]);
587
-		}
584
+            initialize_user_prefs($_SESSION["uid"], $profile);
585
+        } else {
586
+            initialize_user_prefs($_SESSION["uid"]);
587
+        }
588 588
 
589
-		$prefs_available = [];
589
+        $prefs_available = [];
590 590
 
591
-		$sth = $this->pdo->prepare("SELECT DISTINCT
591
+        $sth = $this->pdo->prepare("SELECT DISTINCT
592 592
 			ttrss_user_prefs.pref_name,value,type_name,
593 593
 			ttrss_prefs_sections.order_id,
594 594
 			def_value,section_id
@@ -599,230 +599,230 @@  discard block
 block discarded – undo
599 599
 				ttrss_user_prefs.pref_name = ttrss_prefs.pref_name AND
600 600
 				owner_uid = :uid
601 601
 			ORDER BY ttrss_prefs_sections.order_id,pref_name");
602
-		$sth->execute([":uid" => $_SESSION['uid'], ":profile" => $profile]);
602
+        $sth->execute([":uid" => $_SESSION['uid'], ":profile" => $profile]);
603 603
 
604
-		$listed_boolean_prefs = [];
604
+        $listed_boolean_prefs = [];
605 605
 
606
-		while ($line = $sth->fetch()) {
606
+        while ($line = $sth->fetch()) {
607 607
 
608
-			if (in_array($line["pref_name"], $this->pref_blacklist)) {
609
-				continue;
610
-			}
608
+            if (in_array($line["pref_name"], $this->pref_blacklist)) {
609
+                continue;
610
+            }
611 611
 
612
-			if ($profile && in_array($line["pref_name"], $this->profile_blacklist)) {
613
-				continue;
614
-			}
612
+            if ($profile && in_array($line["pref_name"], $this->profile_blacklist)) {
613
+                continue;
614
+            }
615 615
 
616
-			$pref_name = $line["pref_name"];
617
-			$short_desc = $this->getShortDesc($pref_name);
616
+            $pref_name = $line["pref_name"];
617
+            $short_desc = $this->getShortDesc($pref_name);
618 618
 
619
-			if (!$short_desc)
620
-				continue;
619
+            if (!$short_desc)
620
+                continue;
621 621
 
622
-			$prefs_available[$pref_name] = [
623
-				'type_name' => $line["type_name"],
624
-				'value' => $line['value'],
625
-				'help_text' => $this->getHelpText($pref_name),
626
-				'short_desc' => $short_desc
627
-			];
628
-		}
622
+            $prefs_available[$pref_name] = [
623
+                'type_name' => $line["type_name"],
624
+                'value' => $line['value'],
625
+                'help_text' => $this->getHelpText($pref_name),
626
+                'short_desc' => $short_desc
627
+            ];
628
+        }
629 629
 
630
-		foreach (array_keys($this->pref_item_map) as $section) {
630
+        foreach (array_keys($this->pref_item_map) as $section) {
631 631
 
632
-			print "<h2>$section</h2>";
632
+            print "<h2>$section</h2>";
633 633
 
634
-			foreach ($this->pref_item_map[$section] as $pref_name) {
634
+            foreach ($this->pref_item_map[$section] as $pref_name) {
635 635
 
636
-				if ($pref_name == 'BLOCK_SEPARATOR' && !$profile) {
637
-					print "<hr/>";
638
-					continue;
639
-				}
636
+                if ($pref_name == 'BLOCK_SEPARATOR' && !$profile) {
637
+                    print "<hr/>";
638
+                    continue;
639
+                }
640 640
 
641
-				if ($pref_name == "DEFAULT_SEARCH_LANGUAGE" && DB_TYPE != "pgsql") {
642
-					continue;
643
-				}
641
+                if ($pref_name == "DEFAULT_SEARCH_LANGUAGE" && DB_TYPE != "pgsql") {
642
+                    continue;
643
+                }
644 644
 
645
-				if ($item = $prefs_available[$pref_name]) {
645
+                if ($item = $prefs_available[$pref_name]) {
646 646
 
647
-					print "<fieldset class='prefs'>";
647
+                    print "<fieldset class='prefs'>";
648 648
 
649
-					print "<label for='CB_$pref_name'>";
650
-					print $item['short_desc'] . ":";
651
-					print "</label>";
649
+                    print "<label for='CB_$pref_name'>";
650
+                    print $item['short_desc'] . ":";
651
+                    print "</label>";
652 652
 
653
-					$value = $item['value'];
654
-					$type_name = $item['type_name'];
653
+                    $value = $item['value'];
654
+                    $type_name = $item['type_name'];
655 655
 
656
-					if ($pref_name == "USER_LANGUAGE") {
657
-						print_select_hash($pref_name, $value, get_translations(),
658
-							"style='width : 220px; margin : 0px' dojoType='fox.form.Select'");
656
+                    if ($pref_name == "USER_LANGUAGE") {
657
+                        print_select_hash($pref_name, $value, get_translations(),
658
+                            "style='width : 220px; margin : 0px' dojoType='fox.form.Select'");
659 659
 
660
-					} else if ($pref_name == "USER_TIMEZONE") {
660
+                    } else if ($pref_name == "USER_TIMEZONE") {
661 661
 
662
-						$timezones = explode("\n", file_get_contents("lib/timezones.txt"));
662
+                        $timezones = explode("\n", file_get_contents("lib/timezones.txt"));
663 663
 
664
-						print_select($pref_name, $value, $timezones, 'dojoType="dijit.form.FilteringSelect"');
665
-					} else if ($pref_name == "USER_CSS_THEME") {
664
+                        print_select($pref_name, $value, $timezones, 'dojoType="dijit.form.FilteringSelect"');
665
+                    } else if ($pref_name == "USER_CSS_THEME") {
666 666
 
667
-						$themes = array_merge(glob("themes/*.php"), glob("themes/*.css"), glob("themes.local/*.css"));
668
-						$themes = array_map("basename", $themes);
669
-						$themes = array_filter($themes, "theme_exists");
670
-						asort($themes);
667
+                        $themes = array_merge(glob("themes/*.php"), glob("themes/*.css"), glob("themes.local/*.css"));
668
+                        $themes = array_map("basename", $themes);
669
+                        $themes = array_filter($themes, "theme_exists");
670
+                        asort($themes);
671 671
 
672
-						if (!theme_exists($value)) $value = "default.php";
672
+                        if (!theme_exists($value)) $value = "default.php";
673 673
 
674
-						print "<select name='$pref_name' id='$pref_name' dojoType='fox.form.Select'>";
674
+                        print "<select name='$pref_name' id='$pref_name' dojoType='fox.form.Select'>";
675 675
 
676
-						$issel = $value == "default.php" ? "selected='selected'" : "";
677
-						print "<option $issel value='default.php'>".__("default")."</option>";
676
+                        $issel = $value == "default.php" ? "selected='selected'" : "";
677
+                        print "<option $issel value='default.php'>".__("default")."</option>";
678 678
 
679
-						foreach ($themes as $theme) {
680
-							$issel = $value == $theme ? "selected='selected'" : "";
681
-							print "<option $issel value='$theme'>$theme</option>";
682
-						}
679
+                        foreach ($themes as $theme) {
680
+                            $issel = $value == $theme ? "selected='selected'" : "";
681
+                            print "<option $issel value='$theme'>$theme</option>";
682
+                        }
683 683
 
684
-						print "</select>";
684
+                        print "</select>";
685 685
 
686
-						print " <button dojoType=\"dijit.form.Button\" class='alt-info'
686
+                        print " <button dojoType=\"dijit.form.Button\" class='alt-info'
687 687
 							onclick=\"Helpers.customizeCSS()\">" . __('Customize') . "</button>";
688 688
 
689
-						print " <button dojoType='dijit.form.Button' onclick='window.open(\"https://tt-rss.org/wiki/Themes\")'>
689
+                        print " <button dojoType='dijit.form.Button' onclick='window.open(\"https://tt-rss.org/wiki/Themes\")'>
690 690
 							<i class='material-icons'>open_in_new</i> ".__("More themes...")."</button>";
691 691
 
692
-					} else if ($pref_name == "DEFAULT_UPDATE_INTERVAL") {
692
+                    } else if ($pref_name == "DEFAULT_UPDATE_INTERVAL") {
693 693
 
694
-						global $update_intervals_nodefault;
694
+                        global $update_intervals_nodefault;
695 695
 
696
-						print_select_hash($pref_name, $value, $update_intervals_nodefault,
697
-							'dojoType="fox.form.Select"');
698
-					} else if ($pref_name == "DEFAULT_SEARCH_LANGUAGE") {
696
+                        print_select_hash($pref_name, $value, $update_intervals_nodefault,
697
+                            'dojoType="fox.form.Select"');
698
+                    } else if ($pref_name == "DEFAULT_SEARCH_LANGUAGE") {
699 699
 
700
-						print_select($pref_name, $value, Pref_Feeds::get_ts_languages(),
701
-							'dojoType="fox.form.Select"');
700
+                        print_select($pref_name, $value, Pref_Feeds::get_ts_languages(),
701
+                            'dojoType="fox.form.Select"');
702 702
 
703
-					} else if ($type_name == "bool") {
703
+                    } else if ($type_name == "bool") {
704 704
 
705
-						array_push($listed_boolean_prefs, $pref_name);
705
+                        array_push($listed_boolean_prefs, $pref_name);
706 706
 
707
-						$checked = ($value == "true") ? "checked=\"checked\"" : "";
707
+                        $checked = ($value == "true") ? "checked=\"checked\"" : "";
708 708
 
709
-						if ($pref_name == "PURGE_UNREAD_ARTICLES" && FORCE_ARTICLE_PURGE != 0) {
710
-							$disabled = "disabled=\"1\"";
711
-							$checked = "checked=\"checked\"";
712
-						} else {
713
-							$disabled = "";
714
-						}
709
+                        if ($pref_name == "PURGE_UNREAD_ARTICLES" && FORCE_ARTICLE_PURGE != 0) {
710
+                            $disabled = "disabled=\"1\"";
711
+                            $checked = "checked=\"checked\"";
712
+                        } else {
713
+                            $disabled = "";
714
+                        }
715 715
 
716
-						print "<input type='checkbox' name='$pref_name' $checked $disabled
716
+                        print "<input type='checkbox' name='$pref_name' $checked $disabled
717 717
 							dojoType='dijit.form.CheckBox' id='CB_$pref_name' value='1'>";
718 718
 
719
-					} else if (array_search($pref_name, array('FRESH_ARTICLE_MAX_AGE',
720
-							'PURGE_OLD_DAYS', 'LONG_DATE_FORMAT', 'SHORT_DATE_FORMAT')) !== false) {
719
+                    } else if (array_search($pref_name, array('FRESH_ARTICLE_MAX_AGE',
720
+                            'PURGE_OLD_DAYS', 'LONG_DATE_FORMAT', 'SHORT_DATE_FORMAT')) !== false) {
721 721
 
722
-						$regexp = ($type_name == 'integer') ? 'regexp="^\d*$"' : '';
722
+                        $regexp = ($type_name == 'integer') ? 'regexp="^\d*$"' : '';
723 723
 
724
-						if ($pref_name == "PURGE_OLD_DAYS" && FORCE_ARTICLE_PURGE != 0) {
725
-							$disabled = "disabled='1'";
726
-							$value = FORCE_ARTICLE_PURGE;
727
-						} else {
728
-							$disabled = "";
729
-						}
724
+                        if ($pref_name == "PURGE_OLD_DAYS" && FORCE_ARTICLE_PURGE != 0) {
725
+                            $disabled = "disabled='1'";
726
+                            $value = FORCE_ARTICLE_PURGE;
727
+                        } else {
728
+                            $disabled = "";
729
+                        }
730 730
 
731
-						if ($type_name == 'integer')
732
-							print "<input dojoType=\"dijit.form.NumberSpinner\"
731
+                        if ($type_name == 'integer')
732
+                            print "<input dojoType=\"dijit.form.NumberSpinner\"
733 733
 								required='1' $disabled
734 734
 								name=\"$pref_name\" value=\"$value\">";
735
-						else
736
-							print "<input dojoType=\"dijit.form.TextBox\"
735
+                        else
736
+                            print "<input dojoType=\"dijit.form.TextBox\"
737 737
 								required='1' $regexp $disabled
738 738
 								name=\"$pref_name\" value=\"$value\">";
739 739
 
740
-					} else if ($pref_name == "SSL_CERT_SERIAL") {
740
+                    } else if ($pref_name == "SSL_CERT_SERIAL") {
741 741
 
742
-						print "<input dojoType='dijit.form.ValidationTextBox'
742
+                        print "<input dojoType='dijit.form.ValidationTextBox'
743 743
 							id='SSL_CERT_SERIAL' readonly='1'
744 744
 							name=\"$pref_name\" value=\"$value\">";
745 745
 
746
-						$cert_serial = htmlspecialchars(get_ssl_certificate_id());
747
-						$has_serial = ($cert_serial) ? "false" : "true";
746
+                        $cert_serial = htmlspecialchars(get_ssl_certificate_id());
747
+                        $has_serial = ($cert_serial) ? "false" : "true";
748 748
 
749
-						print "<button dojoType='dijit.form.Button' disabled='$has_serial'
749
+                        print "<button dojoType='dijit.form.Button' disabled='$has_serial'
750 750
 							onclick=\"dijit.byId('SSL_CERT_SERIAL').attr('value', '$cert_serial')\">" .
751
-							__('Register') . "</button>";
751
+                            __('Register') . "</button>";
752 752
 
753
-						print "<button dojoType='dijit.form.Button' class='alt-danger'
753
+                        print "<button dojoType='dijit.form.Button' class='alt-danger'
754 754
 							onclick=\"dijit.byId('SSL_CERT_SERIAL').attr('value', '')\">" .
755
-							__('Clear') . "</button>";
755
+                            __('Clear') . "</button>";
756 756
 
757
-						print "<button dojoType='dijit.form.Button' class='alt-info'
757
+                        print "<button dojoType='dijit.form.Button' class='alt-info'
758 758
 							onclick='window.open(\"https://tt-rss.org/wiki/SSL%20Certificate%20Authentication\")'>
759 759
 							<i class='material-icons'>help</i> ".__("More info...")."</button>";
760 760
 
761
-					} else if ($pref_name == 'DIGEST_PREFERRED_TIME') {
762
-						print "<input dojoType=\"dijit.form.ValidationTextBox\"
761
+                    } else if ($pref_name == 'DIGEST_PREFERRED_TIME') {
762
+                        print "<input dojoType=\"dijit.form.ValidationTextBox\"
763 763
 							id=\"$pref_name\" regexp=\"[012]?\d:\d\d\" placeHolder=\"12:00\"
764 764
 							name=\"$pref_name\" value=\"$value\">";
765 765
 
766
-						$item['help_text'] .= ". " . T_sprintf("Current server time: %s", date("H:i"));
767
-					} else {
768
-						$regexp = ($type_name == 'integer') ? 'regexp="^\d*$"' : '';
766
+                        $item['help_text'] .= ". " . T_sprintf("Current server time: %s", date("H:i"));
767
+                    } else {
768
+                        $regexp = ($type_name == 'integer') ? 'regexp="^\d*$"' : '';
769 769
 
770
-						print "<input dojoType=\"dijit.form.ValidationTextBox\" $regexp name=\"$pref_name\" value=\"$value\">";
771
-					}
770
+                        print "<input dojoType=\"dijit.form.ValidationTextBox\" $regexp name=\"$pref_name\" value=\"$value\">";
771
+                    }
772 772
 
773
-					if ($item['help_text'])
774
-						print "<div class='help-text text-muted'><label for='CB_$pref_name'>".$item['help_text']."</label></div>";
773
+                    if ($item['help_text'])
774
+                        print "<div class='help-text text-muted'><label for='CB_$pref_name'>".$item['help_text']."</label></div>";
775 775
 
776
-					print "</fieldset>";
777
-				}
778
-			}
779
-		}
776
+                    print "</fieldset>";
777
+                }
778
+            }
779
+        }
780 780
 
781
-		$listed_boolean_prefs = htmlspecialchars(join(",", $listed_boolean_prefs));
781
+        $listed_boolean_prefs = htmlspecialchars(join(",", $listed_boolean_prefs));
782 782
 
783
-		print_hidden("boolean_prefs", "$listed_boolean_prefs");
783
+        print_hidden("boolean_prefs", "$listed_boolean_prefs");
784 784
 
785
-		PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION,
786
-			"hook_prefs_tab_section", "prefPrefsPrefsInside");
785
+        PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION,
786
+            "hook_prefs_tab_section", "prefPrefsPrefsInside");
787 787
 
788
-		print '</div>'; # inside pane
789
-		print '<div dojoType="dijit.layout.ContentPane" region="bottom">';
788
+        print '</div>'; # inside pane
789
+        print '<div dojoType="dijit.layout.ContentPane" region="bottom">';
790 790
 
791
-		print_hidden("op", "pref-prefs");
792
-		print_hidden("method", "saveconfig");
791
+        print_hidden("op", "pref-prefs");
792
+        print_hidden("method", "saveconfig");
793 793
 
794
-		print "<div dojoType=\"fox.form.ComboButton\" type=\"submit\" class=\"alt-primary\">
794
+        print "<div dojoType=\"fox.form.ComboButton\" type=\"submit\" class=\"alt-primary\">
795 795
 			<span>".__('Save configuration')."</span>
796 796
 			<div dojoType=\"dijit.DropDownMenu\">
797 797
 				<div dojoType=\"dijit.MenuItem\"
798 798
 					onclick=\"dijit.byId('changeSettingsForm').onSubmit(null, true)\">".
799
-				__("Save and exit preferences")."</div>
799
+                __("Save and exit preferences")."</div>
800 800
 			</div>
801 801
 			</div>";
802 802
 
803
-		print "<button dojoType=\"dijit.form.Button\" onclick=\"return Helpers.editProfiles()\">".
804
-			__('Manage profiles')."</button> ";
803
+        print "<button dojoType=\"dijit.form.Button\" onclick=\"return Helpers.editProfiles()\">".
804
+            __('Manage profiles')."</button> ";
805 805
 
806
-		print "<button dojoType=\"dijit.form.Button\" class=\"alt-danger\" onclick=\"return Helpers.confirmReset()\">".
807
-			__('Reset to defaults')."</button>";
806
+        print "<button dojoType=\"dijit.form.Button\" class=\"alt-danger\" onclick=\"return Helpers.confirmReset()\">".
807
+            __('Reset to defaults')."</button>";
808 808
 
809
-		print "&nbsp;";
809
+        print "&nbsp;";
810 810
 
811
-		PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION,
812
-			"hook_prefs_tab_section", "prefPrefsPrefsOutside");
811
+        PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION,
812
+            "hook_prefs_tab_section", "prefPrefsPrefsOutside");
813 813
 
814
-		print "</form>";
815
-		print '</div>'; # inner pane
816
-		print '</div>'; # border container
814
+        print "</form>";
815
+        print '</div>'; # inner pane
816
+        print '</div>'; # border container
817 817
 
818
-		print "</div>"; #pane
818
+        print "</div>"; #pane
819 819
 
820
-		print "<div dojoType=\"dijit.layout.AccordionPane\"
820
+        print "<div dojoType=\"dijit.layout.AccordionPane\"
821 821
 			title=\"<i class='material-icons'>extension</i> ".__('Plugins')."\">";
822 822
 
823
-		print "<form dojoType=\"dijit.form.Form\" id=\"changePluginsForm\">";
823
+        print "<form dojoType=\"dijit.form.Form\" id=\"changePluginsForm\">";
824 824
 
825
-		print "<script type=\"dojo/method\" event=\"onSubmit\" args=\"evt\">
825
+        print "<script type=\"dojo/method\" event=\"onSubmit\" args=\"evt\">
826 826
 		evt.preventDefault();
827 827
 		if (this.validate()) {
828 828
 			Notify.progress('Saving data...', true);
@@ -839,383 +839,383 @@  discard block
 block discarded – undo
839 839
 		}
840 840
 		</script>";
841 841
 
842
-		print_hidden("op", "pref-prefs");
843
-		print_hidden("method", "setplugins");
842
+        print_hidden("op", "pref-prefs");
843
+        print_hidden("method", "setplugins");
844 844
 
845
-		print '<div dojoType="dijit.layout.BorderContainer" gutters="false">';
846
-		print '<div dojoType="dijit.layout.ContentPane" region="center" style="overflow-y : auto">';
845
+        print '<div dojoType="dijit.layout.BorderContainer" gutters="false">';
846
+        print '<div dojoType="dijit.layout.ContentPane" region="center" style="overflow-y : auto">';
847 847
 
848
-		if (ini_get("open_basedir") && function_exists("curl_init") && !defined("NO_CURL")) {
849
-			print_warning("Your PHP configuration has open_basedir restrictions enabled. Some plugins relying on CURL for functionality may not work correctly.");
850
-		}
848
+        if (ini_get("open_basedir") && function_exists("curl_init") && !defined("NO_CURL")) {
849
+            print_warning("Your PHP configuration has open_basedir restrictions enabled. Some plugins relying on CURL for functionality may not work correctly.");
850
+        }
851 851
 
852
-		$feed_handler_whitelist = [ "Af_Comics" ];
852
+        $feed_handler_whitelist = [ "Af_Comics" ];
853 853
 
854
-		$feed_handlers = array_merge(
855
-			PluginHost::getInstance()->get_hooks(PluginHost::HOOK_FEED_FETCHED),
856
-			PluginHost::getInstance()->get_hooks(PluginHost::HOOK_FEED_PARSED),
857
-			PluginHost::getInstance()->get_hooks(PluginHost::HOOK_FETCH_FEED));
854
+        $feed_handlers = array_merge(
855
+            PluginHost::getInstance()->get_hooks(PluginHost::HOOK_FEED_FETCHED),
856
+            PluginHost::getInstance()->get_hooks(PluginHost::HOOK_FEED_PARSED),
857
+            PluginHost::getInstance()->get_hooks(PluginHost::HOOK_FETCH_FEED));
858 858
 
859
-		$feed_handlers = array_filter($feed_handlers, function($plugin) use ($feed_handler_whitelist) {
860
-			return in_array(get_class($plugin), $feed_handler_whitelist) === FALSE; });
859
+        $feed_handlers = array_filter($feed_handlers, function($plugin) use ($feed_handler_whitelist) {
860
+            return in_array(get_class($plugin), $feed_handler_whitelist) === FALSE; });
861 861
 
862
-		if (count($feed_handlers) > 0) {
863
-			print_error(
864
-				T_sprintf("The following plugins use per-feed content hooks. This may cause excessive data usage and origin server load resulting in a ban of your instance: <b>%s</b>" ,
865
-					implode(", ", array_map(function($plugin) { return get_class($plugin); }, $feed_handlers))
866
-				) . " (<a href='https://tt-rss.org/wiki/FeedHandlerPlugins' target='_blank'>".__("More info...")."</a>)"
867
-			);
868
-		}
862
+        if (count($feed_handlers) > 0) {
863
+            print_error(
864
+                T_sprintf("The following plugins use per-feed content hooks. This may cause excessive data usage and origin server load resulting in a ban of your instance: <b>%s</b>" ,
865
+                    implode(", ", array_map(function($plugin) { return get_class($plugin); }, $feed_handlers))
866
+                ) . " (<a href='https://tt-rss.org/wiki/FeedHandlerPlugins' target='_blank'>".__("More info...")."</a>)"
867
+            );
868
+        }
869 869
 
870
-		print "<h2>".__("System plugins")."</h2>";
871
-		print_notice("System plugins are enabled in <strong>config.php</strong> for all users.");
870
+        print "<h2>".__("System plugins")."</h2>";
871
+        print_notice("System plugins are enabled in <strong>config.php</strong> for all users.");
872 872
 
873
-		$system_enabled = array_map("trim", explode(",", PLUGINS));
874
-		$user_enabled = array_map("trim", explode(",", get_pref("_ENABLED_PLUGINS")));
873
+        $system_enabled = array_map("trim", explode(",", PLUGINS));
874
+        $user_enabled = array_map("trim", explode(",", get_pref("_ENABLED_PLUGINS")));
875 875
 
876
-		$tmppluginhost = new PluginHost();
877
-		$tmppluginhost->load_all($tmppluginhost::KIND_ALL, $_SESSION["uid"], true);
878
-		$tmppluginhost->load_data();
876
+        $tmppluginhost = new PluginHost();
877
+        $tmppluginhost->load_all($tmppluginhost::KIND_ALL, $_SESSION["uid"], true);
878
+        $tmppluginhost->load_data();
879 879
 
880
-		foreach ($tmppluginhost->get_plugins() as $name => $plugin) {
881
-			$about = $plugin->about();
880
+        foreach ($tmppluginhost->get_plugins() as $name => $plugin) {
881
+            $about = $plugin->about();
882 882
 
883
-			if ($about[3]) {
884
-				if (in_array($name, $system_enabled)) {
885
-					$checked = "checked='1'";
886
-				} else {
887
-					$checked = "";
888
-				}
883
+            if ($about[3]) {
884
+                if (in_array($name, $system_enabled)) {
885
+                    $checked = "checked='1'";
886
+                } else {
887
+                    $checked = "";
888
+                }
889 889
 
890
-				print "<fieldset class='prefs plugin'>
890
+                print "<fieldset class='prefs plugin'>
891 891
 					<label>$name:</label>
892 892
 					<label class='checkbox description text-muted' id='PLABEL-$name'>
893 893
 						<input disabled='1'
894 894
 							dojoType='dijit.form.CheckBox' $checked type='checkbox'>
895 895
 						".htmlspecialchars($about[1]). "</label>";
896 896
 
897
-					if (@$about[4]) {
898
-						print "<button dojoType='dijit.form.Button' class='alt-info'
897
+                    if (@$about[4]) {
898
+                        print "<button dojoType='dijit.form.Button' class='alt-info'
899 899
 							onclick='window.open(\"".htmlspecialchars($about[4])."\")'>
900 900
 								<i class='material-icons'>open_in_new</i> ".__("More info...")."</button>";
901
-					}
901
+                    }
902 902
 
903
-					print "<div dojoType='dijit.Tooltip' connectId='PLABEL-$name' position='after'>".
904
-						htmlspecialchars(T_sprintf("v%.2f, by %s", $about[0], $about[2])).
905
-						"</div>";
903
+                    print "<div dojoType='dijit.Tooltip' connectId='PLABEL-$name' position='after'>".
904
+                        htmlspecialchars(T_sprintf("v%.2f, by %s", $about[0], $about[2])).
905
+                        "</div>";
906 906
 
907
-				print "</fieldset>";
907
+                print "</fieldset>";
908 908
 
909
-			}
910
-		}
909
+            }
910
+        }
911 911
 
912
-		print "<h2>".__("User plugins")."</h2>";
912
+        print "<h2>".__("User plugins")."</h2>";
913 913
 
914
-		foreach ($tmppluginhost->get_plugins() as $name => $plugin) {
915
-			$about = $plugin->about();
914
+        foreach ($tmppluginhost->get_plugins() as $name => $plugin) {
915
+            $about = $plugin->about();
916 916
 
917
-			if (!$about[3]) {
917
+            if (!$about[3]) {
918 918
 
919
-				$checked = "";
920
-				$disabled = "";
919
+                $checked = "";
920
+                $disabled = "";
921 921
 
922
-				if (in_array($name, $system_enabled)) {
923
-					$checked = "checked='1'";
924
-					$disabled = "disabled='1'";
925
-				} else if (in_array($name, $user_enabled)) {
926
-					$checked = "checked='1'";
927
-				}
922
+                if (in_array($name, $system_enabled)) {
923
+                    $checked = "checked='1'";
924
+                    $disabled = "disabled='1'";
925
+                } else if (in_array($name, $user_enabled)) {
926
+                    $checked = "checked='1'";
927
+                }
928 928
 
929
-				print "<fieldset class='prefs plugin'>
929
+                print "<fieldset class='prefs plugin'>
930 930
 					<label>$name:</label>
931 931
 					<label class='checkbox description text-muted' id='PLABEL-$name'>
932 932
 						<input name='plugins[]' value='$name' dojoType='dijit.form.CheckBox' $checked $disabled type='checkbox'>
933 933
 						".htmlspecialchars($about[1])."</label>";
934 934
 
935
-				if (count($tmppluginhost->get_all($plugin)) > 0) {
936
-					if (in_array($name, $system_enabled) || in_array($name, $user_enabled)) {
937
-						print " <button dojoType='dijit.form.Button'
935
+                if (count($tmppluginhost->get_all($plugin)) > 0) {
936
+                    if (in_array($name, $system_enabled) || in_array($name, $user_enabled)) {
937
+                        print " <button dojoType='dijit.form.Button'
938 938
 							onclick=\"Helpers.clearPluginData('$name')\">
939 939
 								<i class='material-icons'>clear</i> ".__("Clear data")."</button>";
940
-					}
941
-				}
940
+                    }
941
+                }
942 942
 
943
-				if (@$about[4]) {
944
-					print " <button dojoType='dijit.form.Button' class='alt-info'
943
+                if (@$about[4]) {
944
+                    print " <button dojoType='dijit.form.Button' class='alt-info'
945 945
 							onclick='window.open(\"".htmlspecialchars($about[4])."\")'>
946 946
 								<i class='material-icons'>open_in_new</i> ".__("More info...")."</button>";
947
-				}
947
+                }
948 948
 
949
-				print "<div dojoType='dijit.Tooltip' connectId='PLABEL-$name' position='after'>".
950
-					htmlspecialchars(T_sprintf("v%.2f, by %s", $about[0], $about[2])).
951
-					"</div>";
949
+                print "<div dojoType='dijit.Tooltip' connectId='PLABEL-$name' position='after'>".
950
+                    htmlspecialchars(T_sprintf("v%.2f, by %s", $about[0], $about[2])).
951
+                    "</div>";
952 952
 
953
-				print "</fieldset>";
954
-			}
955
-		}
953
+                print "</fieldset>";
954
+            }
955
+        }
956 956
 
957
-		print "</div>"; #content-pane
958
-		print '<div dojoType="dijit.layout.ContentPane" region="bottom">';
957
+        print "</div>"; #content-pane
958
+        print '<div dojoType="dijit.layout.ContentPane" region="bottom">';
959 959
 
960
-		print "<button dojoType='dijit.form.Button' style='float : left' class='alt-info' onclick='window.open(\"https://tt-rss.org/wiki/Plugins\")'>
960
+        print "<button dojoType='dijit.form.Button' style='float : left' class='alt-info' onclick='window.open(\"https://tt-rss.org/wiki/Plugins\")'>
961 961
 			<i class='material-icons'>help</i> ".__("More info...")."</button>";
962 962
 
963
-		print "<button dojoType='dijit.form.Button' class='alt-primary' type='submit'>".
964
-			__("Enable selected plugins")."</button>";
965
-		print "</div>"; #pane
963
+        print "<button dojoType='dijit.form.Button' class='alt-primary' type='submit'>".
964
+            __("Enable selected plugins")."</button>";
965
+        print "</div>"; #pane
966 966
 
967
-		print "</div>"; #pane
968
-		print "</div>"; #border-container
967
+        print "</div>"; #pane
968
+        print "</div>"; #border-container
969 969
 
970
-		print "</form>";
970
+        print "</form>";
971 971
 
972
-		PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB,
973
-			"hook_prefs_tab", "prefPrefs");
972
+        PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB,
973
+            "hook_prefs_tab", "prefPrefs");
974 974
 
975
-		print "</div>"; #container
975
+        print "</div>"; #container
976 976
 
977
-	}
977
+    }
978 978
 
979
-	public function toggleAdvanced() {
980
-		$_SESSION["prefs_show_advanced"] = !$_SESSION["prefs_show_advanced"];
981
-	}
979
+    public function toggleAdvanced() {
980
+        $_SESSION["prefs_show_advanced"] = !$_SESSION["prefs_show_advanced"];
981
+    }
982 982
 
983
-	public function otpsecret() {
984
-		$sth = $this->pdo->prepare("SELECT salt, otp_enabled
983
+    public function otpsecret() {
984
+        $sth = $this->pdo->prepare("SELECT salt, otp_enabled
985 985
 			FROM ttrss_users
986 986
 			WHERE id = ?");
987
-		$sth->execute([$_SESSION['uid']]);
987
+        $sth->execute([$_SESSION['uid']]);
988 988
 
989
-		if ($row = $sth->fetch()) {
990
-			$otp_enabled = sql_bool_to_bool($row["otp_enabled"]);
989
+        if ($row = $sth->fetch()) {
990
+            $otp_enabled = sql_bool_to_bool($row["otp_enabled"]);
991 991
 
992
-			if (!$otp_enabled) {
993
-				$base32 = new \OTPHP\Base32();
994
-				$secret = $base32->encode(mb_substr(sha1($row["salt"]), 0, 12), false);
992
+            if (!$otp_enabled) {
993
+                $base32 = new \OTPHP\Base32();
994
+                $secret = $base32->encode(mb_substr(sha1($row["salt"]), 0, 12), false);
995 995
 
996
-				return $secret;
997
-			}
998
-		}
996
+                return $secret;
997
+            }
998
+        }
999 999
 
1000
-		return false;
1001
-	}
1000
+        return false;
1001
+    }
1002 1002
 
1003
-	public function otpqrcode() {
1004
-		require_once "lib/phpqrcode/phpqrcode.php";
1003
+    public function otpqrcode() {
1004
+        require_once "lib/phpqrcode/phpqrcode.php";
1005 1005
 
1006
-		$sth = $this->pdo->prepare("SELECT login
1006
+        $sth = $this->pdo->prepare("SELECT login
1007 1007
 			FROM ttrss_users
1008 1008
 			WHERE id = ?");
1009
-		$sth->execute([$_SESSION['uid']]);
1009
+        $sth->execute([$_SESSION['uid']]);
1010 1010
 
1011
-		if ($row = $sth->fetch()) {
1012
-			$secret = $this->otpsecret();
1013
-			$login = $row['login'];
1011
+        if ($row = $sth->fetch()) {
1012
+            $secret = $this->otpsecret();
1013
+            $login = $row['login'];
1014 1014
 
1015
-			if ($secret) {
1016
-				QRcode::png("otpauth://totp/".urlencode($login).
1017
-					"?secret=$secret&issuer=".urlencode("Tiny Tiny RSS"));
1018
-			}
1019
-		}
1020
-	}
1015
+            if ($secret) {
1016
+                QRcode::png("otpauth://totp/".urlencode($login).
1017
+                    "?secret=$secret&issuer=".urlencode("Tiny Tiny RSS"));
1018
+            }
1019
+        }
1020
+    }
1021 1021
 
1022
-	public function otpenable() {
1022
+    public function otpenable() {
1023 1023
 
1024
-		$password = clean($_REQUEST["password"]);
1025
-		$otp = clean($_REQUEST["otp"]);
1024
+        $password = clean($_REQUEST["password"]);
1025
+        $otp = clean($_REQUEST["otp"]);
1026 1026
 
1027
-		$authenticator = PluginHost::getInstance()->get_plugin($_SESSION["auth_module"]);
1027
+        $authenticator = PluginHost::getInstance()->get_plugin($_SESSION["auth_module"]);
1028 1028
 
1029
-		if ($authenticator->check_password($_SESSION["uid"], $password)) {
1029
+        if ($authenticator->check_password($_SESSION["uid"], $password)) {
1030 1030
 
1031
-			$secret = $this->otpsecret();
1031
+            $secret = $this->otpsecret();
1032 1032
 
1033
-			if ($secret) {
1034
-				$topt = new \OTPHP\TOTP($secret);
1035
-				$otp_check = $topt->now();
1033
+            if ($secret) {
1034
+                $topt = new \OTPHP\TOTP($secret);
1035
+                $otp_check = $topt->now();
1036 1036
 
1037
-				if ($otp == $otp_check) {
1038
-					$sth = $this->pdo->prepare("UPDATE ttrss_users SET otp_enabled = true WHERE id = ?");
1037
+                if ($otp == $otp_check) {
1038
+                    $sth = $this->pdo->prepare("UPDATE ttrss_users SET otp_enabled = true WHERE id = ?");
1039 1039
 
1040
-					$sth->execute([$_SESSION['uid']]);
1040
+                    $sth->execute([$_SESSION['uid']]);
1041 1041
 
1042
-					print "OK";
1043
-				} else {
1044
-					print "ERROR:".__("Incorrect one time password");
1045
-				}
1046
-			}
1042
+                    print "OK";
1043
+                } else {
1044
+                    print "ERROR:".__("Incorrect one time password");
1045
+                }
1046
+            }
1047 1047
 
1048
-		} else {
1049
-			print "ERROR:".__("Incorrect password");
1050
-		}
1048
+        } else {
1049
+            print "ERROR:".__("Incorrect password");
1050
+        }
1051 1051
 
1052
-	}
1052
+    }
1053 1053
 
1054
-	public static function isdefaultpassword() {
1055
-		$authenticator = PluginHost::getInstance()->get_plugin($_SESSION["auth_module"]);
1054
+    public static function isdefaultpassword() {
1055
+        $authenticator = PluginHost::getInstance()->get_plugin($_SESSION["auth_module"]);
1056 1056
 
1057
-		if ($authenticator &&
1057
+        if ($authenticator &&
1058 1058
                 method_exists($authenticator, "check_password") &&
1059 1059
                 $authenticator->check_password($_SESSION["uid"], "password")) {
1060 1060
 
1061
-			return true;
1062
-		}
1061
+            return true;
1062
+        }
1063 1063
 
1064
-		return false;
1065
-	}
1064
+        return false;
1065
+    }
1066 1066
 
1067
-	public function otpdisable() {
1068
-		$password = clean($_REQUEST["password"]);
1067
+    public function otpdisable() {
1068
+        $password = clean($_REQUEST["password"]);
1069 1069
 
1070
-		$authenticator = PluginHost::getInstance()->get_plugin($_SESSION["auth_module"]);
1070
+        $authenticator = PluginHost::getInstance()->get_plugin($_SESSION["auth_module"]);
1071 1071
 
1072
-		if ($authenticator->check_password($_SESSION["uid"], $password)) {
1072
+        if ($authenticator->check_password($_SESSION["uid"], $password)) {
1073 1073
 
1074
-			$sth = $this->pdo->prepare("SELECT email, login FROM ttrss_users WHERE id = ?");
1075
-			$sth->execute([$_SESSION['uid']]);
1074
+            $sth = $this->pdo->prepare("SELECT email, login FROM ttrss_users WHERE id = ?");
1075
+            $sth->execute([$_SESSION['uid']]);
1076 1076
 
1077
-			if ($row = $sth->fetch()) {
1078
-				$mailer = new Mailer();
1077
+            if ($row = $sth->fetch()) {
1078
+                $mailer = new Mailer();
1079 1079
 
1080
-				require_once "lib/MiniTemplator.class.php";
1080
+                require_once "lib/MiniTemplator.class.php";
1081 1081
 
1082
-				$tpl = new MiniTemplator;
1082
+                $tpl = new MiniTemplator;
1083 1083
 
1084
-				$tpl->readTemplateFromFile("templates/otp_disabled_template.txt");
1084
+                $tpl->readTemplateFromFile("templates/otp_disabled_template.txt");
1085 1085
 
1086
-				$tpl->setVariable('LOGIN', $row["login"]);
1087
-				$tpl->setVariable('TTRSS_HOST', SELF_URL_PATH);
1086
+                $tpl->setVariable('LOGIN', $row["login"]);
1087
+                $tpl->setVariable('TTRSS_HOST', SELF_URL_PATH);
1088 1088
 
1089
-				$tpl->addBlock('message');
1089
+                $tpl->addBlock('message');
1090 1090
 
1091
-				$tpl->generateOutputToString($message);
1091
+                $tpl->generateOutputToString($message);
1092 1092
 
1093
-				$mailer->mail(["to_name" => $row["login"],
1094
-					"to_address" => $row["email"],
1095
-					"subject" => "[tt-rss] OTP change notification",
1096
-					"message" => $message]);
1097
-			}
1093
+                $mailer->mail(["to_name" => $row["login"],
1094
+                    "to_address" => $row["email"],
1095
+                    "subject" => "[tt-rss] OTP change notification",
1096
+                    "message" => $message]);
1097
+            }
1098 1098
 
1099
-			$sth = $this->pdo->prepare("UPDATE ttrss_users SET otp_enabled = false WHERE
1099
+            $sth = $this->pdo->prepare("UPDATE ttrss_users SET otp_enabled = false WHERE
1100 1100
 				id = ?");
1101
-			$sth->execute([$_SESSION['uid']]);
1101
+            $sth->execute([$_SESSION['uid']]);
1102 1102
 
1103
-			print "OK";
1104
-		} else {
1105
-			print "ERROR: ".__("Incorrect password");
1106
-		}
1103
+            print "OK";
1104
+        } else {
1105
+            print "ERROR: ".__("Incorrect password");
1106
+        }
1107 1107
 
1108
-	}
1108
+    }
1109 1109
 
1110
-	public function setplugins() {
1111
-		if (is_array(clean($_REQUEST["plugins"])))
1112
-			$plugins = join(",", clean($_REQUEST["plugins"]));
1113
-		else
1114
-			$plugins = "";
1110
+    public function setplugins() {
1111
+        if (is_array(clean($_REQUEST["plugins"])))
1112
+            $plugins = join(",", clean($_REQUEST["plugins"]));
1113
+        else
1114
+            $plugins = "";
1115 1115
 
1116
-		set_pref("_ENABLED_PLUGINS", $plugins);
1117
-	}
1116
+        set_pref("_ENABLED_PLUGINS", $plugins);
1117
+    }
1118 1118
 
1119
-	public function clearplugindata() {
1120
-		$name = clean($_REQUEST["name"]);
1119
+    public function clearplugindata() {
1120
+        $name = clean($_REQUEST["name"]);
1121 1121
 
1122
-		PluginHost::getInstance()->clear_data(PluginHost::getInstance()->get_plugin($name));
1123
-	}
1122
+        PluginHost::getInstance()->clear_data(PluginHost::getInstance()->get_plugin($name));
1123
+    }
1124 1124
 
1125
-	public function customizeCSS() {
1126
-		$value = get_pref("USER_STYLESHEET");
1127
-		$value = str_replace("<br/>", "\n", $value);
1125
+    public function customizeCSS() {
1126
+        $value = get_pref("USER_STYLESHEET");
1127
+        $value = str_replace("<br/>", "\n", $value);
1128 1128
 
1129
-		print_notice(__("You can override colors, fonts and layout of your currently selected theme with custom CSS declarations here."));
1129
+        print_notice(__("You can override colors, fonts and layout of your currently selected theme with custom CSS declarations here."));
1130 1130
 
1131
-		print_hidden("op", "rpc");
1132
-		print_hidden("method", "setpref");
1133
-		print_hidden("key", "USER_STYLESHEET");
1131
+        print_hidden("op", "rpc");
1132
+        print_hidden("method", "setpref");
1133
+        print_hidden("key", "USER_STYLESHEET");
1134 1134
 
1135
-		print "<div id='css_edit_apply_msg' style='display : none'>";
1136
-		print_warning(__("User CSS has been applied, you might need to reload the page to see all changes."));
1137
-		print "</div>";
1135
+        print "<div id='css_edit_apply_msg' style='display : none'>";
1136
+        print_warning(__("User CSS has been applied, you might need to reload the page to see all changes."));
1137
+        print "</div>";
1138 1138
 
1139
-		print "<textarea class='panel user-css-editor' dojoType='dijit.form.SimpleTextarea'
1139
+        print "<textarea class='panel user-css-editor' dojoType='dijit.form.SimpleTextarea'
1140 1140
 			style='font-size : 12px;' name='value'>$value</textarea>";
1141 1141
 
1142
-		print "<footer>";
1143
-		print "<button dojoType='dijit.form.Button' class='alt-success'
1142
+        print "<footer>";
1143
+        print "<button dojoType='dijit.form.Button' class='alt-success'
1144 1144
 			onclick=\"dijit.byId('cssEditDlg').apply()\">".__('Apply')."</button> ";
1145
-		print "<button dojoType='dijit.form.Button' class='alt-primary'
1145
+        print "<button dojoType='dijit.form.Button' class='alt-primary'
1146 1146
 			onclick=\"dijit.byId('cssEditDlg').execute()\">".__('Save and reload')."</button> ";
1147
-		print "<button dojoType='dijit.form.Button'
1147
+        print "<button dojoType='dijit.form.Button'
1148 1148
 			onclick=\"dijit.byId('cssEditDlg').hide()\">".__('Cancel')."</button>";
1149
-		print "</footer>";
1149
+        print "</footer>";
1150 1150
 
1151
-	}
1151
+    }
1152 1152
 
1153
-	public function editPrefProfiles() {
1154
-		print "<div dojoType='fox.Toolbar'>";
1153
+    public function editPrefProfiles() {
1154
+        print "<div dojoType='fox.Toolbar'>";
1155 1155
 
1156
-		print "<div dojoType='fox.form.DropDownButton'>".
1157
-				"<span>" . __('Select')."</span>";
1158
-		print "<div dojoType='dijit.Menu' style='display: none'>";
1159
-		print "<div onclick=\"Tables.select('pref-profiles-list', true)\"
1156
+        print "<div dojoType='fox.form.DropDownButton'>".
1157
+                "<span>" . __('Select')."</span>";
1158
+        print "<div dojoType='dijit.Menu' style='display: none'>";
1159
+        print "<div onclick=\"Tables.select('pref-profiles-list', true)\"
1160 1160
 			dojoType='dijit.MenuItem'>".__('All')."</div>";
1161
-		print "<div onclick=\"Tables.select('pref-profiles-list', false)\"
1161
+        print "<div onclick=\"Tables.select('pref-profiles-list', false)\"
1162 1162
 			dojoType='dijit.MenuItem'>".__('None')."</div>";
1163
-		print "</div></div>";
1163
+        print "</div></div>";
1164 1164
 
1165
-		print "<div style='float : right'>";
1165
+        print "<div style='float : right'>";
1166 1166
 
1167
-		print "<input name='newprofile' dojoType='dijit.form.ValidationTextBox'
1167
+        print "<input name='newprofile' dojoType='dijit.form.ValidationTextBox'
1168 1168
 				required='1'>
1169 1169
 			<button dojoType='dijit.form.Button'
1170 1170
 			onclick=\"dijit.byId('profileEditDlg').addProfile()\">".
1171
-				__('Create profile')."</button></div>";
1171
+                __('Create profile')."</button></div>";
1172 1172
 
1173
-		print "</div>";
1173
+        print "</div>";
1174 1174
 
1175
-		$sth = $this->pdo->prepare("SELECT title,id FROM ttrss_settings_profiles
1175
+        $sth = $this->pdo->prepare("SELECT title,id FROM ttrss_settings_profiles
1176 1176
 			WHERE owner_uid = ? ORDER BY title");
1177
-		$sth->execute([$_SESSION['uid']]);
1177
+        $sth->execute([$_SESSION['uid']]);
1178 1178
 
1179
-		print "<div class='panel panel-scrollable'>";
1179
+        print "<div class='panel panel-scrollable'>";
1180 1180
 
1181
-		print "<form id='profile_edit_form' onsubmit='return false'>";
1181
+        print "<form id='profile_edit_form' onsubmit='return false'>";
1182 1182
 
1183
-		print "<table width='100%' id='pref-profiles-list'>";
1183
+        print "<table width='100%' id='pref-profiles-list'>";
1184 1184
 
1185
-		print "<tr>"; # data-row-id='0' <-- no point, shouldn't be removed
1185
+        print "<tr>"; # data-row-id='0' <-- no point, shouldn't be removed
1186 1186
 
1187
-		print "<td><input onclick='Tables.onRowChecked(this);' dojoType='dijit.form.CheckBox' type='checkbox'></td>";
1187
+        print "<td><input onclick='Tables.onRowChecked(this);' dojoType='dijit.form.CheckBox' type='checkbox'></td>";
1188 1188
 
1189
-		if (!$_SESSION["profile"]) {
1190
-			$is_active = __("(active)");
1191
-		} else {
1192
-			$is_active = "";
1193
-		}
1189
+        if (!$_SESSION["profile"]) {
1190
+            $is_active = __("(active)");
1191
+        } else {
1192
+            $is_active = "";
1193
+        }
1194 1194
 
1195
-		print "<td width='100%'><span>" . __("Default profile") . " $is_active</span></td>";
1195
+        print "<td width='100%'><span>" . __("Default profile") . " $is_active</span></td>";
1196 1196
 
1197
-		print "</tr>";
1197
+        print "</tr>";
1198 1198
 
1199
-		while ($line = $sth->fetch()) {
1199
+        while ($line = $sth->fetch()) {
1200 1200
 
1201
-			$profile_id = $line["id"];
1201
+            $profile_id = $line["id"];
1202 1202
 
1203
-			print "<tr data-row-id='$profile_id'>";
1203
+            print "<tr data-row-id='$profile_id'>";
1204 1204
 
1205
-			$edit_title = htmlspecialchars($line["title"]);
1205
+            $edit_title = htmlspecialchars($line["title"]);
1206 1206
 
1207
-			print "<td><input onclick='Tables.onRowChecked(this);' dojoType='dijit.form.CheckBox' type='checkbox'></td>";
1207
+            print "<td><input onclick='Tables.onRowChecked(this);' dojoType='dijit.form.CheckBox' type='checkbox'></td>";
1208 1208
 
1209
-			if ($_SESSION["profile"] == $line["id"]) {
1210
-				$is_active = __("(active)");
1211
-			} else {
1212
-				$is_active = "";
1213
-			}
1209
+            if ($_SESSION["profile"] == $line["id"]) {
1210
+                $is_active = __("(active)");
1211
+            } else {
1212
+                $is_active = "";
1213
+            }
1214 1214
 
1215
-			print "<td><span dojoType='dijit.InlineEditBox'
1215
+            print "<td><span dojoType='dijit.InlineEditBox'
1216 1216
 				width='300px' autoSave='false'
1217 1217
 				profile-id='$profile_id'>" . $edit_title .
1218
-				"<script type='dojo/method' event='onChange' args='item'>
1218
+                "<script type='dojo/method' event='onChange' args='item'>
1219 1219
 					var elem = this;
1220 1220
 					dojo.xhrPost({
1221 1221
 						url: 'backend.php',
@@ -1229,118 +1229,118 @@  discard block
 block discarded – undo
1229 1229
 				</script>
1230 1230
 			</span> $is_active</td>";
1231 1231
 
1232
-			print "</tr>";
1233
-		}
1232
+            print "</tr>";
1233
+        }
1234 1234
 
1235
-		print "</table>";
1236
-		print "</form>";
1237
-		print "</div>";
1235
+        print "</table>";
1236
+        print "</form>";
1237
+        print "</div>";
1238 1238
 
1239
-		print "<footer>
1239
+        print "<footer>
1240 1240
 			<button style='float : left' class='alt-danger' dojoType=\"dijit.form.Button\" onclick=\"dijit.byId('profileEditDlg').removeSelected()\">".
1241
-			__('Remove selected profiles')."</button>
1241
+            __('Remove selected profiles')."</button>
1242 1242
 			<button dojoType='dijit.form.Button' class='alt-primary' type='submit' onclick=\"dijit.byId('profileEditDlg').activateProfile()\">".
1243
-			__('Activate profile')."</button>
1243
+            __('Activate profile')."</button>
1244 1244
 			<button dojoType='dijit.form.Button' onclick=\"dijit.byId('profileEditDlg').hide()\">".
1245
-			__('Cancel')."</button>";
1246
-		print "</footer>";
1247
-
1248
-	}
1249
-
1250
-	private function getShortDesc($pref_name) {
1251
-		if (isset($this->pref_help[$pref_name])) {
1252
-			return $this->pref_help[$pref_name][0];
1253
-		}
1254
-		return "";
1255
-	}
1256
-
1257
-	private function getHelpText($pref_name) {
1258
-		if (isset($this->pref_help[$pref_name])) {
1259
-			return $this->pref_help[$pref_name][1];
1260
-		}
1261
-		return "";
1262
-	}
1263
-
1264
-	private function appPasswordList() {
1265
-		print "<div dojoType='fox.Toolbar'>";
1266
-		print "<div dojoType='fox.form.DropDownButton'>" .
1267
-			"<span>" . __('Select') . "</span>";
1268
-		print "<div dojoType='dijit.Menu' style='display: none'>";
1269
-		print "<div onclick=\"Tables.select('app-password-list', true)\"
1245
+            __('Cancel')."</button>";
1246
+        print "</footer>";
1247
+
1248
+    }
1249
+
1250
+    private function getShortDesc($pref_name) {
1251
+        if (isset($this->pref_help[$pref_name])) {
1252
+            return $this->pref_help[$pref_name][0];
1253
+        }
1254
+        return "";
1255
+    }
1256
+
1257
+    private function getHelpText($pref_name) {
1258
+        if (isset($this->pref_help[$pref_name])) {
1259
+            return $this->pref_help[$pref_name][1];
1260
+        }
1261
+        return "";
1262
+    }
1263
+
1264
+    private function appPasswordList() {
1265
+        print "<div dojoType='fox.Toolbar'>";
1266
+        print "<div dojoType='fox.form.DropDownButton'>" .
1267
+            "<span>" . __('Select') . "</span>";
1268
+        print "<div dojoType='dijit.Menu' style='display: none'>";
1269
+        print "<div onclick=\"Tables.select('app-password-list', true)\"
1270 1270
 				dojoType=\"dijit.MenuItem\">" . __('All') . "</div>";
1271
-		print "<div onclick=\"Tables.select('app-password-list', false)\"
1271
+        print "<div onclick=\"Tables.select('app-password-list', false)\"
1272 1272
 				dojoType=\"dijit.MenuItem\">" . __('None') . "</div>";
1273
-		print "</div></div>";
1274
-		print "</div>"; #toolbar
1275
-
1276
-		print "<div class='panel panel-scrollable'>";
1277
-		print "<table width='100%' id='app-password-list'>";
1278
-		print "<tr>";
1279
-		print "<th width='2%'></th>";
1280
-		print "<th align='left'>".__("Description")."</th>";
1281
-		print "<th align='right'>".__("Created")."</th>";
1282
-		print "<th align='right'>".__("Last used")."</th>";
1283
-		print "</tr>";
1284
-
1285
-		$sth = $this->pdo->prepare("SELECT id, title, created, last_used
1273
+        print "</div></div>";
1274
+        print "</div>"; #toolbar
1275
+
1276
+        print "<div class='panel panel-scrollable'>";
1277
+        print "<table width='100%' id='app-password-list'>";
1278
+        print "<tr>";
1279
+        print "<th width='2%'></th>";
1280
+        print "<th align='left'>".__("Description")."</th>";
1281
+        print "<th align='right'>".__("Created")."</th>";
1282
+        print "<th align='right'>".__("Last used")."</th>";
1283
+        print "</tr>";
1284
+
1285
+        $sth = $this->pdo->prepare("SELECT id, title, created, last_used
1286 1286
 			FROM ttrss_app_passwords WHERE owner_uid = ?");
1287
-		$sth->execute([$_SESSION['uid']]);
1287
+        $sth->execute([$_SESSION['uid']]);
1288 1288
 
1289
-		while ($row = $sth->fetch()) {
1289
+        while ($row = $sth->fetch()) {
1290 1290
 
1291
-			$row_id = $row["id"];
1291
+            $row_id = $row["id"];
1292 1292
 
1293
-			print "<tr data-row-id='$row_id'>";
1293
+            print "<tr data-row-id='$row_id'>";
1294 1294
 
1295
-			print "<td align='center'>
1295
+            print "<td align='center'>
1296 1296
 						<input onclick='Tables.onRowChecked(this)' dojoType='dijit.form.CheckBox' type='checkbox'></td>";
1297
-			print "<td>" . htmlspecialchars($row["title"]) . "</td>";
1297
+            print "<td>" . htmlspecialchars($row["title"]) . "</td>";
1298 1298
 
1299
-			print "<td align='right' class='text-muted'>";
1300
-			print make_local_datetime($row['created'], false);
1301
-			print "</td>";
1299
+            print "<td align='right' class='text-muted'>";
1300
+            print make_local_datetime($row['created'], false);
1301
+            print "</td>";
1302 1302
 
1303
-			print "<td align='right' class='text-muted'>";
1304
-			print make_local_datetime($row['last_used'], false);
1305
-			print "</td>";
1303
+            print "<td align='right' class='text-muted'>";
1304
+            print make_local_datetime($row['last_used'], false);
1305
+            print "</td>";
1306 1306
 
1307
-			print "</tr>";
1308
-		}
1307
+            print "</tr>";
1308
+        }
1309 1309
 
1310
-		print "</table>";
1311
-		print "</div>";
1312
-	}
1310
+        print "</table>";
1311
+        print "</div>";
1312
+    }
1313 1313
 
1314
-	private function encryptAppPassword($password) {
1315
-		$salt = substr(bin2hex(get_random_bytes(24)), 0, 24);
1314
+    private function encryptAppPassword($password) {
1315
+        $salt = substr(bin2hex(get_random_bytes(24)), 0, 24);
1316 1316
 
1317
-		return "SSHA-512:".hash('sha512', $salt . $password). ":$salt";
1318
-	}
1317
+        return "SSHA-512:".hash('sha512', $salt . $password). ":$salt";
1318
+    }
1319 1319
 
1320
-	public function deleteAppPassword() {
1321
-		$ids = explode(",", clean($_REQUEST['ids']));
1322
-		$ids_qmarks = arr_qmarks($ids);
1320
+    public function deleteAppPassword() {
1321
+        $ids = explode(",", clean($_REQUEST['ids']));
1322
+        $ids_qmarks = arr_qmarks($ids);
1323 1323
 
1324
-		$sth = $this->pdo->prepare("DELETE FROM ttrss_app_passwords WHERE id IN ($ids_qmarks) AND owner_uid = ?");
1325
-		$sth->execute(array_merge($ids, [$_SESSION['uid']]));
1324
+        $sth = $this->pdo->prepare("DELETE FROM ttrss_app_passwords WHERE id IN ($ids_qmarks) AND owner_uid = ?");
1325
+        $sth->execute(array_merge($ids, [$_SESSION['uid']]));
1326 1326
 
1327
-		$this->appPasswordList();
1328
-	}
1327
+        $this->appPasswordList();
1328
+    }
1329 1329
 
1330
-	public function generateAppPassword() {
1331
-		$title = clean($_REQUEST['title']);
1332
-		$new_password = make_password(16);
1333
-		$new_password_hash = $this->encryptAppPassword($new_password);
1330
+    public function generateAppPassword() {
1331
+        $title = clean($_REQUEST['title']);
1332
+        $new_password = make_password(16);
1333
+        $new_password_hash = $this->encryptAppPassword($new_password);
1334 1334
 
1335
-		print_warning(T_sprintf("Generated password <strong>%s</strong> for %s. Please remember it for future reference.", $new_password, $title));
1335
+        print_warning(T_sprintf("Generated password <strong>%s</strong> for %s. Please remember it for future reference.", $new_password, $title));
1336 1336
 
1337
-		$sth = $this->pdo->prepare("INSERT INTO ttrss_app_passwords
1337
+        $sth = $this->pdo->prepare("INSERT INTO ttrss_app_passwords
1338 1338
     			(title, pwd_hash, service, created, owner_uid)
1339 1339
     		 VALUES
1340 1340
     		    (?, ?, ?, NOW(), ?)");
1341 1341
 
1342
-		$sth->execute([$title, $new_password_hash, Auth_Base::AUTH_SERVICE_API, $_SESSION['uid']]);
1342
+        $sth->execute([$title, $new_password_hash, Auth_Base::AUTH_SERVICE_API, $_SESSION['uid']]);
1343 1343
 
1344
-		$this->appPasswordList();
1345
-	}
1344
+        $this->appPasswordList();
1345
+    }
1346 1346
 }
Please login to merge, or discard this patch.