Passed
Push — master ( a3c0d0...678db7 )
by Cody
06:27 queued 03:12
created
classes/pluginhost.php 1 patch
Indentation   +497 added lines, -497 removed lines patch added patch discarded remove patch
@@ -1,526 +1,526 @@
 block discarded – undo
1 1
 <?php
2 2
 class PluginHost {
3
-	private $pdo;
4
-	private $hooks = array();
5
-	private $plugins = array();
6
-	private $handlers = array();
7
-	private $commands = array();
8
-	private $storage = array();
9
-	private $feeds = array();
10
-	private $api_methods = array();
11
-	private $plugin_actions = array();
12
-	private $owner_uid;
13
-	private $last_registered;
14
-	private static $instance;
15
-
16
-	const API_VERSION = 2;
17
-
18
-	// Hooks marked with *1 are run in global context and available
19
-	// to plugins loaded in config.php only
20
-
21
-	const HOOK_ARTICLE_BUTTON = 1;
22
-	const HOOK_ARTICLE_FILTER = 2;
23
-	const HOOK_PREFS_TAB = 3;
24
-	const HOOK_PREFS_TAB_SECTION = 4;
25
-	const HOOK_PREFS_TABS = 5;
26
-	const HOOK_FEED_PARSED = 6;
27
-	const HOOK_UPDATE_TASK = 7; // *1
28
-	const HOOK_AUTH_USER = 8;
29
-	const HOOK_HOTKEY_MAP = 9;
30
-	const HOOK_RENDER_ARTICLE = 10;
31
-	const HOOK_RENDER_ARTICLE_CDM = 11;
32
-	const HOOK_FEED_FETCHED = 12;
33
-	const HOOK_SANITIZE = 13;
34
-	const HOOK_RENDER_ARTICLE_API = 14;
35
-	const HOOK_TOOLBAR_BUTTON = 15;
36
-	const HOOK_ACTION_ITEM = 16;
37
-	const HOOK_HEADLINE_TOOLBAR_BUTTON = 17;
38
-	const HOOK_HOTKEY_INFO = 18;
39
-	const HOOK_ARTICLE_LEFT_BUTTON = 19;
40
-	const HOOK_PREFS_EDIT_FEED = 20;
41
-	const HOOK_PREFS_SAVE_FEED = 21;
42
-	const HOOK_FETCH_FEED = 22;
43
-	const HOOK_QUERY_HEADLINES = 23;
44
-	const HOOK_HOUSE_KEEPING = 24; // *1
45
-	const HOOK_SEARCH = 25;
46
-	const HOOK_FORMAT_ENCLOSURES = 26;
47
-	const HOOK_SUBSCRIBE_FEED = 27;
48
-	const HOOK_HEADLINES_BEFORE = 28;
49
-	const HOOK_RENDER_ENCLOSURE = 29;
50
-	const HOOK_ARTICLE_FILTER_ACTION = 30;
51
-	const HOOK_ARTICLE_EXPORT_FEED = 31;
52
-	const HOOK_MAIN_TOOLBAR_BUTTON = 32;
53
-	const HOOK_ENCLOSURE_ENTRY = 33;
54
-	const HOOK_FORMAT_ARTICLE = 34;
55
-	const HOOK_FORMAT_ARTICLE_CDM = 35; /* RIP */
56
-	const HOOK_FEED_BASIC_INFO = 36;
57
-	const HOOK_SEND_LOCAL_FILE = 37;
58
-	const HOOK_UNSUBSCRIBE_FEED = 38;
59
-	const HOOK_SEND_MAIL = 39;
60
-	const HOOK_FILTER_TRIGGERED = 40;
61
-	const HOOK_GET_FULL_TEXT = 41;
62
-	const HOOK_ARTICLE_IMAGE = 42;
63
-	const HOOK_FEED_TREE = 43;
64
-	const HOOK_IFRAME_WHITELISTED = 44;
65
-
66
-	const KIND_ALL = 1;
67
-	const KIND_SYSTEM = 2;
68
-	const KIND_USER = 3;
69
-
70
-	public static function object_to_domain($plugin) {
71
-		return strtolower(get_class($plugin));
72
-	}
73
-
74
-	public function __construct() {
75
-		$this->pdo = Db::pdo();
76
-
77
-		$this->storage = array();
78
-	}
79
-
80
-	private function __clone() {
81
-		//
82
-	}
83
-
84
-	public static function getInstance() {
85
-		if (self::$instance == null)
86
-			self::$instance = new self();
87
-
88
-		return self::$instance;
89
-	}
90
-
91
-	private function register_plugin($name, $plugin) {
92
-		//array_push($this->plugins, $plugin);
93
-		$this->plugins[$name] = $plugin;
94
-	}
95
-
96
-	// needed for compatibility with API 1
97
-	public function get_link() {
98
-		return false;
99
-	}
100
-
101
-	public function get_dbh() {
102
-		return Db::get();
103
-	}
104
-
105
-	public function get_pdo() {
106
-		return $this->pdo;
107
-	}
108
-
109
-	public function get_plugin_names() {
110
-		$names = array();
111
-
112
-		foreach ($this->plugins as $p) {
113
-			array_push($names, get_class($p));
114
-		}
115
-
116
-		return $names;
117
-	}
118
-
119
-	public function get_plugins() {
120
-		return $this->plugins;
121
-	}
122
-
123
-	public function get_plugin($name) {
124
-		return $this->plugins[strtolower($name)];
125
-	}
126
-
127
-	public function run_hooks($type, $method, $args) {
128
-		foreach ($this->get_hooks($type) as $hook) {
129
-			$hook->$method($args);
130
-		}
131
-	}
132
-
133
-	public function add_hook($type, $sender, $priority = 50) {
134
-		$priority = (int) $priority;
135
-
136
-		if (!is_array($this->hooks[$type])) {
137
-			$this->hooks[$type] = [];
138
-		}
139
-
140
-		if (!is_array($this->hooks[$type][$priority])) {
141
-			$this->hooks[$type][$priority] = [];
142
-		}
143
-
144
-		array_push($this->hooks[$type][$priority], $sender);
145
-		ksort($this->hooks[$type]);
146
-	}
147
-
148
-	public function del_hook($type, $sender) {
149
-		if (is_array($this->hooks[$type])) {
150
-			foreach (array_keys($this->hooks[$type]) as $prio) {
151
-				$key = array_search($sender, $this->hooks[$type][$prio]);
152
-
153
-				if ($key !== false) {
154
-					unset($this->hooks[$type][$prio][$key]);
155
-				}
156
-			}
157
-		}
158
-	}
159
-
160
-	public function get_hooks($type) {
161
-		if (isset($this->hooks[$type])) {
162
-			$tmp = [];
163
-
164
-			foreach (array_keys($this->hooks[$type]) as $prio) {
165
-				$tmp = array_merge($tmp, $this->hooks[$type][$prio]);
166
-			}
167
-
168
-			return $tmp;
169
-		} else {
170
-			return [];
171
-		}
172
-	}
173
-	public function load_all($kind, $owner_uid = false, $skip_init = false) {
174
-
175
-		$plugins = array_merge(glob("plugins/*"), glob("plugins.local/*"));
176
-		$plugins = array_filter($plugins, "is_dir");
177
-		$plugins = array_map("basename", $plugins);
178
-
179
-		asort($plugins);
180
-
181
-		$this->load(join(",", $plugins), $kind, $owner_uid, $skip_init);
182
-	}
183
-
184
-	public function load($classlist, $kind, $owner_uid = false, $skip_init = false) {
185
-		$plugins = explode(",", $classlist);
186
-
187
-		$this->owner_uid = (int) $owner_uid;
188
-
189
-		foreach ($plugins as $class) {
190
-			$class = trim($class);
191
-			$class_file = strtolower(clean_filename($class));
192
-
193
-			if (!is_dir(__DIR__."/../plugins/$class_file") &&
194
-					!is_dir(__DIR__."/../plugins.local/$class_file")) continue;
195
-
196
-			// try system plugin directory first
197
-			$file = __DIR__ . "/../plugins/$class_file/init.php";
198
-			$vendor_dir = __DIR__ . "/../plugins/$class_file/vendor";
199
-
200
-			if (!file_exists($file)) {
201
-				$file = __DIR__ . "/../plugins.local/$class_file/init.php";
202
-				$vendor_dir = __DIR__ . "/../plugins.local/$class_file/vendor";
203
-			}
204
-
205
-			if (!isset($this->plugins[$class])) {
206
-				if (file_exists($file)) require_once $file;
207
-
208
-				if (class_exists($class) && is_subclass_of($class, "Plugin")) {
209
-
210
-					// register plugin autoloader if necessary, for namespaced classes ONLY
211
-					// layout corresponds to tt-rss main /vendor/author/Package/Class.php
212
-
213
-					if (file_exists($vendor_dir)) {
214
-						spl_autoload_register(function($class) use ($vendor_dir) {
215
-
216
-							if (strpos($class, '\\') !== false) {
217
-								list ($namespace, $class_name) = explode('\\', $class, 2);
218
-
219
-								if ($namespace && $class_name) {
220
-									$class_file = "$vendor_dir/$namespace/" . str_replace('\\', '/', $class_name) . ".php";
221
-
222
-									if (file_exists($class_file))
223
-										require_once $class_file;
224
-								}
225
-							}
226
-						});
227
-					}
228
-
229
-					$plugin = new $class($this);
230
-
231
-					$plugin_api = $plugin->api_version();
232
-
233
-					if ($plugin_api < PluginHost::API_VERSION) {
234
-						user_error("plugin $class is not compatible with current API version (need: " . PluginHost::API_VERSION . ", got: $plugin_api)", E_USER_WARNING);
235
-						continue;
236
-					}
237
-
238
-					if (file_exists(dirname($file) . "/locale")) {
239
-						_bindtextdomain($class, dirname($file) . "/locale");
240
-						_bind_textdomain_codeset($class, "UTF-8");
241
-					}
242
-
243
-					$this->last_registered = $class;
244
-
245
-					switch ($kind) {
246
-					case $this::KIND_SYSTEM:
247
-						if ($this->is_system($plugin)) {
248
-							if (!$skip_init) $plugin->init($this);
249
-							$this->register_plugin($class, $plugin);
250
-						}
251
-						break;
252
-					case $this::KIND_USER:
253
-						if (!$this->is_system($plugin)) {
254
-							if (!$skip_init) $plugin->init($this);
255
-							$this->register_plugin($class, $plugin);
256
-						}
257
-						break;
258
-					case $this::KIND_ALL:
259
-						if (!$skip_init) $plugin->init($this);
260
-						$this->register_plugin($class, $plugin);
261
-						break;
262
-					}
263
-				}
264
-			}
265
-		}
266
-	}
267
-
268
-	public function is_system($plugin) {
269
-		$about = $plugin->about();
270
-
271
-		return @$about[3];
272
-	}
273
-
274
-	// only system plugins are allowed to modify routing
275
-	public function add_handler($handler, $method, $sender) {
276
-		$handler = str_replace("-", "_", strtolower($handler));
277
-		$method = strtolower($method);
278
-
279
-		if ($this->is_system($sender)) {
280
-			if (!is_array($this->handlers[$handler])) {
281
-				$this->handlers[$handler] = array();
282
-			}
283
-
284
-			$this->handlers[$handler][$method] = $sender;
285
-		}
286
-	}
287
-
288
-	public function del_handler($handler, $method, $sender) {
289
-		$handler = str_replace("-", "_", strtolower($handler));
290
-		$method = strtolower($method);
291
-
292
-		if ($this->is_system($sender)) {
293
-			unset($this->handlers[$handler][$method]);
294
-		}
295
-	}
296
-
297
-	public function lookup_handler($handler, $method) {
298
-		$handler = str_replace("-", "_", strtolower($handler));
299
-		$method = strtolower($method);
300
-
301
-		if (is_array($this->handlers[$handler])) {
302
-			if (isset($this->handlers[$handler]["*"])) {
303
-				return $this->handlers[$handler]["*"];
304
-			} else {
305
-				return $this->handlers[$handler][$method];
306
-			}
307
-		}
308
-
309
-		return false;
310
-	}
311
-
312
-	public function add_command($command, $description, $sender, $suffix = "", $arghelp = "") {
313
-		$command = str_replace("-", "_", strtolower($command));
314
-
315
-		$this->commands[$command] = array("description" => $description,
316
-			"suffix" => $suffix,
317
-			"arghelp" => $arghelp,
318
-			"class" => $sender);
319
-	}
320
-
321
-	public function del_command($command) {
322
-		$command = "-" . strtolower($command);
323
-
324
-		unset($this->commands[$command]);
325
-	}
326
-
327
-	public function lookup_command($command) {
328
-		$command = "-" . strtolower($command);
329
-
330
-		if (is_array($this->commands[$command])) {
331
-			return $this->commands[$command]["class"];
332
-		} else {
333
-			return false;
334
-		}
335
-	}
336
-
337
-	public function get_commands() {
338
-		return $this->commands;
339
-	}
340
-
341
-	public function run_commands($args) {
342
-		foreach ($this->get_commands() as $command => $data) {
343
-			if (isset($args[$command])) {
344
-				$command = str_replace("-", "", $command);
345
-				$data["class"]->$command($args);
346
-			}
347
-		}
348
-	}
349
-
350
-	public function load_data() {
351
-		if ($this->owner_uid)  {
352
-			$sth = $this->pdo->prepare("SELECT name, content FROM ttrss_plugin_storage
3
+    private $pdo;
4
+    private $hooks = array();
5
+    private $plugins = array();
6
+    private $handlers = array();
7
+    private $commands = array();
8
+    private $storage = array();
9
+    private $feeds = array();
10
+    private $api_methods = array();
11
+    private $plugin_actions = array();
12
+    private $owner_uid;
13
+    private $last_registered;
14
+    private static $instance;
15
+
16
+    const API_VERSION = 2;
17
+
18
+    // Hooks marked with *1 are run in global context and available
19
+    // to plugins loaded in config.php only
20
+
21
+    const HOOK_ARTICLE_BUTTON = 1;
22
+    const HOOK_ARTICLE_FILTER = 2;
23
+    const HOOK_PREFS_TAB = 3;
24
+    const HOOK_PREFS_TAB_SECTION = 4;
25
+    const HOOK_PREFS_TABS = 5;
26
+    const HOOK_FEED_PARSED = 6;
27
+    const HOOK_UPDATE_TASK = 7; // *1
28
+    const HOOK_AUTH_USER = 8;
29
+    const HOOK_HOTKEY_MAP = 9;
30
+    const HOOK_RENDER_ARTICLE = 10;
31
+    const HOOK_RENDER_ARTICLE_CDM = 11;
32
+    const HOOK_FEED_FETCHED = 12;
33
+    const HOOK_SANITIZE = 13;
34
+    const HOOK_RENDER_ARTICLE_API = 14;
35
+    const HOOK_TOOLBAR_BUTTON = 15;
36
+    const HOOK_ACTION_ITEM = 16;
37
+    const HOOK_HEADLINE_TOOLBAR_BUTTON = 17;
38
+    const HOOK_HOTKEY_INFO = 18;
39
+    const HOOK_ARTICLE_LEFT_BUTTON = 19;
40
+    const HOOK_PREFS_EDIT_FEED = 20;
41
+    const HOOK_PREFS_SAVE_FEED = 21;
42
+    const HOOK_FETCH_FEED = 22;
43
+    const HOOK_QUERY_HEADLINES = 23;
44
+    const HOOK_HOUSE_KEEPING = 24; // *1
45
+    const HOOK_SEARCH = 25;
46
+    const HOOK_FORMAT_ENCLOSURES = 26;
47
+    const HOOK_SUBSCRIBE_FEED = 27;
48
+    const HOOK_HEADLINES_BEFORE = 28;
49
+    const HOOK_RENDER_ENCLOSURE = 29;
50
+    const HOOK_ARTICLE_FILTER_ACTION = 30;
51
+    const HOOK_ARTICLE_EXPORT_FEED = 31;
52
+    const HOOK_MAIN_TOOLBAR_BUTTON = 32;
53
+    const HOOK_ENCLOSURE_ENTRY = 33;
54
+    const HOOK_FORMAT_ARTICLE = 34;
55
+    const HOOK_FORMAT_ARTICLE_CDM = 35; /* RIP */
56
+    const HOOK_FEED_BASIC_INFO = 36;
57
+    const HOOK_SEND_LOCAL_FILE = 37;
58
+    const HOOK_UNSUBSCRIBE_FEED = 38;
59
+    const HOOK_SEND_MAIL = 39;
60
+    const HOOK_FILTER_TRIGGERED = 40;
61
+    const HOOK_GET_FULL_TEXT = 41;
62
+    const HOOK_ARTICLE_IMAGE = 42;
63
+    const HOOK_FEED_TREE = 43;
64
+    const HOOK_IFRAME_WHITELISTED = 44;
65
+
66
+    const KIND_ALL = 1;
67
+    const KIND_SYSTEM = 2;
68
+    const KIND_USER = 3;
69
+
70
+    public static function object_to_domain($plugin) {
71
+        return strtolower(get_class($plugin));
72
+    }
73
+
74
+    public function __construct() {
75
+        $this->pdo = Db::pdo();
76
+
77
+        $this->storage = array();
78
+    }
79
+
80
+    private function __clone() {
81
+        //
82
+    }
83
+
84
+    public static function getInstance() {
85
+        if (self::$instance == null)
86
+            self::$instance = new self();
87
+
88
+        return self::$instance;
89
+    }
90
+
91
+    private function register_plugin($name, $plugin) {
92
+        //array_push($this->plugins, $plugin);
93
+        $this->plugins[$name] = $plugin;
94
+    }
95
+
96
+    // needed for compatibility with API 1
97
+    public function get_link() {
98
+        return false;
99
+    }
100
+
101
+    public function get_dbh() {
102
+        return Db::get();
103
+    }
104
+
105
+    public function get_pdo() {
106
+        return $this->pdo;
107
+    }
108
+
109
+    public function get_plugin_names() {
110
+        $names = array();
111
+
112
+        foreach ($this->plugins as $p) {
113
+            array_push($names, get_class($p));
114
+        }
115
+
116
+        return $names;
117
+    }
118
+
119
+    public function get_plugins() {
120
+        return $this->plugins;
121
+    }
122
+
123
+    public function get_plugin($name) {
124
+        return $this->plugins[strtolower($name)];
125
+    }
126
+
127
+    public function run_hooks($type, $method, $args) {
128
+        foreach ($this->get_hooks($type) as $hook) {
129
+            $hook->$method($args);
130
+        }
131
+    }
132
+
133
+    public function add_hook($type, $sender, $priority = 50) {
134
+        $priority = (int) $priority;
135
+
136
+        if (!is_array($this->hooks[$type])) {
137
+            $this->hooks[$type] = [];
138
+        }
139
+
140
+        if (!is_array($this->hooks[$type][$priority])) {
141
+            $this->hooks[$type][$priority] = [];
142
+        }
143
+
144
+        array_push($this->hooks[$type][$priority], $sender);
145
+        ksort($this->hooks[$type]);
146
+    }
147
+
148
+    public function del_hook($type, $sender) {
149
+        if (is_array($this->hooks[$type])) {
150
+            foreach (array_keys($this->hooks[$type]) as $prio) {
151
+                $key = array_search($sender, $this->hooks[$type][$prio]);
152
+
153
+                if ($key !== false) {
154
+                    unset($this->hooks[$type][$prio][$key]);
155
+                }
156
+            }
157
+        }
158
+    }
159
+
160
+    public function get_hooks($type) {
161
+        if (isset($this->hooks[$type])) {
162
+            $tmp = [];
163
+
164
+            foreach (array_keys($this->hooks[$type]) as $prio) {
165
+                $tmp = array_merge($tmp, $this->hooks[$type][$prio]);
166
+            }
167
+
168
+            return $tmp;
169
+        } else {
170
+            return [];
171
+        }
172
+    }
173
+    public function load_all($kind, $owner_uid = false, $skip_init = false) {
174
+
175
+        $plugins = array_merge(glob("plugins/*"), glob("plugins.local/*"));
176
+        $plugins = array_filter($plugins, "is_dir");
177
+        $plugins = array_map("basename", $plugins);
178
+
179
+        asort($plugins);
180
+
181
+        $this->load(join(",", $plugins), $kind, $owner_uid, $skip_init);
182
+    }
183
+
184
+    public function load($classlist, $kind, $owner_uid = false, $skip_init = false) {
185
+        $plugins = explode(",", $classlist);
186
+
187
+        $this->owner_uid = (int) $owner_uid;
188
+
189
+        foreach ($plugins as $class) {
190
+            $class = trim($class);
191
+            $class_file = strtolower(clean_filename($class));
192
+
193
+            if (!is_dir(__DIR__."/../plugins/$class_file") &&
194
+                    !is_dir(__DIR__."/../plugins.local/$class_file")) continue;
195
+
196
+            // try system plugin directory first
197
+            $file = __DIR__ . "/../plugins/$class_file/init.php";
198
+            $vendor_dir = __DIR__ . "/../plugins/$class_file/vendor";
199
+
200
+            if (!file_exists($file)) {
201
+                $file = __DIR__ . "/../plugins.local/$class_file/init.php";
202
+                $vendor_dir = __DIR__ . "/../plugins.local/$class_file/vendor";
203
+            }
204
+
205
+            if (!isset($this->plugins[$class])) {
206
+                if (file_exists($file)) require_once $file;
207
+
208
+                if (class_exists($class) && is_subclass_of($class, "Plugin")) {
209
+
210
+                    // register plugin autoloader if necessary, for namespaced classes ONLY
211
+                    // layout corresponds to tt-rss main /vendor/author/Package/Class.php
212
+
213
+                    if (file_exists($vendor_dir)) {
214
+                        spl_autoload_register(function($class) use ($vendor_dir) {
215
+
216
+                            if (strpos($class, '\\') !== false) {
217
+                                list ($namespace, $class_name) = explode('\\', $class, 2);
218
+
219
+                                if ($namespace && $class_name) {
220
+                                    $class_file = "$vendor_dir/$namespace/" . str_replace('\\', '/', $class_name) . ".php";
221
+
222
+                                    if (file_exists($class_file))
223
+                                        require_once $class_file;
224
+                                }
225
+                            }
226
+                        });
227
+                    }
228
+
229
+                    $plugin = new $class($this);
230
+
231
+                    $plugin_api = $plugin->api_version();
232
+
233
+                    if ($plugin_api < PluginHost::API_VERSION) {
234
+                        user_error("plugin $class is not compatible with current API version (need: " . PluginHost::API_VERSION . ", got: $plugin_api)", E_USER_WARNING);
235
+                        continue;
236
+                    }
237
+
238
+                    if (file_exists(dirname($file) . "/locale")) {
239
+                        _bindtextdomain($class, dirname($file) . "/locale");
240
+                        _bind_textdomain_codeset($class, "UTF-8");
241
+                    }
242
+
243
+                    $this->last_registered = $class;
244
+
245
+                    switch ($kind) {
246
+                    case $this::KIND_SYSTEM:
247
+                        if ($this->is_system($plugin)) {
248
+                            if (!$skip_init) $plugin->init($this);
249
+                            $this->register_plugin($class, $plugin);
250
+                        }
251
+                        break;
252
+                    case $this::KIND_USER:
253
+                        if (!$this->is_system($plugin)) {
254
+                            if (!$skip_init) $plugin->init($this);
255
+                            $this->register_plugin($class, $plugin);
256
+                        }
257
+                        break;
258
+                    case $this::KIND_ALL:
259
+                        if (!$skip_init) $plugin->init($this);
260
+                        $this->register_plugin($class, $plugin);
261
+                        break;
262
+                    }
263
+                }
264
+            }
265
+        }
266
+    }
267
+
268
+    public function is_system($plugin) {
269
+        $about = $plugin->about();
270
+
271
+        return @$about[3];
272
+    }
273
+
274
+    // only system plugins are allowed to modify routing
275
+    public function add_handler($handler, $method, $sender) {
276
+        $handler = str_replace("-", "_", strtolower($handler));
277
+        $method = strtolower($method);
278
+
279
+        if ($this->is_system($sender)) {
280
+            if (!is_array($this->handlers[$handler])) {
281
+                $this->handlers[$handler] = array();
282
+            }
283
+
284
+            $this->handlers[$handler][$method] = $sender;
285
+        }
286
+    }
287
+
288
+    public function del_handler($handler, $method, $sender) {
289
+        $handler = str_replace("-", "_", strtolower($handler));
290
+        $method = strtolower($method);
291
+
292
+        if ($this->is_system($sender)) {
293
+            unset($this->handlers[$handler][$method]);
294
+        }
295
+    }
296
+
297
+    public function lookup_handler($handler, $method) {
298
+        $handler = str_replace("-", "_", strtolower($handler));
299
+        $method = strtolower($method);
300
+
301
+        if (is_array($this->handlers[$handler])) {
302
+            if (isset($this->handlers[$handler]["*"])) {
303
+                return $this->handlers[$handler]["*"];
304
+            } else {
305
+                return $this->handlers[$handler][$method];
306
+            }
307
+        }
308
+
309
+        return false;
310
+    }
311
+
312
+    public function add_command($command, $description, $sender, $suffix = "", $arghelp = "") {
313
+        $command = str_replace("-", "_", strtolower($command));
314
+
315
+        $this->commands[$command] = array("description" => $description,
316
+            "suffix" => $suffix,
317
+            "arghelp" => $arghelp,
318
+            "class" => $sender);
319
+    }
320
+
321
+    public function del_command($command) {
322
+        $command = "-" . strtolower($command);
323
+
324
+        unset($this->commands[$command]);
325
+    }
326
+
327
+    public function lookup_command($command) {
328
+        $command = "-" . strtolower($command);
329
+
330
+        if (is_array($this->commands[$command])) {
331
+            return $this->commands[$command]["class"];
332
+        } else {
333
+            return false;
334
+        }
335
+    }
336
+
337
+    public function get_commands() {
338
+        return $this->commands;
339
+    }
340
+
341
+    public function run_commands($args) {
342
+        foreach ($this->get_commands() as $command => $data) {
343
+            if (isset($args[$command])) {
344
+                $command = str_replace("-", "", $command);
345
+                $data["class"]->$command($args);
346
+            }
347
+        }
348
+    }
349
+
350
+    public function load_data() {
351
+        if ($this->owner_uid)  {
352
+            $sth = $this->pdo->prepare("SELECT name, content FROM ttrss_plugin_storage
353 353
 				WHERE owner_uid = ?");
354
-			$sth->execute([$this->owner_uid]);
354
+            $sth->execute([$this->owner_uid]);
355 355
 
356
-			while ($line = $sth->fetch()) {
357
-				$this->storage[$line["name"]] = unserialize($line["content"]);
358
-			}
359
-		}
360
-	}
356
+            while ($line = $sth->fetch()) {
357
+                $this->storage[$line["name"]] = unserialize($line["content"]);
358
+            }
359
+        }
360
+    }
361 361
 
362
-	private function save_data($plugin) {
363
-		if ($this->owner_uid) {
364
-			$this->pdo->beginTransaction();
362
+    private function save_data($plugin) {
363
+        if ($this->owner_uid) {
364
+            $this->pdo->beginTransaction();
365 365
 
366
-			$sth = $this->pdo->prepare("SELECT id FROM ttrss_plugin_storage WHERE
366
+            $sth = $this->pdo->prepare("SELECT id FROM ttrss_plugin_storage WHERE
367 367
 				owner_uid= ? AND name = ?");
368
-			$sth->execute([$this->owner_uid, $plugin]);
368
+            $sth->execute([$this->owner_uid, $plugin]);
369 369
 
370
-			if (!isset($this->storage[$plugin]))
371
-				$this->storage[$plugin] = array();
370
+            if (!isset($this->storage[$plugin]))
371
+                $this->storage[$plugin] = array();
372 372
 
373
-			$content = serialize($this->storage[$plugin]);
373
+            $content = serialize($this->storage[$plugin]);
374 374
 
375
-			if ($sth->fetch()) {
376
-				$sth = $this->pdo->prepare("UPDATE ttrss_plugin_storage SET content = ?
375
+            if ($sth->fetch()) {
376
+                $sth = $this->pdo->prepare("UPDATE ttrss_plugin_storage SET content = ?
377 377
 					WHERE owner_uid= ? AND name = ?");
378
-				$sth->execute([(string)$content, $this->owner_uid, $plugin]);
378
+                $sth->execute([(string)$content, $this->owner_uid, $plugin]);
379 379
 
380
-			} else {
381
-				$sth = $this->pdo->prepare("INSERT INTO ttrss_plugin_storage
380
+            } else {
381
+                $sth = $this->pdo->prepare("INSERT INTO ttrss_plugin_storage
382 382
 					(name,owner_uid,content) VALUES
383 383
 					(?, ?, ?)");
384
-				$sth->execute([$plugin, $this->owner_uid, (string)$content]);
385
-			}
384
+                $sth->execute([$plugin, $this->owner_uid, (string)$content]);
385
+            }
386 386
 
387
-			$this->pdo->commit();
388
-		}
389
-	}
387
+            $this->pdo->commit();
388
+        }
389
+    }
390 390
 
391
-	public function set($sender, $name, $value, $sync = true) {
392
-		$idx = get_class($sender);
391
+    public function set($sender, $name, $value, $sync = true) {
392
+        $idx = get_class($sender);
393 393
 
394
-		if (!isset($this->storage[$idx]))
395
-			$this->storage[$idx] = array();
394
+        if (!isset($this->storage[$idx]))
395
+            $this->storage[$idx] = array();
396 396
 
397
-		$this->storage[$idx][$name] = $value;
397
+        $this->storage[$idx][$name] = $value;
398 398
 
399
-		if ($sync) $this->save_data(get_class($sender));
400
-	}
399
+        if ($sync) $this->save_data(get_class($sender));
400
+    }
401 401
 
402
-	public function get($sender, $name, $default_value = false) {
403
-		$idx = get_class($sender);
402
+    public function get($sender, $name, $default_value = false) {
403
+        $idx = get_class($sender);
404 404
 
405
-		if (isset($this->storage[$idx][$name])) {
406
-			return $this->storage[$idx][$name];
407
-		} else {
408
-			return $default_value;
409
-		}
410
-	}
405
+        if (isset($this->storage[$idx][$name])) {
406
+            return $this->storage[$idx][$name];
407
+        } else {
408
+            return $default_value;
409
+        }
410
+    }
411 411
 
412
-	public function get_all($sender) {
413
-		$idx = get_class($sender);
412
+    public function get_all($sender) {
413
+        $idx = get_class($sender);
414 414
 
415
-		$data = $this->storage[$idx];
415
+        $data = $this->storage[$idx];
416 416
 
417
-		return $data ? $data : [];
418
-	}
417
+        return $data ? $data : [];
418
+    }
419 419
 
420
-	public function clear_data($sender) {
421
-		if ($this->owner_uid) {
422
-			$idx = get_class($sender);
420
+    public function clear_data($sender) {
421
+        if ($this->owner_uid) {
422
+            $idx = get_class($sender);
423 423
 
424
-			unset($this->storage[$idx]);
424
+            unset($this->storage[$idx]);
425 425
 
426
-			$sth = $this->pdo->prepare("DELETE FROM ttrss_plugin_storage WHERE name = ?
426
+            $sth = $this->pdo->prepare("DELETE FROM ttrss_plugin_storage WHERE name = ?
427 427
 				AND owner_uid = ?");
428
-			$sth->execute([$idx, $this->owner_uid]);
429
-		}
430
-	}
431
-
432
-	// Plugin feed functions are *EXPERIMENTAL*!
433
-
434
-	// cat_id: only -1 is supported (Special)
435
-	public function add_feed($cat_id, $title, $icon, $sender) {
436
-		if (!$this->feeds[$cat_id]) $this->feeds[$cat_id] = array();
437
-
438
-		$id = count($this->feeds[$cat_id]);
439
-
440
-		array_push($this->feeds[$cat_id],
441
-			array('id' => $id, 'title' => $title, 'sender' => $sender, 'icon' => $icon));
442
-
443
-		return $id;
444
-	}
445
-
446
-	public function get_feeds($cat_id) {
447
-		return $this->feeds[$cat_id];
448
-	}
449
-
450
-	// convert feed_id (e.g. -129) to pfeed_id first
451
-	public function get_feed_handler($pfeed_id) {
452
-		foreach ($this->feeds as $cat) {
453
-			foreach ($cat as $feed) {
454
-				if ($feed['id'] == $pfeed_id) {
455
-					return $feed['sender'];
456
-				}
457
-			}
458
-		}
459
-	}
460
-
461
-	public static function pfeed_to_feed_id($label) {
462
-		return PLUGIN_FEED_BASE_INDEX - 1 - abs($label);
463
-	}
464
-
465
-	public static function feed_to_pfeed_id($feed) {
466
-		return PLUGIN_FEED_BASE_INDEX - 1 + abs($feed);
467
-	}
468
-
469
-	public function add_api_method($name, $sender) {
470
-		if ($this->is_system($sender)) {
471
-			$this->api_methods[strtolower($name)] = $sender;
472
-		}
473
-	}
474
-
475
-	public function get_api_method($name) {
476
-		return $this->api_methods[$name];
477
-	}
478
-
479
-	public function add_filter_action($sender, $action_name, $action_desc) {
480
-		$sender_class = get_class($sender);
481
-
482
-		if (!isset($this->plugin_actions[$sender_class]))
483
-			$this->plugin_actions[$sender_class] = array();
484
-
485
-		array_push($this->plugin_actions[$sender_class],
486
-			array("action" => $action_name, "description" => $action_desc, "sender" => $sender));
487
-	}
488
-
489
-	public function get_filter_actions() {
490
-		return $this->plugin_actions;
491
-	}
492
-
493
-	public function get_owner_uid() {
494
-		return $this->owner_uid;
495
-	}
496
-
497
-	// handled by classes/pluginhandler.php, requires valid session
498
-	public function get_method_url($sender, $method, $params)  {
499
-		return get_self_url_prefix() . "/backend.php?" .
500
-			http_build_query(
501
-				array_merge(
502
-					[
503
-						"op" => "pluginhandler",
504
-						"plugin" => strtolower(get_class($sender)),
505
-						"method" => $method
506
-					],
507
-					$params));
508
-	}
509
-
510
-	// WARNING: endpoint in public.php, exposed to unauthenticated users
511
-	public function get_public_method_url($sender, $method, $params)  {
512
-		if ($sender->is_public_method($method)) {
513
-			return get_self_url_prefix() . "/public.php?" .
514
-				http_build_query(
515
-					array_merge(
516
-						[
517
-							"op" => "pluginhandler",
518
-							"plugin" => strtolower(get_class($sender)),
519
-							"pmethod" => $method
520
-						],
521
-						$params));
522
-		} else {
523
-			user_error("get_public_method_url: requested method '$method' of '" . get_class($sender) . "' is private.");
524
-		}
525
-	}
428
+            $sth->execute([$idx, $this->owner_uid]);
429
+        }
430
+    }
431
+
432
+    // Plugin feed functions are *EXPERIMENTAL*!
433
+
434
+    // cat_id: only -1 is supported (Special)
435
+    public function add_feed($cat_id, $title, $icon, $sender) {
436
+        if (!$this->feeds[$cat_id]) $this->feeds[$cat_id] = array();
437
+
438
+        $id = count($this->feeds[$cat_id]);
439
+
440
+        array_push($this->feeds[$cat_id],
441
+            array('id' => $id, 'title' => $title, 'sender' => $sender, 'icon' => $icon));
442
+
443
+        return $id;
444
+    }
445
+
446
+    public function get_feeds($cat_id) {
447
+        return $this->feeds[$cat_id];
448
+    }
449
+
450
+    // convert feed_id (e.g. -129) to pfeed_id first
451
+    public function get_feed_handler($pfeed_id) {
452
+        foreach ($this->feeds as $cat) {
453
+            foreach ($cat as $feed) {
454
+                if ($feed['id'] == $pfeed_id) {
455
+                    return $feed['sender'];
456
+                }
457
+            }
458
+        }
459
+    }
460
+
461
+    public static function pfeed_to_feed_id($label) {
462
+        return PLUGIN_FEED_BASE_INDEX - 1 - abs($label);
463
+    }
464
+
465
+    public static function feed_to_pfeed_id($feed) {
466
+        return PLUGIN_FEED_BASE_INDEX - 1 + abs($feed);
467
+    }
468
+
469
+    public function add_api_method($name, $sender) {
470
+        if ($this->is_system($sender)) {
471
+            $this->api_methods[strtolower($name)] = $sender;
472
+        }
473
+    }
474
+
475
+    public function get_api_method($name) {
476
+        return $this->api_methods[$name];
477
+    }
478
+
479
+    public function add_filter_action($sender, $action_name, $action_desc) {
480
+        $sender_class = get_class($sender);
481
+
482
+        if (!isset($this->plugin_actions[$sender_class]))
483
+            $this->plugin_actions[$sender_class] = array();
484
+
485
+        array_push($this->plugin_actions[$sender_class],
486
+            array("action" => $action_name, "description" => $action_desc, "sender" => $sender));
487
+    }
488
+
489
+    public function get_filter_actions() {
490
+        return $this->plugin_actions;
491
+    }
492
+
493
+    public function get_owner_uid() {
494
+        return $this->owner_uid;
495
+    }
496
+
497
+    // handled by classes/pluginhandler.php, requires valid session
498
+    public function get_method_url($sender, $method, $params)  {
499
+        return get_self_url_prefix() . "/backend.php?" .
500
+            http_build_query(
501
+                array_merge(
502
+                    [
503
+                        "op" => "pluginhandler",
504
+                        "plugin" => strtolower(get_class($sender)),
505
+                        "method" => $method
506
+                    ],
507
+                    $params));
508
+    }
509
+
510
+    // WARNING: endpoint in public.php, exposed to unauthenticated users
511
+    public function get_public_method_url($sender, $method, $params)  {
512
+        if ($sender->is_public_method($method)) {
513
+            return get_self_url_prefix() . "/public.php?" .
514
+                http_build_query(
515
+                    array_merge(
516
+                        [
517
+                            "op" => "pluginhandler",
518
+                            "plugin" => strtolower(get_class($sender)),
519
+                            "pmethod" => $method
520
+                        ],
521
+                        $params));
522
+        } else {
523
+            user_error("get_public_method_url: requested method '$method' of '" . get_class($sender) . "' is private.");
524
+        }
525
+    }
526 526
 }
Please login to merge, or discard this patch.
classes/backend.php 1 patch
Indentation   +92 added lines, -92 removed lines patch added patch discarded remove patch
@@ -1,97 +1,97 @@
 block discarded – undo
1 1
 <?php
2 2
 class Backend extends Handler {
3
-	public function loading() {
4
-		header("Content-type: text/html");
5
-		print __("Loading, please wait...") . " " .
6
-			"<img src='images/indicator_tiny.gif'>";
7
-	}
8
-
9
-	public function digestTest() {
10
-		if (isset($_SESSION['uid'])) {
11
-			header("Content-type: text/html");
12
-
13
-			$rv = Digest::prepare_headlines_digest($_SESSION['uid'], 1, 1000);
14
-
15
-			print "<h1>HTML</h1>";
16
-			print $rv[0];
17
-			print "<h1>Plain text</h1>";
18
-			print "<pre>".$rv[3]."</pre>";
19
-		} else {
20
-			print error_json(6);
21
-		}
22
-	}
23
-
24
-	public function help() {
25
-		$topic = clean_filename($_REQUEST["topic"]); // only one for now
26
-
27
-		if ($topic == "main") {
28
-			$info = get_hotkeys_info();
29
-			$imap = get_hotkeys_map();
30
-			$omap = array();
31
-
32
-			foreach ($imap[1] as $sequence => $action) {
33
-				if (!isset($omap[$action])) $omap[$action] = array();
34
-
35
-				array_push($omap[$action], $sequence);
36
-			}
37
-
38
-			print "<ul class='panel panel-scrollable hotkeys-help' style='height : 300px'>";
39
-
40
-			$cur_section = "";
41
-			foreach ($info as $section => $hotkeys) {
42
-
43
-				if ($cur_section) print "<li>&nbsp;</li>";
44
-				print "<li><h3>" . $section . "</h3></li>";
45
-				$cur_section = $section;
46
-
47
-				foreach ($hotkeys as $action => $description) {
48
-
49
-					if (is_array($omap[$action])) {
50
-						foreach ($omap[$action] as $sequence) {
51
-							if (strpos($sequence, "|") !== false) {
52
-								$sequence = substr($sequence,
53
-									strpos($sequence, "|")+1,
54
-									strlen($sequence));
55
-							} else {
56
-								$keys = explode(" ", $sequence);
57
-
58
-								for ($i = 0; $i < count($keys); $i++) {
59
-									if (strlen($keys[$i]) > 1) {
60
-										$tmp = '';
61
-										foreach (str_split($keys[$i]) as $c) {
62
-											switch ($c) {
63
-												case '*':
64
-													$tmp .= __('Shift') . '+';
65
-													break;
66
-												case '^':
67
-													$tmp .= __('Ctrl') . '+';
68
-													break;
69
-												default:
70
-													$tmp .= $c;
71
-											}
72
-										}
73
-										$keys[$i] = $tmp;
74
-									}
75
-								}
76
-								$sequence = join(" ", $keys);
77
-							}
78
-
79
-							print "<li>";
80
-							print "<div class='hk'><code>$sequence</code></div>";
81
-							print "<div class='desc'>$description</div>";
82
-							print "</li>";
83
-						}
84
-					}
85
-				}
86
-			}
87
-
88
-			print "</ul>";
89
-		}
90
-
91
-		print "<footer class='text-center'>";
92
-		print "<button dojoType='dijit.form.Button'
3
+    public function loading() {
4
+        header("Content-type: text/html");
5
+        print __("Loading, please wait...") . " " .
6
+            "<img src='images/indicator_tiny.gif'>";
7
+    }
8
+
9
+    public function digestTest() {
10
+        if (isset($_SESSION['uid'])) {
11
+            header("Content-type: text/html");
12
+
13
+            $rv = Digest::prepare_headlines_digest($_SESSION['uid'], 1, 1000);
14
+
15
+            print "<h1>HTML</h1>";
16
+            print $rv[0];
17
+            print "<h1>Plain text</h1>";
18
+            print "<pre>".$rv[3]."</pre>";
19
+        } else {
20
+            print error_json(6);
21
+        }
22
+    }
23
+
24
+    public function help() {
25
+        $topic = clean_filename($_REQUEST["topic"]); // only one for now
26
+
27
+        if ($topic == "main") {
28
+            $info = get_hotkeys_info();
29
+            $imap = get_hotkeys_map();
30
+            $omap = array();
31
+
32
+            foreach ($imap[1] as $sequence => $action) {
33
+                if (!isset($omap[$action])) $omap[$action] = array();
34
+
35
+                array_push($omap[$action], $sequence);
36
+            }
37
+
38
+            print "<ul class='panel panel-scrollable hotkeys-help' style='height : 300px'>";
39
+
40
+            $cur_section = "";
41
+            foreach ($info as $section => $hotkeys) {
42
+
43
+                if ($cur_section) print "<li>&nbsp;</li>";
44
+                print "<li><h3>" . $section . "</h3></li>";
45
+                $cur_section = $section;
46
+
47
+                foreach ($hotkeys as $action => $description) {
48
+
49
+                    if (is_array($omap[$action])) {
50
+                        foreach ($omap[$action] as $sequence) {
51
+                            if (strpos($sequence, "|") !== false) {
52
+                                $sequence = substr($sequence,
53
+                                    strpos($sequence, "|")+1,
54
+                                    strlen($sequence));
55
+                            } else {
56
+                                $keys = explode(" ", $sequence);
57
+
58
+                                for ($i = 0; $i < count($keys); $i++) {
59
+                                    if (strlen($keys[$i]) > 1) {
60
+                                        $tmp = '';
61
+                                        foreach (str_split($keys[$i]) as $c) {
62
+                                            switch ($c) {
63
+                                                case '*':
64
+                                                    $tmp .= __('Shift') . '+';
65
+                                                    break;
66
+                                                case '^':
67
+                                                    $tmp .= __('Ctrl') . '+';
68
+                                                    break;
69
+                                                default:
70
+                                                    $tmp .= $c;
71
+                                            }
72
+                                        }
73
+                                        $keys[$i] = $tmp;
74
+                                    }
75
+                                }
76
+                                $sequence = join(" ", $keys);
77
+                            }
78
+
79
+                            print "<li>";
80
+                            print "<div class='hk'><code>$sequence</code></div>";
81
+                            print "<div class='desc'>$description</div>";
82
+                            print "</li>";
83
+                        }
84
+                    }
85
+                }
86
+            }
87
+
88
+            print "</ul>";
89
+        }
90
+
91
+        print "<footer class='text-center'>";
92
+        print "<button dojoType='dijit.form.Button'
93 93
 			onclick=\"return dijit.byId('helpDlg').hide()\">".__('Close this window')."</button>";
94
-		print "</footer>";
94
+        print "</footer>";
95 95
 
96
-	}
96
+    }
97 97
 }
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/db/mysqli.php 1 patch
Indentation   +81 added lines, -81 removed lines patch added patch discarded remove patch
@@ -1,85 +1,85 @@
 block discarded – undo
1 1
 <?php
2 2
 class Db_Mysqli implements IDb {
3
-	private $link;
4
-	private $last_error;
5
-
6
-	public function connect($host, $user, $pass, $db, $port) {
7
-		if ($port)
8
-			$this->link = mysqli_connect($host, $user, $pass, $db, $port);
9
-		else
10
-			$this->link = mysqli_connect($host, $user, $pass, $db);
11
-
12
-		if ($this->link) {
13
-			$this->init();
14
-
15
-			return $this->link;
16
-		} else {
17
-			print("Unable to connect to database (as $user to $host, database $db): " . mysqli_connect_error());
18
-			exit(102);
19
-		}
20
-	}
21
-
22
-	public function escape_string($s, $strip_tags = true) {
23
-		if ($strip_tags) $s = strip_tags($s);
24
-
25
-		return mysqli_real_escape_string($this->link, $s);
26
-	}
27
-
28
-	public function query($query, $die_on_error = true) {
29
-		$result = @mysqli_query($this->link, $query);
30
-		if (!$result) {
31
-			$this->last_error = @mysqli_error($this->link);
32
-
33
-			@mysqli_query($this->link, "ROLLBACK");
34
-			user_error("query $query failed: " . ($this->link ? $this->last_error : "No connection"),
35
-				$die_on_error ? E_USER_ERROR : E_USER_WARNING);
36
-		}
37
-
38
-		return $result;
39
-	}
40
-
41
-	public function fetch_assoc($result) {
42
-		return mysqli_fetch_assoc($result);
43
-	}
44
-
45
-
46
-	public function num_rows($result) {
47
-		return mysqli_num_rows($result);
48
-	}
49
-
50
-	public function fetch_result($result, $row, $param) {
51
-		if (mysqli_data_seek($result, $row)) {
52
-			$line = mysqli_fetch_assoc($result);
53
-			return $line[$param];
54
-		} else {
55
-			return false;
56
-		}
57
-	}
58
-
59
-	public function close() {
60
-		return mysqli_close($this->link);
61
-	}
62
-
63
-	public function affected_rows($result) {
64
-		return mysqli_affected_rows($this->link);
65
-	}
66
-
67
-	public function last_error() {
68
-		return mysqli_error($this->link);
69
-	}
70
-
71
-	public function last_query_error() {
72
-		return $this->last_error;
73
-	}
74
-
75
-	public function init() {
76
-		$this->query("SET time_zone = '+0:0'");
77
-
78
-		if (defined('MYSQL_CHARSET') && MYSQL_CHARSET) {
79
-			mysqli_set_charset($this->link, MYSQL_CHARSET);
80
-		}
81
-
82
-		return true;
83
-	}
3
+    private $link;
4
+    private $last_error;
5
+
6
+    public function connect($host, $user, $pass, $db, $port) {
7
+        if ($port)
8
+            $this->link = mysqli_connect($host, $user, $pass, $db, $port);
9
+        else
10
+            $this->link = mysqli_connect($host, $user, $pass, $db);
11
+
12
+        if ($this->link) {
13
+            $this->init();
14
+
15
+            return $this->link;
16
+        } else {
17
+            print("Unable to connect to database (as $user to $host, database $db): " . mysqli_connect_error());
18
+            exit(102);
19
+        }
20
+    }
21
+
22
+    public function escape_string($s, $strip_tags = true) {
23
+        if ($strip_tags) $s = strip_tags($s);
24
+
25
+        return mysqli_real_escape_string($this->link, $s);
26
+    }
27
+
28
+    public function query($query, $die_on_error = true) {
29
+        $result = @mysqli_query($this->link, $query);
30
+        if (!$result) {
31
+            $this->last_error = @mysqli_error($this->link);
32
+
33
+            @mysqli_query($this->link, "ROLLBACK");
34
+            user_error("query $query failed: " . ($this->link ? $this->last_error : "No connection"),
35
+                $die_on_error ? E_USER_ERROR : E_USER_WARNING);
36
+        }
37
+
38
+        return $result;
39
+    }
40
+
41
+    public function fetch_assoc($result) {
42
+        return mysqli_fetch_assoc($result);
43
+    }
44
+
45
+
46
+    public function num_rows($result) {
47
+        return mysqli_num_rows($result);
48
+    }
49
+
50
+    public function fetch_result($result, $row, $param) {
51
+        if (mysqli_data_seek($result, $row)) {
52
+            $line = mysqli_fetch_assoc($result);
53
+            return $line[$param];
54
+        } else {
55
+            return false;
56
+        }
57
+    }
58
+
59
+    public function close() {
60
+        return mysqli_close($this->link);
61
+    }
62
+
63
+    public function affected_rows($result) {
64
+        return mysqli_affected_rows($this->link);
65
+    }
66
+
67
+    public function last_error() {
68
+        return mysqli_error($this->link);
69
+    }
70
+
71
+    public function last_query_error() {
72
+        return $this->last_error;
73
+    }
74
+
75
+    public function init() {
76
+        $this->query("SET time_zone = '+0:0'");
77
+
78
+        if (defined('MYSQL_CHARSET') && MYSQL_CHARSET) {
79
+            mysqli_set_charset($this->link, MYSQL_CHARSET);
80
+        }
81
+
82
+        return true;
83
+    }
84 84
 
85 85
 }
Please login to merge, or discard this patch.
classes/db/pgsql.php 1 patch
Indentation   +65 added lines, -65 removed lines patch added patch discarded remove patch
@@ -1,91 +1,91 @@
 block discarded – undo
1 1
 <?php
2 2
 class Db_Pgsql implements IDb {
3
-	private $link;
4
-	private $last_error;
3
+    private $link;
4
+    private $last_error;
5 5
 
6
-	public function connect($host, $user, $pass, $db, $port) {
7
-		$string = "dbname=$db user=$user";
6
+    public function connect($host, $user, $pass, $db, $port) {
7
+        $string = "dbname=$db user=$user";
8 8
 
9
-		if ($pass) {
10
-			$string .= " password=$pass";
11
-		}
9
+        if ($pass) {
10
+            $string .= " password=$pass";
11
+        }
12 12
 
13
-		if ($host) {
14
-			$string .= " host=$host";
15
-		}
13
+        if ($host) {
14
+            $string .= " host=$host";
15
+        }
16 16
 
17
-		if (is_numeric($port) && $port > 0) {
18
-			$string = "$string port=" . $port;
19
-		}
17
+        if (is_numeric($port) && $port > 0) {
18
+            $string = "$string port=" . $port;
19
+        }
20 20
 
21
-		$this->link = pg_connect($string);
21
+        $this->link = pg_connect($string);
22 22
 
23
-		if (!$this->link) {
24
-			print("Unable to connect to database (as $user to $host, database $db):" . pg_last_error());
25
-			exit(102);
26
-		}
23
+        if (!$this->link) {
24
+            print("Unable to connect to database (as $user to $host, database $db):" . pg_last_error());
25
+            exit(102);
26
+        }
27 27
 
28
-		$this->init();
28
+        $this->init();
29 29
 
30
-		return $this->link;
31
-	}
30
+        return $this->link;
31
+    }
32 32
 
33
-	public function escape_string($s, $strip_tags = true) {
34
-		if ($strip_tags) $s = strip_tags($s);
33
+    public function escape_string($s, $strip_tags = true) {
34
+        if ($strip_tags) $s = strip_tags($s);
35 35
 
36
-		return pg_escape_string($s);
37
-	}
36
+        return pg_escape_string($s);
37
+    }
38 38
 
39
-	public function query($query, $die_on_error = true) {
40
-		$result = @pg_query($this->link, $query);
39
+    public function query($query, $die_on_error = true) {
40
+        $result = @pg_query($this->link, $query);
41 41
 
42
-		if (!$result) {
43
-			$this->last_error = @pg_last_error($this->link);
42
+        if (!$result) {
43
+            $this->last_error = @pg_last_error($this->link);
44 44
 
45
-			@pg_query($this->link, "ROLLBACK");
46
-			$query = htmlspecialchars($query); // just in case
47
-			user_error("query $query failed: " . ($this->link ? $this->last_error : "No connection"),
48
-				$die_on_error ? E_USER_ERROR : E_USER_WARNING);
49
-		}
50
-		return $result;
51
-	}
45
+            @pg_query($this->link, "ROLLBACK");
46
+            $query = htmlspecialchars($query); // just in case
47
+            user_error("query $query failed: " . ($this->link ? $this->last_error : "No connection"),
48
+                $die_on_error ? E_USER_ERROR : E_USER_WARNING);
49
+        }
50
+        return $result;
51
+    }
52 52
 
53
-	public function fetch_assoc($result) {
54
-		return pg_fetch_assoc($result);
55
-	}
53
+    public function fetch_assoc($result) {
54
+        return pg_fetch_assoc($result);
55
+    }
56 56
 
57 57
 
58
-	public function num_rows($result) {
59
-		return pg_num_rows($result);
60
-	}
58
+    public function num_rows($result) {
59
+        return pg_num_rows($result);
60
+    }
61 61
 
62
-	public function fetch_result($result, $row, $param) {
63
-		return pg_fetch_result($result, $row, $param);
64
-	}
62
+    public function fetch_result($result, $row, $param) {
63
+        return pg_fetch_result($result, $row, $param);
64
+    }
65 65
 
66
-	public function close() {
67
-		return pg_close($this->link);
68
-	}
66
+    public function close() {
67
+        return pg_close($this->link);
68
+    }
69 69
 
70
-	public function affected_rows($result) {
71
-		return pg_affected_rows($result);
72
-	}
70
+    public function affected_rows($result) {
71
+        return pg_affected_rows($result);
72
+    }
73 73
 
74
-	public function last_error() {
75
-		return pg_last_error($this->link);
76
-	}
74
+    public function last_error() {
75
+        return pg_last_error($this->link);
76
+    }
77 77
 
78
-	public function last_query_error() {
79
-		return $this->last_error;
80
-	}
78
+    public function last_query_error() {
79
+        return $this->last_error;
80
+    }
81 81
 
82
-	public function init() {
83
-		$this->query("set client_encoding = 'UTF-8'");
84
-		pg_set_client_encoding("UNICODE");
85
-		$this->query("set datestyle = 'ISO, european'");
86
-		$this->query("set TIME ZONE 0");
87
-		$this->query("set cpu_tuple_cost = 0.5");
82
+    public function init() {
83
+        $this->query("set client_encoding = 'UTF-8'");
84
+        pg_set_client_encoding("UNICODE");
85
+        $this->query("set datestyle = 'ISO, european'");
86
+        $this->query("set TIME ZONE 0");
87
+        $this->query("set cpu_tuple_cost = 0.5");
88 88
 
89
-		return true;
90
-	}
89
+        return true;
90
+    }
91 91
 }
Please login to merge, or discard this patch.
classes/rssutils.php 1 patch
Indentation   +1270 added lines, -1270 removed lines patch added patch discarded remove patch
@@ -1,50 +1,50 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 class RSSUtils {
3
-	public static function calculate_article_hash($article, $pluginhost) {
4
-		$tmp = "";
5
-
6
-		foreach ($article as $k => $v) {
7
-			if ($k != "feed" && isset($v)) {
8
-				$x = strip_tags(is_array($v) ? implode(",", $v) : $v);
9
-
10
-				$tmp .= sha1("$k:" . sha1($x));
11
-			}
12
-		}
13
-
14
-		return sha1(implode(",", $pluginhost->get_plugin_names()) . $tmp);
15
-	}
16
-
17
-	// Strips utf8mb4 characters (i.e. emoji) for mysql
18
-	public static function strip_utf8mb4($str) {
19
-		return preg_replace('/[\x{10000}-\x{10FFFF}]/u', "\xEF\xBF\xBD", $str);
20
-	}
21
-
22
-	public static function cleanup_feed_browser() {
23
-		$pdo = Db::pdo();
24
-		$pdo->query("DELETE FROM ttrss_feedbrowser_cache");
25
-	}
26
-
27
-	public static function update_daemon_common($limit = DAEMON_FEED_LIMIT) {
28
-		$schema_version = get_schema_version();
29
-
30
-		if ($schema_version != SCHEMA_VERSION) {
31
-			die("Schema version is wrong, please upgrade the database.\n");
32
-		}
33
-
34
-		$pdo = Db::pdo();
35
-
36
-		if (!SINGLE_USER_MODE && DAEMON_UPDATE_LOGIN_LIMIT > 0) {
37
-			if (DB_TYPE == "pgsql") {
38
-				$login_thresh_qpart = "AND ttrss_users.last_login >= NOW() - INTERVAL '".DAEMON_UPDATE_LOGIN_LIMIT." days'";
39
-			} else {
40
-				$login_thresh_qpart = "AND ttrss_users.last_login >= DATE_SUB(NOW(), INTERVAL ".DAEMON_UPDATE_LOGIN_LIMIT." DAY)";
41
-			}
42
-		} else {
43
-			$login_thresh_qpart = "";
44
-		}
45
-
46
-		if (DB_TYPE == "pgsql") {
47
-			$update_limit_qpart = "AND ((
3
+    public static function calculate_article_hash($article, $pluginhost) {
4
+        $tmp = "";
5
+
6
+        foreach ($article as $k => $v) {
7
+            if ($k != "feed" && isset($v)) {
8
+                $x = strip_tags(is_array($v) ? implode(",", $v) : $v);
9
+
10
+                $tmp .= sha1("$k:" . sha1($x));
11
+            }
12
+        }
13
+
14
+        return sha1(implode(",", $pluginhost->get_plugin_names()) . $tmp);
15
+    }
16
+
17
+    // Strips utf8mb4 characters (i.e. emoji) for mysql
18
+    public static function strip_utf8mb4($str) {
19
+        return preg_replace('/[\x{10000}-\x{10FFFF}]/u', "\xEF\xBF\xBD", $str);
20
+    }
21
+
22
+    public static function cleanup_feed_browser() {
23
+        $pdo = Db::pdo();
24
+        $pdo->query("DELETE FROM ttrss_feedbrowser_cache");
25
+    }
26
+
27
+    public static function update_daemon_common($limit = DAEMON_FEED_LIMIT) {
28
+        $schema_version = get_schema_version();
29
+
30
+        if ($schema_version != SCHEMA_VERSION) {
31
+            die("Schema version is wrong, please upgrade the database.\n");
32
+        }
33
+
34
+        $pdo = Db::pdo();
35
+
36
+        if (!SINGLE_USER_MODE && DAEMON_UPDATE_LOGIN_LIMIT > 0) {
37
+            if (DB_TYPE == "pgsql") {
38
+                $login_thresh_qpart = "AND ttrss_users.last_login >= NOW() - INTERVAL '".DAEMON_UPDATE_LOGIN_LIMIT." days'";
39
+            } else {
40
+                $login_thresh_qpart = "AND ttrss_users.last_login >= DATE_SUB(NOW(), INTERVAL ".DAEMON_UPDATE_LOGIN_LIMIT." DAY)";
41
+            }
42
+        } else {
43
+            $login_thresh_qpart = "";
44
+        }
45
+
46
+        if (DB_TYPE == "pgsql") {
47
+            $update_limit_qpart = "AND ((
48 48
 					ttrss_feeds.update_interval = 0
49 49
 					AND ttrss_user_prefs.value != '-1'
50 50
 					AND ttrss_feeds.last_updated < NOW() - CAST((ttrss_user_prefs.value || ' minutes') AS INTERVAL)
@@ -55,8 +55,8 @@  discard block
 block discarded – undo
55 55
 					AND ttrss_user_prefs.value != '-1')
56 56
 				OR (last_updated = '1970-01-01 00:00:00'
57 57
 					AND ttrss_user_prefs.value != '-1'))";
58
-		} else {
59
-			$update_limit_qpart = "AND ((
58
+        } else {
59
+            $update_limit_qpart = "AND ((
60 60
 					ttrss_feeds.update_interval = 0
61 61
 					AND ttrss_user_prefs.value != '-1'
62 62
 					AND ttrss_feeds.last_updated < DATE_SUB(NOW(), INTERVAL CONVERT(ttrss_user_prefs.value, SIGNED INTEGER) MINUTE)
@@ -67,22 +67,22 @@  discard block
 block discarded – undo
67 67
 					AND ttrss_user_prefs.value != '-1')
68 68
 				OR (last_updated = '1970-01-01 00:00:00'
69 69
 					AND ttrss_user_prefs.value != '-1'))";
70
-		}
70
+        }
71 71
 
72
-		// Test if feed is currently being updated by another process.
73
-		if (DB_TYPE == "pgsql") {
74
-			$updstart_thresh_qpart = "AND (ttrss_feeds.last_update_started IS NULL OR ttrss_feeds.last_update_started < NOW() - INTERVAL '10 minutes')";
75
-		} else {
76
-			$updstart_thresh_qpart = "AND (ttrss_feeds.last_update_started IS NULL OR ttrss_feeds.last_update_started < DATE_SUB(NOW(), INTERVAL 10 MINUTE))";
77
-		}
72
+        // Test if feed is currently being updated by another process.
73
+        if (DB_TYPE == "pgsql") {
74
+            $updstart_thresh_qpart = "AND (ttrss_feeds.last_update_started IS NULL OR ttrss_feeds.last_update_started < NOW() - INTERVAL '10 minutes')";
75
+        } else {
76
+            $updstart_thresh_qpart = "AND (ttrss_feeds.last_update_started IS NULL OR ttrss_feeds.last_update_started < DATE_SUB(NOW(), INTERVAL 10 MINUTE))";
77
+        }
78 78
 
79
-		$query_limit = $limit ? sprintf("LIMIT %d", $limit) : "";
79
+        $query_limit = $limit ? sprintf("LIMIT %d", $limit) : "";
80 80
 
81
-		// Update the least recently updated feeds first
82
-		$query_order = "ORDER BY last_updated";
83
-		if (DB_TYPE == "pgsql") $query_order .= " NULLS FIRST";
81
+        // Update the least recently updated feeds first
82
+        $query_order = "ORDER BY last_updated";
83
+        if (DB_TYPE == "pgsql") $query_order .= " NULLS FIRST";
84 84
 
85
-		$query = "SELECT DISTINCT ttrss_feeds.feed_url, ttrss_feeds.last_updated
85
+        $query = "SELECT DISTINCT ttrss_feeds.feed_url, ttrss_feeds.last_updated
86 86
 			FROM
87 87
 				ttrss_feeds, ttrss_users, ttrss_user_prefs
88 88
 			WHERE
@@ -94,32 +94,32 @@  discard block
 block discarded – undo
94 94
 				$updstart_thresh_qpart
95 95
 				$query_order $query_limit";
96 96
 
97
-		$res = $pdo->query($query);
97
+        $res = $pdo->query($query);
98 98
 
99
-		$feeds_to_update = array();
100
-		while ($line = $res->fetch()) {
101
-			array_push($feeds_to_update, $line['feed_url']);
102
-		}
99
+        $feeds_to_update = array();
100
+        while ($line = $res->fetch()) {
101
+            array_push($feeds_to_update, $line['feed_url']);
102
+        }
103 103
 
104
-		Debug::log(sprintf("Scheduled %d feeds to update...", count($feeds_to_update)));
104
+        Debug::log(sprintf("Scheduled %d feeds to update...", count($feeds_to_update)));
105 105
 
106
-		// Update last_update_started before actually starting the batch
107
-		// in order to minimize collision risk for parallel daemon tasks
108
-		if (count($feeds_to_update) > 0) {
109
-			$feeds_qmarks = arr_qmarks($feeds_to_update);
106
+        // Update last_update_started before actually starting the batch
107
+        // in order to minimize collision risk for parallel daemon tasks
108
+        if (count($feeds_to_update) > 0) {
109
+            $feeds_qmarks = arr_qmarks($feeds_to_update);
110 110
 
111
-			$tmph = $pdo->prepare("UPDATE ttrss_feeds SET last_update_started = NOW()
111
+            $tmph = $pdo->prepare("UPDATE ttrss_feeds SET last_update_started = NOW()
112 112
 				WHERE feed_url IN ($feeds_qmarks)");
113
-			$tmph->execute($feeds_to_update);
114
-		}
113
+            $tmph->execute($feeds_to_update);
114
+        }
115 115
 
116
-		$nf = 0;
117
-		$bstarted = microtime(true);
116
+        $nf = 0;
117
+        $bstarted = microtime(true);
118 118
 
119
-		$batch_owners = array();
119
+        $batch_owners = array();
120 120
 
121
-		// since we have the data cached, we can deal with other feeds with the same url
122
-		$usth = $pdo->prepare("SELECT DISTINCT ttrss_feeds.id,last_updated,ttrss_feeds.owner_uid
121
+        // since we have the data cached, we can deal with other feeds with the same url
122
+        $usth = $pdo->prepare("SELECT DISTINCT ttrss_feeds.id,last_updated,ttrss_feeds.owner_uid
123 123
 			FROM ttrss_feeds, ttrss_users, ttrss_user_prefs WHERE
124 124
 				ttrss_user_prefs.owner_uid = ttrss_feeds.owner_uid AND
125 125
 				ttrss_users.id = ttrss_user_prefs.owner_uid AND
@@ -130,715 +130,715 @@  discard block
 block discarded – undo
130 130
 				$login_thresh_qpart
131 131
 			ORDER BY ttrss_feeds.id $query_limit");
132 132
 
133
-		foreach ($feeds_to_update as $feed) {
134
-			Debug::log("Base feed: $feed");
133
+        foreach ($feeds_to_update as $feed) {
134
+            Debug::log("Base feed: $feed");
135 135
 
136
-			$usth->execute([$feed]);
137
-			//update_rss_feed($line["id"], true);
136
+            $usth->execute([$feed]);
137
+            //update_rss_feed($line["id"], true);
138 138
 
139
-			if ($tline = $usth->fetch()) {
140
-				Debug::log(" => " . $tline["last_updated"] . ", " . $tline["id"] . " " . $tline["owner_uid"]);
139
+            if ($tline = $usth->fetch()) {
140
+                Debug::log(" => " . $tline["last_updated"] . ", " . $tline["id"] . " " . $tline["owner_uid"]);
141 141
 
142
-				if (array_search($tline["owner_uid"], $batch_owners) === false)
143
-					array_push($batch_owners, $tline["owner_uid"]);
142
+                if (array_search($tline["owner_uid"], $batch_owners) === false)
143
+                    array_push($batch_owners, $tline["owner_uid"]);
144 144
 
145
-				$fstarted = microtime(true);
145
+                $fstarted = microtime(true);
146 146
 
147
-				try {
148
-					RSSUtils::update_rss_feed($tline["id"], true, false);
149
-				} catch (PDOException $e) {
150
-					Logger::get()->log_error(E_USER_NOTICE, $e->getMessage(), $e->getFile(), $e->getLine(), $e->getTraceAsString());
147
+                try {
148
+                    RSSUtils::update_rss_feed($tline["id"], true, false);
149
+                } catch (PDOException $e) {
150
+                    Logger::get()->log_error(E_USER_NOTICE, $e->getMessage(), $e->getFile(), $e->getLine(), $e->getTraceAsString());
151 151
 
152
-					try {
153
-						$pdo->rollback();
154
-					} catch (PDOException $e) {
155
-						// it doesn't matter if there wasn't actually anything to rollback, PDO Exception can be
156
-						// thrown outside of an active transaction during feed update
157
-					}
158
-				}
152
+                    try {
153
+                        $pdo->rollback();
154
+                    } catch (PDOException $e) {
155
+                        // it doesn't matter if there wasn't actually anything to rollback, PDO Exception can be
156
+                        // thrown outside of an active transaction during feed update
157
+                    }
158
+                }
159 159
 
160
-				Debug::log(sprintf("    %.4f (sec)", microtime(true) - $fstarted));
160
+                Debug::log(sprintf("    %.4f (sec)", microtime(true) - $fstarted));
161 161
 
162
-				++$nf;
163
-			}
164
-		}
162
+                ++$nf;
163
+            }
164
+        }
165 165
 
166
-		if ($nf > 0) {
167
-			Debug::log(sprintf("Processed %d feeds in %.4f (sec), %.4f (sec/feed avg)", $nf,
168
-				microtime(true) - $bstarted, (microtime(true) - $bstarted) / $nf));
169
-		}
166
+        if ($nf > 0) {
167
+            Debug::log(sprintf("Processed %d feeds in %.4f (sec), %.4f (sec/feed avg)", $nf,
168
+                microtime(true) - $bstarted, (microtime(true) - $bstarted) / $nf));
169
+        }
170 170
 
171
-		foreach ($batch_owners as $owner_uid) {
172
-			Debug::log("Running housekeeping tasks for user $owner_uid...");
171
+        foreach ($batch_owners as $owner_uid) {
172
+            Debug::log("Running housekeeping tasks for user $owner_uid...");
173 173
 
174
-			RSSUtils::housekeeping_user($owner_uid);
175
-		}
174
+            RSSUtils::housekeeping_user($owner_uid);
175
+        }
176 176
 
177
-		// Send feed digests by email if needed.
178
-		Digest::send_headlines_digests();
177
+        // Send feed digests by email if needed.
178
+        Digest::send_headlines_digests();
179 179
 
180
-		return $nf;
181
-	}
180
+        return $nf;
181
+    }
182 182
 
183
-	// this is used when subscribing
184
-	public static function set_basic_feed_info($feed) {
183
+    // this is used when subscribing
184
+    public static function set_basic_feed_info($feed) {
185 185
 
186
-		$pdo = Db::pdo();
186
+        $pdo = Db::pdo();
187 187
 
188
-		$sth = $pdo->prepare("SELECT owner_uid,feed_url,auth_pass,auth_login
188
+        $sth = $pdo->prepare("SELECT owner_uid,feed_url,auth_pass,auth_login
189 189
 				FROM ttrss_feeds WHERE id = ?");
190
-		$sth->execute([$feed]);
190
+        $sth->execute([$feed]);
191 191
 
192
-		if ($row = $sth->fetch()) {
192
+        if ($row = $sth->fetch()) {
193 193
 
194
-			$owner_uid = $row["owner_uid"];
195
-			$auth_login = $row["auth_login"];
196
-			$auth_pass = $row["auth_pass"];
197
-			$fetch_url = $row["feed_url"];
194
+            $owner_uid = $row["owner_uid"];
195
+            $auth_login = $row["auth_login"];
196
+            $auth_pass = $row["auth_pass"];
197
+            $fetch_url = $row["feed_url"];
198 198
 
199
-			$pluginhost = new PluginHost();
200
-			$user_plugins = get_pref("_ENABLED_PLUGINS", $owner_uid);
199
+            $pluginhost = new PluginHost();
200
+            $user_plugins = get_pref("_ENABLED_PLUGINS", $owner_uid);
201 201
 
202
-			$pluginhost->load(PLUGINS, PluginHost::KIND_ALL);
203
-			$pluginhost->load($user_plugins, PluginHost::KIND_USER, $owner_uid);
204
-			$pluginhost->load_data();
202
+            $pluginhost->load(PLUGINS, PluginHost::KIND_ALL);
203
+            $pluginhost->load($user_plugins, PluginHost::KIND_USER, $owner_uid);
204
+            $pluginhost->load_data();
205 205
 
206
-			$basic_info = array();
207
-			foreach ($pluginhost->get_hooks(PluginHost::HOOK_FEED_BASIC_INFO) as $plugin) {
208
-				$basic_info = $plugin->hook_feed_basic_info($basic_info, $fetch_url, $owner_uid, $feed, $auth_login, $auth_pass);
209
-			}
206
+            $basic_info = array();
207
+            foreach ($pluginhost->get_hooks(PluginHost::HOOK_FEED_BASIC_INFO) as $plugin) {
208
+                $basic_info = $plugin->hook_feed_basic_info($basic_info, $fetch_url, $owner_uid, $feed, $auth_login, $auth_pass);
209
+            }
210 210
 
211
-			if (!$basic_info) {
212
-				$feed_data = fetch_file_contents($fetch_url, false,
213
-					$auth_login, $auth_pass, false,
214
-					FEED_FETCH_TIMEOUT,
215
-					0);
211
+            if (!$basic_info) {
212
+                $feed_data = fetch_file_contents($fetch_url, false,
213
+                    $auth_login, $auth_pass, false,
214
+                    FEED_FETCH_TIMEOUT,
215
+                    0);
216 216
 
217
-				$feed_data = trim($feed_data);
217
+                $feed_data = trim($feed_data);
218 218
 
219
-				$rss = new FeedParser($feed_data);
220
-				$rss->init();
219
+                $rss = new FeedParser($feed_data);
220
+                $rss->init();
221 221
 
222
-				if (!$rss->error()) {
223
-					$basic_info = array(
224
-						'title' => mb_substr(clean($rss->get_title()), 0, 199),
225
-						'site_url' => mb_substr(rewrite_relative_url($fetch_url, clean($rss->get_link())), 0, 245)
226
-					);
227
-				}
228
-			}
222
+                if (!$rss->error()) {
223
+                    $basic_info = array(
224
+                        'title' => mb_substr(clean($rss->get_title()), 0, 199),
225
+                        'site_url' => mb_substr(rewrite_relative_url($fetch_url, clean($rss->get_link())), 0, 245)
226
+                    );
227
+                }
228
+            }
229 229
 
230
-			if ($basic_info && is_array($basic_info)) {
231
-				$sth = $pdo->prepare("SELECT title, site_url FROM ttrss_feeds WHERE id = ?");
232
-				$sth->execute([$feed]);
230
+            if ($basic_info && is_array($basic_info)) {
231
+                $sth = $pdo->prepare("SELECT title, site_url FROM ttrss_feeds WHERE id = ?");
232
+                $sth->execute([$feed]);
233 233
 
234
-				if ($row = $sth->fetch()) {
234
+                if ($row = $sth->fetch()) {
235 235
 
236
-					$registered_title = $row["title"];
237
-					$orig_site_url = $row["site_url"];
236
+                    $registered_title = $row["title"];
237
+                    $orig_site_url = $row["site_url"];
238 238
 
239
-					if ($basic_info['title'] && (!$registered_title || $registered_title == "[Unknown]")) {
239
+                    if ($basic_info['title'] && (!$registered_title || $registered_title == "[Unknown]")) {
240 240
 
241
-						$sth = $pdo->prepare("UPDATE ttrss_feeds SET
241
+                        $sth = $pdo->prepare("UPDATE ttrss_feeds SET
242 242
 							title = ? WHERE id = ?");
243
-						$sth->execute([$basic_info['title'], $feed]);
244
-					}
243
+                        $sth->execute([$basic_info['title'], $feed]);
244
+                    }
245 245
 
246
-					if ($basic_info['site_url'] && $orig_site_url != $basic_info['site_url']) {
247
-						$sth = $pdo->prepare("UPDATE ttrss_feeds SET
246
+                    if ($basic_info['site_url'] && $orig_site_url != $basic_info['site_url']) {
247
+                        $sth = $pdo->prepare("UPDATE ttrss_feeds SET
248 248
 							site_url = ? WHERE id = ?");
249
-						$sth->execute([$basic_info['site_url'], $feed]);
250
-					}
249
+                        $sth->execute([$basic_info['site_url'], $feed]);
250
+                    }
251 251
 
252
-				}
253
-			}
254
-		}
255
-	}
252
+                }
253
+            }
254
+        }
255
+    }
256 256
 
257
-	/**
258
-	 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
259
-	 */
260
-	public static function update_rss_feed($feed, $no_cache = false) {
257
+    /**
258
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
259
+     */
260
+    public static function update_rss_feed($feed, $no_cache = false) {
261 261
 
262
-		reset_fetch_domain_quota();
262
+        reset_fetch_domain_quota();
263 263
 
264
-		Debug::log("start", Debug::$LOG_VERBOSE);
264
+        Debug::log("start", Debug::$LOG_VERBOSE);
265 265
 
266
-		$pdo = Db::pdo();
266
+        $pdo = Db::pdo();
267 267
 
268
-		$sth = $pdo->prepare("SELECT title, site_url FROM ttrss_feeds WHERE id = ?");
269
-		$sth->execute([$feed]);
268
+        $sth = $pdo->prepare("SELECT title, site_url FROM ttrss_feeds WHERE id = ?");
269
+        $sth->execute([$feed]);
270 270
 
271
-		if (!$row = $sth->fetch()) {
272
-			Debug::log("feed $feed not found, skipping.");
273
-			user_error("Attempt to update unknown/invalid feed $feed", E_USER_WARNING);
274
-			return false;
275
-		}
271
+        if (!$row = $sth->fetch()) {
272
+            Debug::log("feed $feed not found, skipping.");
273
+            user_error("Attempt to update unknown/invalid feed $feed", E_USER_WARNING);
274
+            return false;
275
+        }
276 276
 
277
-		$title = $row["title"];
278
-		$site_url = $row["site_url"];
277
+        $title = $row["title"];
278
+        $site_url = $row["site_url"];
279 279
 
280
-		// feed was batch-subscribed or something, we need to get basic info
281
-		// this is not optimal currently as it fetches stuff separately TODO: optimize
282
-		if ($title == "[Unknown]" || !$title || !$site_url) {
283
-			Debug::log("setting basic feed info for $feed [$title, $site_url]...");
284
-			RSSUtils::set_basic_feed_info($feed);
285
-		}
280
+        // feed was batch-subscribed or something, we need to get basic info
281
+        // this is not optimal currently as it fetches stuff separately TODO: optimize
282
+        if ($title == "[Unknown]" || !$title || !$site_url) {
283
+            Debug::log("setting basic feed info for $feed [$title, $site_url]...");
284
+            RSSUtils::set_basic_feed_info($feed);
285
+        }
286 286
 
287
-		$sth = $pdo->prepare("SELECT id,update_interval,auth_login,
287
+        $sth = $pdo->prepare("SELECT id,update_interval,auth_login,
288 288
 			feed_url,auth_pass,cache_images,
289 289
 			mark_unread_on_update, owner_uid,
290 290
 			auth_pass_encrypted, feed_language,
291 291
 			last_modified,
292 292
 			".SUBSTRING_FOR_DATE."(last_unconditional, 1, 19) AS last_unconditional
293 293
 			FROM ttrss_feeds WHERE id = ?");
294
-		$sth->execute([$feed]);
294
+        $sth->execute([$feed]);
295 295
 
296
-		if ($row = $sth->fetch()) {
296
+        if ($row = $sth->fetch()) {
297 297
 
298
-			$owner_uid = $row["owner_uid"];
299
-			$mark_unread_on_update = $row["mark_unread_on_update"];
298
+            $owner_uid = $row["owner_uid"];
299
+            $mark_unread_on_update = $row["mark_unread_on_update"];
300 300
 
301
-			$sth = $pdo->prepare("UPDATE ttrss_feeds SET last_update_started = NOW()
301
+            $sth = $pdo->prepare("UPDATE ttrss_feeds SET last_update_started = NOW()
302 302
 				WHERE id = ?");
303
-			$sth->execute([$feed]);
303
+            $sth->execute([$feed]);
304 304
 
305
-			$auth_login = $row["auth_login"];
306
-			$auth_pass = $row["auth_pass"];
307
-			$stored_last_modified = $row["last_modified"];
308
-			$last_unconditional = $row["last_unconditional"];
309
-			$cache_images = $row["cache_images"];
310
-			$fetch_url = $row["feed_url"];
305
+            $auth_login = $row["auth_login"];
306
+            $auth_pass = $row["auth_pass"];
307
+            $stored_last_modified = $row["last_modified"];
308
+            $last_unconditional = $row["last_unconditional"];
309
+            $cache_images = $row["cache_images"];
310
+            $fetch_url = $row["feed_url"];
311 311
 
312
-			$feed_language = mb_strtolower($row["feed_language"]);
312
+            $feed_language = mb_strtolower($row["feed_language"]);
313 313
 
314
-			if (!$feed_language)
315
-				$feed_language = mb_strtolower(get_pref('DEFAULT_SEARCH_LANGUAGE', $owner_uid));
314
+            if (!$feed_language)
315
+                $feed_language = mb_strtolower(get_pref('DEFAULT_SEARCH_LANGUAGE', $owner_uid));
316 316
 
317
-			if (!$feed_language)
318
-				$feed_language = 'simple';
317
+            if (!$feed_language)
318
+                $feed_language = 'simple';
319 319
 
320
-		} else {
321
-			return false;
322
-		}
320
+        } else {
321
+            return false;
322
+        }
323 323
 
324
-		$date_feed_processed = date('Y-m-d H:i');
324
+        $date_feed_processed = date('Y-m-d H:i');
325 325
 
326
-		$cache_filename = CACHE_DIR . "/feeds/" . sha1($fetch_url) . ".xml";
326
+        $cache_filename = CACHE_DIR . "/feeds/" . sha1($fetch_url) . ".xml";
327 327
 
328
-		$pluginhost = new PluginHost();
329
-		$user_plugins = get_pref("_ENABLED_PLUGINS", $owner_uid);
328
+        $pluginhost = new PluginHost();
329
+        $user_plugins = get_pref("_ENABLED_PLUGINS", $owner_uid);
330 330
 
331
-		$pluginhost->load(PLUGINS, PluginHost::KIND_ALL);
332
-		$pluginhost->load($user_plugins, PluginHost::KIND_USER, $owner_uid);
333
-		$pluginhost->load_data();
331
+        $pluginhost->load(PLUGINS, PluginHost::KIND_ALL);
332
+        $pluginhost->load($user_plugins, PluginHost::KIND_USER, $owner_uid);
333
+        $pluginhost->load_data();
334 334
 
335
-		$rss_hash = false;
335
+        $rss_hash = false;
336 336
 
337
-		$force_refetch = isset($_REQUEST["force_refetch"]);
338
-		$feed_data = "";
337
+        $force_refetch = isset($_REQUEST["force_refetch"]);
338
+        $feed_data = "";
339 339
 
340
-		Debug::log("running HOOK_FETCH_FEED handlers...", Debug::$LOG_VERBOSE);
340
+        Debug::log("running HOOK_FETCH_FEED handlers...", Debug::$LOG_VERBOSE);
341 341
 
342
-		foreach ($pluginhost->get_hooks(PluginHost::HOOK_FETCH_FEED) as $plugin) {
343
-			Debug::log("... " . get_class($plugin), Debug::$LOG_VERBOSE);
344
-			$start = microtime(true);
345
-			$feed_data = $plugin->hook_fetch_feed($feed_data, $fetch_url, $owner_uid, $feed, 0, $auth_login, $auth_pass);
346
-			Debug::log(sprintf("=== %.4f (sec)", microtime(true) - $start), Debug::$LOG_VERBOSE);
347
-		}
342
+        foreach ($pluginhost->get_hooks(PluginHost::HOOK_FETCH_FEED) as $plugin) {
343
+            Debug::log("... " . get_class($plugin), Debug::$LOG_VERBOSE);
344
+            $start = microtime(true);
345
+            $feed_data = $plugin->hook_fetch_feed($feed_data, $fetch_url, $owner_uid, $feed, 0, $auth_login, $auth_pass);
346
+            Debug::log(sprintf("=== %.4f (sec)", microtime(true) - $start), Debug::$LOG_VERBOSE);
347
+        }
348 348
 
349
-		if ($feed_data) {
350
-			Debug::log("feed data has been modified by a plugin.", Debug::$LOG_VERBOSE);
351
-		} else {
352
-			Debug::log("feed data has not been modified by a plugin.", Debug::$LOG_VERBOSE);
353
-		}
349
+        if ($feed_data) {
350
+            Debug::log("feed data has been modified by a plugin.", Debug::$LOG_VERBOSE);
351
+        } else {
352
+            Debug::log("feed data has not been modified by a plugin.", Debug::$LOG_VERBOSE);
353
+        }
354 354
 
355
-		// try cache
356
-		if (!$feed_data &&
357
-			file_exists($cache_filename) &&
358
-			is_readable($cache_filename) &&
359
-			!$auth_login && !$auth_pass &&
360
-			filemtime($cache_filename) > time() - 30) {
355
+        // try cache
356
+        if (!$feed_data &&
357
+            file_exists($cache_filename) &&
358
+            is_readable($cache_filename) &&
359
+            !$auth_login && !$auth_pass &&
360
+            filemtime($cache_filename) > time() - 30) {
361 361
 
362
-			Debug::log("using local cache [$cache_filename].", Debug::$LOG_VERBOSE);
362
+            Debug::log("using local cache [$cache_filename].", Debug::$LOG_VERBOSE);
363 363
 
364
-			@$feed_data = file_get_contents($cache_filename);
364
+            @$feed_data = file_get_contents($cache_filename);
365 365
 
366
-			if ($feed_data) {
367
-				$rss_hash = sha1($feed_data);
368
-			}
366
+            if ($feed_data) {
367
+                $rss_hash = sha1($feed_data);
368
+            }
369 369
 
370
-		} else {
371
-			Debug::log("local cache will not be used for this feed", Debug::$LOG_VERBOSE);
372
-		}
370
+        } else {
371
+            Debug::log("local cache will not be used for this feed", Debug::$LOG_VERBOSE);
372
+        }
373 373
 
374
-		global $fetch_last_modified;
374
+        global $fetch_last_modified;
375 375
 
376
-		// fetch feed from source
377
-		if (!$feed_data) {
378
-			Debug::log("last unconditional update request: $last_unconditional", Debug::$LOG_VERBOSE);
376
+        // fetch feed from source
377
+        if (!$feed_data) {
378
+            Debug::log("last unconditional update request: $last_unconditional", Debug::$LOG_VERBOSE);
379 379
 
380
-			if (ini_get("open_basedir") && function_exists("curl_init")) {
381
-				Debug::log("not using CURL due to open_basedir restrictions", Debug::$LOG_VERBOSE);
382
-			}
380
+            if (ini_get("open_basedir") && function_exists("curl_init")) {
381
+                Debug::log("not using CURL due to open_basedir restrictions", Debug::$LOG_VERBOSE);
382
+            }
383 383
 
384
-			if (time() - strtotime($last_unconditional) > MAX_CONDITIONAL_INTERVAL) {
385
-				Debug::log("maximum allowed interval for conditional requests exceeded, forcing refetch", Debug::$LOG_VERBOSE);
384
+            if (time() - strtotime($last_unconditional) > MAX_CONDITIONAL_INTERVAL) {
385
+                Debug::log("maximum allowed interval for conditional requests exceeded, forcing refetch", Debug::$LOG_VERBOSE);
386 386
 
387
-				$force_refetch = true;
388
-			} else {
389
-				Debug::log("stored last modified for conditional request: $stored_last_modified", Debug::$LOG_VERBOSE);
390
-			}
387
+                $force_refetch = true;
388
+            } else {
389
+                Debug::log("stored last modified for conditional request: $stored_last_modified", Debug::$LOG_VERBOSE);
390
+            }
391 391
 
392
-			Debug::log("fetching [$fetch_url] (force_refetch: $force_refetch)...", Debug::$LOG_VERBOSE);
392
+            Debug::log("fetching [$fetch_url] (force_refetch: $force_refetch)...", Debug::$LOG_VERBOSE);
393 393
 
394
-			$feed_data = fetch_file_contents([
395
-				"url" => $fetch_url,
396
-				"login" => $auth_login,
397
-				"pass" => $auth_pass,
398
-				"timeout" => $no_cache ? FEED_FETCH_NO_CACHE_TIMEOUT : FEED_FETCH_TIMEOUT,
399
-				"last_modified" => $force_refetch ? "" : $stored_last_modified
400
-			]);
394
+            $feed_data = fetch_file_contents([
395
+                "url" => $fetch_url,
396
+                "login" => $auth_login,
397
+                "pass" => $auth_pass,
398
+                "timeout" => $no_cache ? FEED_FETCH_NO_CACHE_TIMEOUT : FEED_FETCH_TIMEOUT,
399
+                "last_modified" => $force_refetch ? "" : $stored_last_modified
400
+            ]);
401 401
 
402
-			$feed_data = trim($feed_data);
402
+            $feed_data = trim($feed_data);
403 403
 
404
-			Debug::log("fetch done.", Debug::$LOG_VERBOSE);
405
-			Debug::log("source last modified: " . $fetch_last_modified, Debug::$LOG_VERBOSE);
404
+            Debug::log("fetch done.", Debug::$LOG_VERBOSE);
405
+            Debug::log("source last modified: " . $fetch_last_modified, Debug::$LOG_VERBOSE);
406 406
 
407
-			if ($feed_data && $fetch_last_modified != $stored_last_modified) {
408
-				$sth = $pdo->prepare("UPDATE ttrss_feeds SET last_modified = ? WHERE id = ?");
409
-				$sth->execute([substr($fetch_last_modified, 0, 245), $feed]);
410
-			}
407
+            if ($feed_data && $fetch_last_modified != $stored_last_modified) {
408
+                $sth = $pdo->prepare("UPDATE ttrss_feeds SET last_modified = ? WHERE id = ?");
409
+                $sth->execute([substr($fetch_last_modified, 0, 245), $feed]);
410
+            }
411 411
 
412
-			// cache vanilla feed data for re-use
413
-			if ($feed_data && !$auth_pass && !$auth_login && is_writable(CACHE_DIR . "/feeds")) {
414
-				$new_rss_hash = sha1($feed_data);
412
+            // cache vanilla feed data for re-use
413
+            if ($feed_data && !$auth_pass && !$auth_login && is_writable(CACHE_DIR . "/feeds")) {
414
+                $new_rss_hash = sha1($feed_data);
415 415
 
416
-				if ($new_rss_hash != $rss_hash) {
417
-					Debug::log("saving $cache_filename", Debug::$LOG_VERBOSE);
418
-					@file_put_contents($cache_filename, $feed_data);
419
-				}
420
-			}
421
-		}
416
+                if ($new_rss_hash != $rss_hash) {
417
+                    Debug::log("saving $cache_filename", Debug::$LOG_VERBOSE);
418
+                    @file_put_contents($cache_filename, $feed_data);
419
+                }
420
+            }
421
+        }
422 422
 
423
-		if (!$feed_data) {
424
-			global $fetch_last_error;
425
-			global $fetch_last_error_code;
423
+        if (!$feed_data) {
424
+            global $fetch_last_error;
425
+            global $fetch_last_error_code;
426 426
 
427
-			Debug::log("unable to fetch: $fetch_last_error [$fetch_last_error_code]", Debug::$LOG_VERBOSE);
427
+            Debug::log("unable to fetch: $fetch_last_error [$fetch_last_error_code]", Debug::$LOG_VERBOSE);
428 428
 
429
-			// If-Modified-Since
430
-			if ($fetch_last_error_code != 304) {
431
-				$error_message = $fetch_last_error;
432
-			} else {
433
-				Debug::log("source claims data not modified, nothing to do.", Debug::$LOG_VERBOSE);
434
-				$error_message = "";
435
-			}
429
+            // If-Modified-Since
430
+            if ($fetch_last_error_code != 304) {
431
+                $error_message = $fetch_last_error;
432
+            } else {
433
+                Debug::log("source claims data not modified, nothing to do.", Debug::$LOG_VERBOSE);
434
+                $error_message = "";
435
+            }
436 436
 
437
-			$sth = $pdo->prepare("UPDATE ttrss_feeds SET last_error = ?,
437
+            $sth = $pdo->prepare("UPDATE ttrss_feeds SET last_error = ?,
438 438
 					last_updated = NOW() WHERE id = ?");
439
-			$sth->execute([$error_message, $feed]);
439
+            $sth->execute([$error_message, $feed]);
440 440
 
441
-			return;
442
-		}
441
+            return;
442
+        }
443 443
 
444
-		Debug::log("running HOOK_FEED_FETCHED handlers...", Debug::$LOG_VERBOSE);
445
-		$feed_data_checksum = md5($feed_data);
444
+        Debug::log("running HOOK_FEED_FETCHED handlers...", Debug::$LOG_VERBOSE);
445
+        $feed_data_checksum = md5($feed_data);
446 446
 
447
-		foreach ($pluginhost->get_hooks(PluginHost::HOOK_FEED_FETCHED) as $plugin) {
448
-			Debug::log("... " . get_class($plugin), Debug::$LOG_VERBOSE);
449
-			$start = microtime(true);
450
-			$feed_data = $plugin->hook_feed_fetched($feed_data, $fetch_url, $owner_uid, $feed);
451
-			Debug::log(sprintf("=== %.4f (sec)", microtime(true) - $start), Debug::$LOG_VERBOSE);
452
-		}
447
+        foreach ($pluginhost->get_hooks(PluginHost::HOOK_FEED_FETCHED) as $plugin) {
448
+            Debug::log("... " . get_class($plugin), Debug::$LOG_VERBOSE);
449
+            $start = microtime(true);
450
+            $feed_data = $plugin->hook_feed_fetched($feed_data, $fetch_url, $owner_uid, $feed);
451
+            Debug::log(sprintf("=== %.4f (sec)", microtime(true) - $start), Debug::$LOG_VERBOSE);
452
+        }
453 453
 
454
-		if (md5($feed_data) != $feed_data_checksum) {
455
-			Debug::log("feed data has been modified by a plugin.", Debug::$LOG_VERBOSE);
456
-		} else {
457
-			Debug::log("feed data has not been modified by a plugin.", Debug::$LOG_VERBOSE);
458
-		}
454
+        if (md5($feed_data) != $feed_data_checksum) {
455
+            Debug::log("feed data has been modified by a plugin.", Debug::$LOG_VERBOSE);
456
+        } else {
457
+            Debug::log("feed data has not been modified by a plugin.", Debug::$LOG_VERBOSE);
458
+        }
459 459
 
460
-		$rss = new FeedParser($feed_data);
461
-		$rss->init();
460
+        $rss = new FeedParser($feed_data);
461
+        $rss->init();
462 462
 
463
-		if (!$rss->error()) {
463
+        if (!$rss->error()) {
464 464
 
465
-			Debug::log("running HOOK_FEED_PARSED handlers...", Debug::$LOG_VERBOSE);
465
+            Debug::log("running HOOK_FEED_PARSED handlers...", Debug::$LOG_VERBOSE);
466 466
 
467
-			// We use local pluginhost here because we need to load different per-user feed plugins
467
+            // We use local pluginhost here because we need to load different per-user feed plugins
468 468
 
469
-			foreach ($pluginhost->get_hooks(PluginHost::HOOK_FEED_PARSED) as $plugin) {
470
-				Debug::log("... " . get_class($plugin), Debug::$LOG_VERBOSE);
471
-				$start = microtime(true);
472
-				$plugin->hook_feed_parsed($rss);
473
-				Debug::log(sprintf("=== %.4f (sec)", microtime(true) - $start), Debug::$LOG_VERBOSE);
474
-			}
469
+            foreach ($pluginhost->get_hooks(PluginHost::HOOK_FEED_PARSED) as $plugin) {
470
+                Debug::log("... " . get_class($plugin), Debug::$LOG_VERBOSE);
471
+                $start = microtime(true);
472
+                $plugin->hook_feed_parsed($rss);
473
+                Debug::log(sprintf("=== %.4f (sec)", microtime(true) - $start), Debug::$LOG_VERBOSE);
474
+            }
475 475
 
476
-			Debug::log("language: $feed_language", Debug::$LOG_VERBOSE);
477
-			Debug::log("processing feed data...", Debug::$LOG_VERBOSE);
476
+            Debug::log("language: $feed_language", Debug::$LOG_VERBOSE);
477
+            Debug::log("processing feed data...", Debug::$LOG_VERBOSE);
478 478
 
479
-			if (DB_TYPE == "pgsql") {
480
-				$favicon_interval_qpart = "favicon_last_checked < NOW() - INTERVAL '12 hour'";
481
-			} else {
482
-				$favicon_interval_qpart = "favicon_last_checked < DATE_SUB(NOW(), INTERVAL 12 HOUR)";
483
-			}
479
+            if (DB_TYPE == "pgsql") {
480
+                $favicon_interval_qpart = "favicon_last_checked < NOW() - INTERVAL '12 hour'";
481
+            } else {
482
+                $favicon_interval_qpart = "favicon_last_checked < DATE_SUB(NOW(), INTERVAL 12 HOUR)";
483
+            }
484 484
 
485
-			$sth = $pdo->prepare("SELECT owner_uid,favicon_avg_color,
485
+            $sth = $pdo->prepare("SELECT owner_uid,favicon_avg_color,
486 486
 				(favicon_last_checked IS NULL OR $favicon_interval_qpart) AS
487 487
 						favicon_needs_check
488 488
 				FROM ttrss_feeds WHERE id = ?");
489
-			$sth->execute([$feed]);
489
+            $sth->execute([$feed]);
490 490
 
491
-			if ($row = $sth->fetch()) {
492
-				$favicon_needs_check = $row["favicon_needs_check"];
493
-				$favicon_avg_color = $row["favicon_avg_color"];
494
-				$owner_uid = $row["owner_uid"];
495
-			} else {
496
-				return false;
497
-			}
491
+            if ($row = $sth->fetch()) {
492
+                $favicon_needs_check = $row["favicon_needs_check"];
493
+                $favicon_avg_color = $row["favicon_avg_color"];
494
+                $owner_uid = $row["owner_uid"];
495
+            } else {
496
+                return false;
497
+            }
498 498
 
499
-			$site_url = mb_substr(rewrite_relative_url($fetch_url, clean($rss->get_link())), 0, 245);
499
+            $site_url = mb_substr(rewrite_relative_url($fetch_url, clean($rss->get_link())), 0, 245);
500 500
 
501
-			Debug::log("site_url: $site_url", Debug::$LOG_VERBOSE);
502
-			Debug::log("feed_title: " . clean($rss->get_title()), Debug::$LOG_VERBOSE);
501
+            Debug::log("site_url: $site_url", Debug::$LOG_VERBOSE);
502
+            Debug::log("feed_title: " . clean($rss->get_title()), Debug::$LOG_VERBOSE);
503 503
 
504
-			if ($favicon_needs_check || $force_refetch) {
504
+            if ($favicon_needs_check || $force_refetch) {
505 505
 
506
-				/* terrible hack: if we crash on floicon shit here, we won't check
506
+                /* terrible hack: if we crash on floicon shit here, we won't check
507 507
 				 * the icon avgcolor again (unless the icon got updated) */
508 508
 
509
-				$favicon_file = ICONS_DIR . "/$feed.ico";
510
-				$favicon_modified = @filemtime($favicon_file);
509
+                $favicon_file = ICONS_DIR . "/$feed.ico";
510
+                $favicon_modified = @filemtime($favicon_file);
511 511
 
512
-				Debug::log("checking favicon...", Debug::$LOG_VERBOSE);
512
+                Debug::log("checking favicon...", Debug::$LOG_VERBOSE);
513 513
 
514
-				RSSUtils::check_feed_favicon($site_url, $feed);
515
-				$favicon_modified_new = @filemtime($favicon_file);
514
+                RSSUtils::check_feed_favicon($site_url, $feed);
515
+                $favicon_modified_new = @filemtime($favicon_file);
516 516
 
517
-				if ($favicon_modified_new > $favicon_modified)
518
-					$favicon_avg_color = '';
517
+                if ($favicon_modified_new > $favicon_modified)
518
+                    $favicon_avg_color = '';
519 519
 
520
-				$favicon_colorstring = "";
521
-				if (file_exists($favicon_file) && function_exists("imagecreatefromstring") && $favicon_avg_color == '') {
522
-					require_once "colors.php";
520
+                $favicon_colorstring = "";
521
+                if (file_exists($favicon_file) && function_exists("imagecreatefromstring") && $favicon_avg_color == '') {
522
+                    require_once "colors.php";
523 523
 
524
-					$sth = $pdo->prepare("UPDATE ttrss_feeds SET favicon_avg_color = 'fail' WHERE
524
+                    $sth = $pdo->prepare("UPDATE ttrss_feeds SET favicon_avg_color = 'fail' WHERE
525 525
 							id = ?");
526
-					$sth->execute([$feed]);
526
+                    $sth->execute([$feed]);
527 527
 
528
-					$favicon_color = calculate_avg_color($favicon_file);
528
+                    $favicon_color = calculate_avg_color($favicon_file);
529 529
 
530
-					$favicon_colorstring = ",favicon_avg_color = " . $pdo->quote($favicon_color);
530
+                    $favicon_colorstring = ",favicon_avg_color = " . $pdo->quote($favicon_color);
531 531
 
532
-				} else if ($favicon_avg_color == 'fail') {
533
-					Debug::log("floicon failed on this file, not trying to recalculate avg color", Debug::$LOG_VERBOSE);
534
-				}
532
+                } else if ($favicon_avg_color == 'fail') {
533
+                    Debug::log("floicon failed on this file, not trying to recalculate avg color", Debug::$LOG_VERBOSE);
534
+                }
535 535
 
536
-				$sth = $pdo->prepare("UPDATE ttrss_feeds SET favicon_last_checked = NOW()
536
+                $sth = $pdo->prepare("UPDATE ttrss_feeds SET favicon_last_checked = NOW()
537 537
 					$favicon_colorstring WHERE id = ?");
538
-				$sth->execute([$feed]);
539
-			}
538
+                $sth->execute([$feed]);
539
+            }
540 540
 
541
-			Debug::log("loading filters & labels...", Debug::$LOG_VERBOSE);
541
+            Debug::log("loading filters & labels...", Debug::$LOG_VERBOSE);
542 542
 
543
-			$filters = RSSUtils::load_filters($feed, $owner_uid);
543
+            $filters = RSSUtils::load_filters($feed, $owner_uid);
544 544
 
545
-			if (Debug::get_loglevel() >= Debug::$LOG_EXTENDED) {
546
-				print_r($filters);
547
-			}
545
+            if (Debug::get_loglevel() >= Debug::$LOG_EXTENDED) {
546
+                print_r($filters);
547
+            }
548 548
 
549
-			Debug::log("" . count($filters) . " filters loaded.", Debug::$LOG_VERBOSE);
549
+            Debug::log("" . count($filters) . " filters loaded.", Debug::$LOG_VERBOSE);
550 550
 
551
-			$items = $rss->get_items();
551
+            $items = $rss->get_items();
552 552
 
553
-			if (!is_array($items)) {
554
-				Debug::log("no articles found.", Debug::$LOG_VERBOSE);
553
+            if (!is_array($items)) {
554
+                Debug::log("no articles found.", Debug::$LOG_VERBOSE);
555 555
 
556
-				$sth = $pdo->prepare("UPDATE ttrss_feeds
556
+                $sth = $pdo->prepare("UPDATE ttrss_feeds
557 557
 					SET last_updated = NOW(), last_unconditional = NOW(), last_error = '' WHERE id = ?");
558
-				$sth->execute([$feed]);
558
+                $sth->execute([$feed]);
559 559
 
560
-				return true; // no articles
561
-			}
560
+                return true; // no articles
561
+            }
562 562
 
563
-			Debug::log("processing articles...", Debug::$LOG_VERBOSE);
563
+            Debug::log("processing articles...", Debug::$LOG_VERBOSE);
564 564
 
565
-			$tstart = time();
565
+            $tstart = time();
566 566
 
567
-			foreach ($items as $item) {
568
-				$pdo->beginTransaction();
567
+            foreach ($items as $item) {
568
+                $pdo->beginTransaction();
569 569
 
570
-				if (Debug::get_loglevel() >= 3) {
571
-					print_r($item);
572
-				}
570
+                if (Debug::get_loglevel() >= 3) {
571
+                    print_r($item);
572
+                }
573 573
 
574
-				if (ini_get("max_execution_time") > 0 && time() - $tstart >= ini_get("max_execution_time") * 0.7) {
575
-					Debug::log("looks like there's too many articles to process at once, breaking out", Debug::$LOG_VERBOSE);
576
-					$pdo->commit();
577
-					break;
578
-				}
574
+                if (ini_get("max_execution_time") > 0 && time() - $tstart >= ini_get("max_execution_time") * 0.7) {
575
+                    Debug::log("looks like there's too many articles to process at once, breaking out", Debug::$LOG_VERBOSE);
576
+                    $pdo->commit();
577
+                    break;
578
+                }
579 579
 
580
-				$entry_guid = strip_tags($item->get_id());
581
-				if (!$entry_guid) $entry_guid = strip_tags($item->get_link());
582
-				if (!$entry_guid) $entry_guid = RSSUtils::make_guid_from_title($item->get_title());
580
+                $entry_guid = strip_tags($item->get_id());
581
+                if (!$entry_guid) $entry_guid = strip_tags($item->get_link());
582
+                if (!$entry_guid) $entry_guid = RSSUtils::make_guid_from_title($item->get_title());
583 583
 
584
-				if (!$entry_guid) {
585
-					$pdo->commit();
586
-					continue;
587
-				}
584
+                if (!$entry_guid) {
585
+                    $pdo->commit();
586
+                    continue;
587
+                }
588 588
 
589
-				$entry_guid = "$owner_uid,$entry_guid";
589
+                $entry_guid = "$owner_uid,$entry_guid";
590 590
 
591
-				$entry_guid_hashed = 'SHA1:' . sha1($entry_guid);
591
+                $entry_guid_hashed = 'SHA1:' . sha1($entry_guid);
592 592
 
593
-				Debug::log("guid $entry_guid / $entry_guid_hashed", Debug::$LOG_VERBOSE);
593
+                Debug::log("guid $entry_guid / $entry_guid_hashed", Debug::$LOG_VERBOSE);
594 594
 
595
-				$entry_timestamp = (int)$item->get_date();
595
+                $entry_timestamp = (int)$item->get_date();
596 596
 
597
-				Debug::log("orig date: " . $item->get_date(), Debug::$LOG_VERBOSE);
597
+                Debug::log("orig date: " . $item->get_date(), Debug::$LOG_VERBOSE);
598 598
 
599
-				$entry_title = strip_tags($item->get_title());
599
+                $entry_title = strip_tags($item->get_title());
600 600
 
601
-				$entry_link = rewrite_relative_url($site_url, clean($item->get_link()));
601
+                $entry_link = rewrite_relative_url($site_url, clean($item->get_link()));
602 602
 
603
-				$entry_language = mb_substr(trim($item->get_language()), 0, 2);
603
+                $entry_language = mb_substr(trim($item->get_language()), 0, 2);
604 604
 
605
-				Debug::log("title $entry_title", Debug::$LOG_VERBOSE);
606
-				Debug::log("link $entry_link", Debug::$LOG_VERBOSE);
607
-				Debug::log("language $entry_language", Debug::$LOG_VERBOSE);
605
+                Debug::log("title $entry_title", Debug::$LOG_VERBOSE);
606
+                Debug::log("link $entry_link", Debug::$LOG_VERBOSE);
607
+                Debug::log("language $entry_language", Debug::$LOG_VERBOSE);
608 608
 
609
-				if (!$entry_title) $entry_title = date("Y-m-d H:i:s", $entry_timestamp);;
609
+                if (!$entry_title) $entry_title = date("Y-m-d H:i:s", $entry_timestamp);;
610 610
 
611
-				$entry_content = $item->get_content();
612
-				if (!$entry_content) $entry_content = $item->get_description();
611
+                $entry_content = $item->get_content();
612
+                if (!$entry_content) $entry_content = $item->get_description();
613 613
 
614
-				if (Debug::get_loglevel() >= 3) {
615
-					print "content: ";
616
-					print htmlspecialchars($entry_content);
617
-					print "\n";
618
-				}
614
+                if (Debug::get_loglevel() >= 3) {
615
+                    print "content: ";
616
+                    print htmlspecialchars($entry_content);
617
+                    print "\n";
618
+                }
619 619
 
620
-				$entry_comments = mb_substr(strip_tags($item->get_comments_url()), 0, 245);
621
-				$num_comments = (int) $item->get_comments_count();
620
+                $entry_comments = mb_substr(strip_tags($item->get_comments_url()), 0, 245);
621
+                $num_comments = (int) $item->get_comments_count();
622 622
 
623
-				$entry_author = strip_tags($item->get_author());
624
-				$entry_guid = mb_substr($entry_guid, 0, 245);
623
+                $entry_author = strip_tags($item->get_author());
624
+                $entry_guid = mb_substr($entry_guid, 0, 245);
625 625
 
626
-				Debug::log("author $entry_author", Debug::$LOG_VERBOSE);
627
-				Debug::log("looking for tags...", Debug::$LOG_VERBOSE);
626
+                Debug::log("author $entry_author", Debug::$LOG_VERBOSE);
627
+                Debug::log("looking for tags...", Debug::$LOG_VERBOSE);
628 628
 
629
-				$entry_tags = $item->get_categories();
630
-				Debug::log("tags found: " . join(", ", $entry_tags), Debug::$LOG_VERBOSE);
629
+                $entry_tags = $item->get_categories();
630
+                Debug::log("tags found: " . join(", ", $entry_tags), Debug::$LOG_VERBOSE);
631 631
 
632
-				Debug::log("done collecting data.", Debug::$LOG_VERBOSE);
632
+                Debug::log("done collecting data.", Debug::$LOG_VERBOSE);
633 633
 
634
-				$sth = $pdo->prepare("SELECT id, content_hash, lang FROM ttrss_entries
634
+                $sth = $pdo->prepare("SELECT id, content_hash, lang FROM ttrss_entries
635 635
 					WHERE guid = ? OR guid = ?");
636
-				$sth->execute([$entry_guid, $entry_guid_hashed]);
637
-
638
-				if ($row = $sth->fetch()) {
639
-					$base_entry_id = $row["id"];
640
-					$entry_stored_hash = $row["content_hash"];
641
-					$article_labels = Article::get_article_labels($base_entry_id, $owner_uid);
642
-
643
-					$existing_tags = Article::get_article_tags($base_entry_id, $owner_uid);
644
-					$entry_tags = array_unique(array_merge($entry_tags, $existing_tags));
645
-				} else {
646
-					$base_entry_id = false;
647
-					$entry_stored_hash = "";
648
-					$article_labels = array();
649
-				}
650
-
651
-				$article = array("owner_uid" => $owner_uid, // read only
652
-					"guid" => $entry_guid, // read only
653
-					"guid_hashed" => $entry_guid_hashed, // read only
654
-					"title" => $entry_title,
655
-					"content" => $entry_content,
656
-					"link" => $entry_link,
657
-					"labels" => $article_labels, // current limitation: can add labels to article, can't remove them
658
-					"tags" => $entry_tags,
659
-					"author" => $entry_author,
660
-					"force_catchup" => false, // ugly hack for the time being
661
-					"score_modifier" => 0, // no previous value, plugin should recalculate score modifier based on content if needed
662
-					"language" => $entry_language,
663
-					"timestamp" => $entry_timestamp,
664
-					"num_comments" => $num_comments,
665
-					"feed" => array("id" => $feed,
666
-						"fetch_url" => $fetch_url,
667
-						"site_url" => $site_url,
668
-						"cache_images" => $cache_images)
669
-				);
670
-
671
-				$entry_plugin_data = "";
672
-				$entry_current_hash = RSSUtils::calculate_article_hash($article, $pluginhost);
673
-
674
-				Debug::log("article hash: $entry_current_hash [stored=$entry_stored_hash]", Debug::$LOG_VERBOSE);
675
-
676
-				if ($entry_current_hash == $entry_stored_hash && !isset($_REQUEST["force_rehash"])) {
677
-					Debug::log("stored article seems up to date [IID: $base_entry_id], updating timestamp only", Debug::$LOG_VERBOSE);
678
-
679
-					// we keep encountering the entry in feeds, so we need to
680
-					// update date_updated column so that we don't get horrible
681
-					// dupes when the entry gets purged and reinserted again e.g.
682
-					// in the case of SLOW SLOW OMG SLOW updating feeds
683
-
684
-					$sth = $pdo->prepare("UPDATE ttrss_entries SET date_updated = NOW()
636
+                $sth->execute([$entry_guid, $entry_guid_hashed]);
637
+
638
+                if ($row = $sth->fetch()) {
639
+                    $base_entry_id = $row["id"];
640
+                    $entry_stored_hash = $row["content_hash"];
641
+                    $article_labels = Article::get_article_labels($base_entry_id, $owner_uid);
642
+
643
+                    $existing_tags = Article::get_article_tags($base_entry_id, $owner_uid);
644
+                    $entry_tags = array_unique(array_merge($entry_tags, $existing_tags));
645
+                } else {
646
+                    $base_entry_id = false;
647
+                    $entry_stored_hash = "";
648
+                    $article_labels = array();
649
+                }
650
+
651
+                $article = array("owner_uid" => $owner_uid, // read only
652
+                    "guid" => $entry_guid, // read only
653
+                    "guid_hashed" => $entry_guid_hashed, // read only
654
+                    "title" => $entry_title,
655
+                    "content" => $entry_content,
656
+                    "link" => $entry_link,
657
+                    "labels" => $article_labels, // current limitation: can add labels to article, can't remove them
658
+                    "tags" => $entry_tags,
659
+                    "author" => $entry_author,
660
+                    "force_catchup" => false, // ugly hack for the time being
661
+                    "score_modifier" => 0, // no previous value, plugin should recalculate score modifier based on content if needed
662
+                    "language" => $entry_language,
663
+                    "timestamp" => $entry_timestamp,
664
+                    "num_comments" => $num_comments,
665
+                    "feed" => array("id" => $feed,
666
+                        "fetch_url" => $fetch_url,
667
+                        "site_url" => $site_url,
668
+                        "cache_images" => $cache_images)
669
+                );
670
+
671
+                $entry_plugin_data = "";
672
+                $entry_current_hash = RSSUtils::calculate_article_hash($article, $pluginhost);
673
+
674
+                Debug::log("article hash: $entry_current_hash [stored=$entry_stored_hash]", Debug::$LOG_VERBOSE);
675
+
676
+                if ($entry_current_hash == $entry_stored_hash && !isset($_REQUEST["force_rehash"])) {
677
+                    Debug::log("stored article seems up to date [IID: $base_entry_id], updating timestamp only", Debug::$LOG_VERBOSE);
678
+
679
+                    // we keep encountering the entry in feeds, so we need to
680
+                    // update date_updated column so that we don't get horrible
681
+                    // dupes when the entry gets purged and reinserted again e.g.
682
+                    // in the case of SLOW SLOW OMG SLOW updating feeds
683
+
684
+                    $sth = $pdo->prepare("UPDATE ttrss_entries SET date_updated = NOW()
685 685
 						WHERE id = ?");
686
-					$sth->execute([$base_entry_id]);
686
+                    $sth->execute([$base_entry_id]);
687 687
 
688
-					$pdo->commit();
689
-					continue;
690
-				}
688
+                    $pdo->commit();
689
+                    continue;
690
+                }
691 691
 
692
-				Debug::log("hash differs, applying plugin filters:", Debug::$LOG_VERBOSE);
692
+                Debug::log("hash differs, applying plugin filters:", Debug::$LOG_VERBOSE);
693 693
 
694
-				foreach ($pluginhost->get_hooks(PluginHost::HOOK_ARTICLE_FILTER) as $plugin) {
695
-					Debug::log("... " . get_class($plugin), Debug::$LOG_VERBOSE);
694
+                foreach ($pluginhost->get_hooks(PluginHost::HOOK_ARTICLE_FILTER) as $plugin) {
695
+                    Debug::log("... " . get_class($plugin), Debug::$LOG_VERBOSE);
696 696
 
697
-					$start = microtime(true);
698
-					$article = $plugin->hook_article_filter($article);
697
+                    $start = microtime(true);
698
+                    $article = $plugin->hook_article_filter($article);
699 699
 
700
-					Debug::log(sprintf("=== %.4f (sec)", microtime(true) - $start), Debug::$LOG_VERBOSE);
700
+                    Debug::log(sprintf("=== %.4f (sec)", microtime(true) - $start), Debug::$LOG_VERBOSE);
701 701
 
702
-					$entry_plugin_data .= mb_strtolower(get_class($plugin)) . ",";
703
-				}
702
+                    $entry_plugin_data .= mb_strtolower(get_class($plugin)) . ",";
703
+                }
704 704
 
705 705
                 if (Debug::get_loglevel() >= 3) {
706
-					print "processed content: ";
707
-					print htmlspecialchars($article["content"]);
708
-					print "\n";
709
-				}
706
+                    print "processed content: ";
707
+                    print htmlspecialchars($article["content"]);
708
+                    print "\n";
709
+                }
710 710
 
711
-				Debug::log("plugin data: $entry_plugin_data", Debug::$LOG_VERBOSE);
711
+                Debug::log("plugin data: $entry_plugin_data", Debug::$LOG_VERBOSE);
712 712
 
713
-				// Workaround: 4-byte unicode requires utf8mb4 in MySQL. See https://tt-rss.org/forum/viewtopic.php?f=1&t=3377&p=20077#p20077
714
-				if (DB_TYPE == "mysql" && MYSQL_CHARSET != "UTF8MB4") {
715
-					foreach ($article as $k => $v) {
716
-						// i guess we'll have to take the risk of 4byte unicode labels & tags here
717
-						if (is_string($article[$k])) {
718
-							$article[$k] = RSSUtils::strip_utf8mb4($v);
719
-						}
720
-					}
721
-				}
713
+                // Workaround: 4-byte unicode requires utf8mb4 in MySQL. See https://tt-rss.org/forum/viewtopic.php?f=1&t=3377&p=20077#p20077
714
+                if (DB_TYPE == "mysql" && MYSQL_CHARSET != "UTF8MB4") {
715
+                    foreach ($article as $k => $v) {
716
+                        // i guess we'll have to take the risk of 4byte unicode labels & tags here
717
+                        if (is_string($article[$k])) {
718
+                            $article[$k] = RSSUtils::strip_utf8mb4($v);
719
+                        }
720
+                    }
721
+                }
722 722
 
723
-				/* Collect article tags here so we could filter by them: */
723
+                /* Collect article tags here so we could filter by them: */
724 724
 
725
-				$matched_rules = [];
726
-				$matched_filters = [];
725
+                $matched_rules = [];
726
+                $matched_filters = [];
727 727
 
728
-				$article_filters = RSSUtils::get_article_filters($filters, $article["title"],
729
-					$article["content"], $article["link"], $article["author"],
730
-					$article["tags"], $matched_rules, $matched_filters);
728
+                $article_filters = RSSUtils::get_article_filters($filters, $article["title"],
729
+                    $article["content"], $article["link"], $article["author"],
730
+                    $article["tags"], $matched_rules, $matched_filters);
731 731
 
732
-				// $article_filters should be renamed to something like $filter_actions; actual filter objects are in $matched_filters
733
-				foreach ($pluginhost->get_hooks(PluginHost::HOOK_FILTER_TRIGGERED) as $plugin) {
734
-					$plugin->hook_filter_triggered($feed, $owner_uid, $article, $matched_filters, $matched_rules, $article_filters);
735
-				}
732
+                // $article_filters should be renamed to something like $filter_actions; actual filter objects are in $matched_filters
733
+                foreach ($pluginhost->get_hooks(PluginHost::HOOK_FILTER_TRIGGERED) as $plugin) {
734
+                    $plugin->hook_filter_triggered($feed, $owner_uid, $article, $matched_filters, $matched_rules, $article_filters);
735
+                }
736 736
 
737
-				$matched_filter_ids = array_map(function($f) { return $f['id']; }, $matched_filters);
737
+                $matched_filter_ids = array_map(function($f) { return $f['id']; }, $matched_filters);
738 738
 
739
-				if (count($matched_filter_ids) > 0) {
740
-					$filter_ids_qmarks = arr_qmarks($matched_filter_ids);
739
+                if (count($matched_filter_ids) > 0) {
740
+                    $filter_ids_qmarks = arr_qmarks($matched_filter_ids);
741 741
 
742
-					$fsth = $pdo->prepare("UPDATE ttrss_filters2 SET last_triggered = NOW() WHERE
742
+                    $fsth = $pdo->prepare("UPDATE ttrss_filters2 SET last_triggered = NOW() WHERE
743 743
 							   id IN ($filter_ids_qmarks) AND owner_uid = ?");
744 744
 
745
-					$fsth->execute(array_merge($matched_filter_ids, [$owner_uid]));
746
-				}
745
+                    $fsth->execute(array_merge($matched_filter_ids, [$owner_uid]));
746
+                }
747 747
 
748
-				if (Debug::get_loglevel() >= Debug::$LOG_EXTENDED) {
749
-					Debug::log("matched filters: ", Debug::$LOG_VERBOSE);
748
+                if (Debug::get_loglevel() >= Debug::$LOG_EXTENDED) {
749
+                    Debug::log("matched filters: ", Debug::$LOG_VERBOSE);
750 750
 
751
-					if (count($matched_filters != 0)) {
752
-						print_r($matched_filters);
753
-					}
751
+                    if (count($matched_filters != 0)) {
752
+                        print_r($matched_filters);
753
+                    }
754 754
 
755
-					Debug::log("matched filter rules: ", Debug::$LOG_VERBOSE);
755
+                    Debug::log("matched filter rules: ", Debug::$LOG_VERBOSE);
756 756
 
757
-					if (count($matched_rules) != 0) {
758
-						print_r($matched_rules);
759
-					}
757
+                    if (count($matched_rules) != 0) {
758
+                        print_r($matched_rules);
759
+                    }
760 760
 
761
-					Debug::log("filter actions: ", Debug::$LOG_VERBOSE);
761
+                    Debug::log("filter actions: ", Debug::$LOG_VERBOSE);
762 762
 
763
-					if (count($article_filters) != 0) {
764
-						print_r($article_filters);
765
-					}
766
-				}
763
+                    if (count($article_filters) != 0) {
764
+                        print_r($article_filters);
765
+                    }
766
+                }
767 767
 
768
-				$plugin_filter_names = RSSUtils::find_article_filters($article_filters, "plugin");
769
-				$plugin_filter_actions = $pluginhost->get_filter_actions();
768
+                $plugin_filter_names = RSSUtils::find_article_filters($article_filters, "plugin");
769
+                $plugin_filter_actions = $pluginhost->get_filter_actions();
770 770
 
771
-				if (count($plugin_filter_names) > 0) {
772
-					Debug::log("applying plugin filter actions...", Debug::$LOG_VERBOSE);
771
+                if (count($plugin_filter_names) > 0) {
772
+                    Debug::log("applying plugin filter actions...", Debug::$LOG_VERBOSE);
773 773
 
774
-					foreach ($plugin_filter_names as $pfn) {
775
-						list($pfclass,$pfaction) = explode(":", $pfn["param"]);
774
+                    foreach ($plugin_filter_names as $pfn) {
775
+                        list($pfclass,$pfaction) = explode(":", $pfn["param"]);
776 776
 
777
-						if (isset($plugin_filter_actions[$pfclass])) {
778
-							$plugin = $pluginhost->get_plugin($pfclass);
777
+                        if (isset($plugin_filter_actions[$pfclass])) {
778
+                            $plugin = $pluginhost->get_plugin($pfclass);
779 779
 
780
-							Debug::log("... $pfclass: $pfaction", Debug::$LOG_VERBOSE);
780
+                            Debug::log("... $pfclass: $pfaction", Debug::$LOG_VERBOSE);
781 781
 
782
-							if ($plugin) {
783
-								$start = microtime(true);
784
-								$article = $plugin->hook_article_filter_action($article, $pfaction);
782
+                            if ($plugin) {
783
+                                $start = microtime(true);
784
+                                $article = $plugin->hook_article_filter_action($article, $pfaction);
785 785
 
786
-								Debug::log(sprintf("=== %.4f (sec)", microtime(true) - $start), Debug::$LOG_VERBOSE);
787
-							} else {
788
-								Debug::log("??? $pfclass: plugin object not found.", Debug::$LOG_VERBOSE);
789
-							}
790
-						} else {
791
-							Debug::log("??? $pfclass: filter plugin not registered.", Debug::$LOG_VERBOSE);
792
-						}
793
-					}
794
-				}
786
+                                Debug::log(sprintf("=== %.4f (sec)", microtime(true) - $start), Debug::$LOG_VERBOSE);
787
+                            } else {
788
+                                Debug::log("??? $pfclass: plugin object not found.", Debug::$LOG_VERBOSE);
789
+                            }
790
+                        } else {
791
+                            Debug::log("??? $pfclass: filter plugin not registered.", Debug::$LOG_VERBOSE);
792
+                        }
793
+                    }
794
+                }
795 795
 
796
-				$entry_tags = $article["tags"];
797
-				$entry_title = strip_tags($article["title"]);
798
-				$entry_author = mb_substr(strip_tags($article["author"]), 0, 245);
799
-				$entry_link = strip_tags($article["link"]);
800
-				$entry_content = $article["content"]; // escaped below
801
-				$entry_force_catchup = $article["force_catchup"];
802
-				$article_labels = $article["labels"];
803
-				$entry_score_modifier = (int) $article["score_modifier"];
804
-				$entry_language = $article["language"];
805
-				$entry_timestamp = $article["timestamp"];
806
-				$num_comments = $article["num_comments"];
796
+                $entry_tags = $article["tags"];
797
+                $entry_title = strip_tags($article["title"]);
798
+                $entry_author = mb_substr(strip_tags($article["author"]), 0, 245);
799
+                $entry_link = strip_tags($article["link"]);
800
+                $entry_content = $article["content"]; // escaped below
801
+                $entry_force_catchup = $article["force_catchup"];
802
+                $article_labels = $article["labels"];
803
+                $entry_score_modifier = (int) $article["score_modifier"];
804
+                $entry_language = $article["language"];
805
+                $entry_timestamp = $article["timestamp"];
806
+                $num_comments = $article["num_comments"];
807 807
 
808
-				if ($entry_timestamp == -1 || !$entry_timestamp || $entry_timestamp > time()) {
809
-					$entry_timestamp = time();
810
-				}
808
+                if ($entry_timestamp == -1 || !$entry_timestamp || $entry_timestamp > time()) {
809
+                    $entry_timestamp = time();
810
+                }
811 811
 
812
-				$entry_timestamp_fmt = strftime("%Y/%m/%d %H:%M:%S", $entry_timestamp);
812
+                $entry_timestamp_fmt = strftime("%Y/%m/%d %H:%M:%S", $entry_timestamp);
813 813
 
814
-				Debug::log("date $entry_timestamp [$entry_timestamp_fmt]", Debug::$LOG_VERBOSE);
815
-				Debug::log("num_comments: $num_comments", Debug::$LOG_VERBOSE);
814
+                Debug::log("date $entry_timestamp [$entry_timestamp_fmt]", Debug::$LOG_VERBOSE);
815
+                Debug::log("num_comments: $num_comments", Debug::$LOG_VERBOSE);
816 816
 
817
-				if (Debug::get_loglevel() >= Debug::$LOG_EXTENDED) {
818
-					Debug::log("article labels:", Debug::$LOG_VERBOSE);
817
+                if (Debug::get_loglevel() >= Debug::$LOG_EXTENDED) {
818
+                    Debug::log("article labels:", Debug::$LOG_VERBOSE);
819 819
 
820
-					if (count($article_labels) != 0) {
821
-						print_r($article_labels);
822
-					}
823
-				}
820
+                    if (count($article_labels) != 0) {
821
+                        print_r($article_labels);
822
+                    }
823
+                }
824 824
 
825
-				Debug::log("force catchup: $entry_force_catchup", Debug::$LOG_VERBOSE);
825
+                Debug::log("force catchup: $entry_force_catchup", Debug::$LOG_VERBOSE);
826 826
 
827
-				if ($cache_images)
828
-					RSSUtils::cache_media($entry_content, $site_url);
827
+                if ($cache_images)
828
+                    RSSUtils::cache_media($entry_content, $site_url);
829 829
 
830
-				$csth = $pdo->prepare("SELECT id FROM ttrss_entries
830
+                $csth = $pdo->prepare("SELECT id FROM ttrss_entries
831 831
 					WHERE guid = ? OR guid = ?");
832
-				$csth->execute([$entry_guid, $entry_guid_hashed]);
832
+                $csth->execute([$entry_guid, $entry_guid_hashed]);
833 833
 
834
-				if (!$row = $csth->fetch()) {
834
+                if (!$row = $csth->fetch()) {
835 835
 
836
-					Debug::log("base guid [$entry_guid or $entry_guid_hashed] not found, creating...", Debug::$LOG_VERBOSE);
836
+                    Debug::log("base guid [$entry_guid or $entry_guid_hashed] not found, creating...", Debug::$LOG_VERBOSE);
837 837
 
838
-					// base post entry does not exist, create it
838
+                    // base post entry does not exist, create it
839 839
 
840
-					$usth = $pdo->prepare(
841
-						"INSERT INTO ttrss_entries
840
+                    $usth = $pdo->prepare(
841
+                        "INSERT INTO ttrss_entries
842 842
 							(title,
843 843
 							guid,
844 844
 							link,
@@ -859,110 +859,110 @@  discard block
 block discarded – undo
859 859
 							NOW(),
860 860
 							?, ?, ?, ?,	?, ?)");
861 861
 
862
-						$usth->execute([$entry_title,
863
-							$entry_guid_hashed,
864
-							$entry_link,
865
-							$entry_timestamp_fmt,
866
-							"$entry_content",
867
-							$entry_current_hash,
868
-							$date_feed_processed,
869
-							$entry_comments,
870
-							(int)$num_comments,
871
-							$entry_plugin_data,
872
-							"$entry_language",
873
-							"$entry_author"]);
862
+                        $usth->execute([$entry_title,
863
+                            $entry_guid_hashed,
864
+                            $entry_link,
865
+                            $entry_timestamp_fmt,
866
+                            "$entry_content",
867
+                            $entry_current_hash,
868
+                            $date_feed_processed,
869
+                            $entry_comments,
870
+                            (int)$num_comments,
871
+                            $entry_plugin_data,
872
+                            "$entry_language",
873
+                            "$entry_author"]);
874 874
 
875
-				}
875
+                }
876 876
 
877
-				$csth->execute([$entry_guid, $entry_guid_hashed]);
877
+                $csth->execute([$entry_guid, $entry_guid_hashed]);
878 878
 
879
-				$entry_ref_id = 0;
880
-				$entry_int_id = 0;
879
+                $entry_ref_id = 0;
880
+                $entry_int_id = 0;
881 881
 
882
-				if ($row = $csth->fetch()) {
882
+                if ($row = $csth->fetch()) {
883 883
 
884
-					Debug::log("base guid found, checking for user record", Debug::$LOG_VERBOSE);
884
+                    Debug::log("base guid found, checking for user record", Debug::$LOG_VERBOSE);
885 885
 
886
-					$ref_id = $row['id'];
887
-					$entry_ref_id = $ref_id;
886
+                    $ref_id = $row['id'];
887
+                    $entry_ref_id = $ref_id;
888 888
 
889
-					if (RSSUtils::find_article_filter($article_filters, "filter")) {
890
-						Debug::log("article is filtered out, nothing to do.", Debug::$LOG_VERBOSE);
891
-						$pdo->commit();
892
-						continue;
893
-					}
889
+                    if (RSSUtils::find_article_filter($article_filters, "filter")) {
890
+                        Debug::log("article is filtered out, nothing to do.", Debug::$LOG_VERBOSE);
891
+                        $pdo->commit();
892
+                        continue;
893
+                    }
894 894
 
895
-					$score = RSSUtils::calculate_article_score($article_filters) + $entry_score_modifier;
895
+                    $score = RSSUtils::calculate_article_score($article_filters) + $entry_score_modifier;
896 896
 
897
-					Debug::log("initial score: $score [including plugin modifier: $entry_score_modifier]", Debug::$LOG_VERBOSE);
897
+                    Debug::log("initial score: $score [including plugin modifier: $entry_score_modifier]", Debug::$LOG_VERBOSE);
898 898
 
899
-					// check for user post link to main table
899
+                    // check for user post link to main table
900 900
 
901
-					$sth = $pdo->prepare("SELECT ref_id, int_id FROM ttrss_user_entries WHERE
901
+                    $sth = $pdo->prepare("SELECT ref_id, int_id FROM ttrss_user_entries WHERE
902 902
 							ref_id = ? AND owner_uid = ?");
903
-					$sth->execute([$ref_id, $owner_uid]);
904
-
905
-					// okay it doesn't exist - create user entry
906
-					if ($row = $sth->fetch()) {
907
-						$entry_ref_id = $row["ref_id"];
908
-						$entry_int_id = $row["int_id"];
909
-
910
-						Debug::log("user record FOUND: RID: $entry_ref_id, IID: $entry_int_id", Debug::$LOG_VERBOSE);
911
-					} else {
912
-
913
-						Debug::log("user record not found, creating...", Debug::$LOG_VERBOSE);
914
-
915
-						if ($score >= -500 && !RSSUtils::find_article_filter($article_filters, 'catchup') && !$entry_force_catchup) {
916
-							$unread = 1;
917
-							$last_read_qpart = null;
918
-						} else {
919
-							$unread = 0;
920
-							$last_read_qpart = date("Y-m-d H:i"); // we can't use NOW() here because it gets quoted
921
-						}
922
-
923
-						if (RSSUtils::find_article_filter($article_filters, 'mark') || $score > 1000) {
924
-							$marked = 1;
925
-						} else {
926
-							$marked = 0;
927
-						}
928
-
929
-						if (RSSUtils::find_article_filter($article_filters, 'publish')) {
930
-							$published = 1;
931
-						} else {
932
-							$published = 0;
933
-						}
934
-
935
-						$last_marked = ($marked == 1) ? 'NOW()' : 'NULL';
936
-						$last_published = ($published == 1) ? 'NOW()' : 'NULL';
937
-
938
-						$sth = $pdo->prepare(
939
-							"INSERT INTO ttrss_user_entries
903
+                    $sth->execute([$ref_id, $owner_uid]);
904
+
905
+                    // okay it doesn't exist - create user entry
906
+                    if ($row = $sth->fetch()) {
907
+                        $entry_ref_id = $row["ref_id"];
908
+                        $entry_int_id = $row["int_id"];
909
+
910
+                        Debug::log("user record FOUND: RID: $entry_ref_id, IID: $entry_int_id", Debug::$LOG_VERBOSE);
911
+                    } else {
912
+
913
+                        Debug::log("user record not found, creating...", Debug::$LOG_VERBOSE);
914
+
915
+                        if ($score >= -500 && !RSSUtils::find_article_filter($article_filters, 'catchup') && !$entry_force_catchup) {
916
+                            $unread = 1;
917
+                            $last_read_qpart = null;
918
+                        } else {
919
+                            $unread = 0;
920
+                            $last_read_qpart = date("Y-m-d H:i"); // we can't use NOW() here because it gets quoted
921
+                        }
922
+
923
+                        if (RSSUtils::find_article_filter($article_filters, 'mark') || $score > 1000) {
924
+                            $marked = 1;
925
+                        } else {
926
+                            $marked = 0;
927
+                        }
928
+
929
+                        if (RSSUtils::find_article_filter($article_filters, 'publish')) {
930
+                            $published = 1;
931
+                        } else {
932
+                            $published = 0;
933
+                        }
934
+
935
+                        $last_marked = ($marked == 1) ? 'NOW()' : 'NULL';
936
+                        $last_published = ($published == 1) ? 'NOW()' : 'NULL';
937
+
938
+                        $sth = $pdo->prepare(
939
+                            "INSERT INTO ttrss_user_entries
940 940
 								(ref_id, owner_uid, feed_id, unread, last_read, marked,
941 941
 								published, score, tag_cache, label_cache, uuid,
942 942
 								last_marked, last_published)
943 943
 							VALUES (?, ?, ?, ?, ?, ?, ?, ?, '', '', '', ".$last_marked.", ".$last_published.")");
944 944
 
945
-						$sth->execute([$ref_id, $owner_uid, $feed, $unread, $last_read_qpart, $marked,
946
-							$published, $score]);
945
+                        $sth->execute([$ref_id, $owner_uid, $feed, $unread, $last_read_qpart, $marked,
946
+                            $published, $score]);
947 947
 
948
-						$sth = $pdo->prepare("SELECT int_id FROM ttrss_user_entries WHERE
948
+                        $sth = $pdo->prepare("SELECT int_id FROM ttrss_user_entries WHERE
949 949
 								ref_id = ? AND owner_uid = ? AND
950 950
 								feed_id = ? LIMIT 1");
951 951
 
952
-						$sth->execute([$ref_id, $owner_uid, $feed]);
952
+                        $sth->execute([$ref_id, $owner_uid, $feed]);
953 953
 
954
-						if ($row = $sth->fetch())
955
-							$entry_int_id = $row['int_id'];
956
-					}
954
+                        if ($row = $sth->fetch())
955
+                            $entry_int_id = $row['int_id'];
956
+                    }
957 957
 
958
-					Debug::log("resulting RID: $entry_ref_id, IID: $entry_int_id", Debug::$LOG_VERBOSE);
958
+                    Debug::log("resulting RID: $entry_ref_id, IID: $entry_int_id", Debug::$LOG_VERBOSE);
959 959
 
960
-					if (DB_TYPE == "pgsql")
961
-						$tsvector_qpart = "tsvector_combined = to_tsvector(:ts_lang, :ts_content),";
962
-					else
963
-						$tsvector_qpart = "";
960
+                    if (DB_TYPE == "pgsql")
961
+                        $tsvector_qpart = "tsvector_combined = to_tsvector(:ts_lang, :ts_content),";
962
+                    else
963
+                        $tsvector_qpart = "";
964 964
 
965
-					$sth = $pdo->prepare("UPDATE ttrss_entries
965
+                    $sth = $pdo->prepare("UPDATE ttrss_entries
966 966
 						SET title = :title,
967 967
 							$tsvector_qpart
968 968
 							content = :content,
@@ -975,634 +975,634 @@  discard block
 block discarded – undo
975 975
 							lang = :lang
976 976
 						WHERE id = :id");
977 977
 
978
-					$params = [":title" => $entry_title,
979
-						":content" => "$entry_content",
980
-						":content_hash" => $entry_current_hash,
981
-						":updated" => $entry_timestamp_fmt,
982
-						":num_comments" => (int)$num_comments,
983
-						":plugin_data" => $entry_plugin_data,
984
-						":author" => "$entry_author",
985
-						":lang" => $entry_language,
986
-						":id" => $ref_id];
987
-
988
-					if (DB_TYPE == "pgsql") {
989
-						$params[":ts_lang"] = $feed_language;
990
-						$params[":ts_content"] = mb_substr(strip_tags($entry_title . " " . $entry_content), 0, 900000);
991
-					}
992
-
993
-					$sth->execute($params);
994
-
995
-					// update aux data
996
-					$sth = $pdo->prepare("UPDATE ttrss_user_entries
978
+                    $params = [":title" => $entry_title,
979
+                        ":content" => "$entry_content",
980
+                        ":content_hash" => $entry_current_hash,
981
+                        ":updated" => $entry_timestamp_fmt,
982
+                        ":num_comments" => (int)$num_comments,
983
+                        ":plugin_data" => $entry_plugin_data,
984
+                        ":author" => "$entry_author",
985
+                        ":lang" => $entry_language,
986
+                        ":id" => $ref_id];
987
+
988
+                    if (DB_TYPE == "pgsql") {
989
+                        $params[":ts_lang"] = $feed_language;
990
+                        $params[":ts_content"] = mb_substr(strip_tags($entry_title . " " . $entry_content), 0, 900000);
991
+                    }
992
+
993
+                    $sth->execute($params);
994
+
995
+                    // update aux data
996
+                    $sth = $pdo->prepare("UPDATE ttrss_user_entries
997 997
 							SET score = ? WHERE ref_id = ?");
998
-					$sth->execute([$score, $ref_id]);
998
+                    $sth->execute([$score, $ref_id]);
999 999
 
1000
-					if ($mark_unread_on_update &&
1001
-						!$entry_force_catchup &&
1002
-						!RSSUtils::find_article_filter($article_filters, 'catchup')) {
1000
+                    if ($mark_unread_on_update &&
1001
+                        !$entry_force_catchup &&
1002
+                        !RSSUtils::find_article_filter($article_filters, 'catchup')) {
1003 1003
 
1004
-						Debug::log("article updated, marking unread as requested.", Debug::$LOG_VERBOSE);
1004
+                        Debug::log("article updated, marking unread as requested.", Debug::$LOG_VERBOSE);
1005 1005
 
1006
-						$sth = $pdo->prepare("UPDATE ttrss_user_entries
1006
+                        $sth = $pdo->prepare("UPDATE ttrss_user_entries
1007 1007
 							SET last_read = null, unread = true WHERE ref_id = ?");
1008
-						$sth->execute([$ref_id]);
1009
-					} else {
1010
-						Debug::log("article updated, but we're forbidden to mark it unread.", Debug::$LOG_VERBOSE);
1011
-					}
1012
-				}
1008
+                        $sth->execute([$ref_id]);
1009
+                    } else {
1010
+                        Debug::log("article updated, but we're forbidden to mark it unread.", Debug::$LOG_VERBOSE);
1011
+                    }
1012
+                }
1013 1013
 
1014
-				Debug::log("assigning labels [other]...", Debug::$LOG_VERBOSE);
1014
+                Debug::log("assigning labels [other]...", Debug::$LOG_VERBOSE);
1015 1015
 
1016
-				foreach ($article_labels as $label) {
1017
-					Labels::add_article($entry_ref_id, $label[1], $owner_uid);
1018
-				}
1016
+                foreach ($article_labels as $label) {
1017
+                    Labels::add_article($entry_ref_id, $label[1], $owner_uid);
1018
+                }
1019 1019
 
1020
-				Debug::log("assigning labels [filters]...", Debug::$LOG_VERBOSE);
1020
+                Debug::log("assigning labels [filters]...", Debug::$LOG_VERBOSE);
1021 1021
 
1022
-				RSSUtils::assign_article_to_label_filters($entry_ref_id, $article_filters,
1023
-					$owner_uid, $article_labels);
1022
+                RSSUtils::assign_article_to_label_filters($entry_ref_id, $article_filters,
1023
+                    $owner_uid, $article_labels);
1024 1024
 
1025
-				Debug::log("looking for enclosures...", Debug::$LOG_VERBOSE);
1025
+                Debug::log("looking for enclosures...", Debug::$LOG_VERBOSE);
1026 1026
 
1027
-				// enclosures
1027
+                // enclosures
1028 1028
 
1029
-				$enclosures = array();
1029
+                $enclosures = array();
1030 1030
 
1031
-				$encs = $item->get_enclosures();
1031
+                $encs = $item->get_enclosures();
1032 1032
 
1033
-				if (is_array($encs)) {
1034
-					foreach ($encs as $e) {
1035
-						$e_item = array(
1036
-							rewrite_relative_url($site_url, $e->link),
1037
-							$e->type, $e->length, $e->title, $e->width, $e->height);
1033
+                if (is_array($encs)) {
1034
+                    foreach ($encs as $e) {
1035
+                        $e_item = array(
1036
+                            rewrite_relative_url($site_url, $e->link),
1037
+                            $e->type, $e->length, $e->title, $e->width, $e->height);
1038 1038
 
1039
-						// Yet another episode of "mysql utf8_general_ci is gimped"
1040
-						if (DB_TYPE == "mysql" && MYSQL_CHARSET != "UTF8MB4") {
1041
-							for ($i = 0; $i < count($e_item); $i++) {
1042
-								if (is_string($e_item[$i])) {
1043
-									$e_item[$i] = RSSUtils::strip_utf8mb4($e_item[$i]);
1044
-								}
1045
-							}
1046
-						}
1039
+                        // Yet another episode of "mysql utf8_general_ci is gimped"
1040
+                        if (DB_TYPE == "mysql" && MYSQL_CHARSET != "UTF8MB4") {
1041
+                            for ($i = 0; $i < count($e_item); $i++) {
1042
+                                if (is_string($e_item[$i])) {
1043
+                                    $e_item[$i] = RSSUtils::strip_utf8mb4($e_item[$i]);
1044
+                                }
1045
+                            }
1046
+                        }
1047 1047
 
1048
-						array_push($enclosures, $e_item);
1049
-					}
1050
-				}
1048
+                        array_push($enclosures, $e_item);
1049
+                    }
1050
+                }
1051 1051
 
1052
-				if ($cache_images)
1053
-					RSSUtils::cache_enclosures($enclosures, $site_url);
1052
+                if ($cache_images)
1053
+                    RSSUtils::cache_enclosures($enclosures, $site_url);
1054 1054
 
1055
-				if (Debug::get_loglevel() >= Debug::$LOG_EXTENDED) {
1056
-					Debug::log("article enclosures:", Debug::$LOG_VERBOSE);
1057
-					print_r($enclosures);
1058
-				}
1055
+                if (Debug::get_loglevel() >= Debug::$LOG_EXTENDED) {
1056
+                    Debug::log("article enclosures:", Debug::$LOG_VERBOSE);
1057
+                    print_r($enclosures);
1058
+                }
1059 1059
 
1060
-				$esth = $pdo->prepare("SELECT id FROM ttrss_enclosures
1060
+                $esth = $pdo->prepare("SELECT id FROM ttrss_enclosures
1061 1061
 						WHERE content_url = ? AND content_type = ? AND post_id = ?");
1062 1062
 
1063
-				$usth = $pdo->prepare("INSERT INTO ttrss_enclosures
1063
+                $usth = $pdo->prepare("INSERT INTO ttrss_enclosures
1064 1064
 							(content_url, content_type, title, duration, post_id, width, height) VALUES
1065 1065
 							(?, ?, ?, ?, ?, ?, ?)");
1066 1066
 
1067
-				foreach ($enclosures as $enc) {
1068
-					$enc_url = $enc[0];
1069
-					$enc_type = $enc[1];
1070
-					$enc_dur = (int)$enc[2];
1071
-					$enc_title = $enc[3];
1072
-					$enc_width = intval($enc[4]);
1073
-					$enc_height = intval($enc[5]);
1067
+                foreach ($enclosures as $enc) {
1068
+                    $enc_url = $enc[0];
1069
+                    $enc_type = $enc[1];
1070
+                    $enc_dur = (int)$enc[2];
1071
+                    $enc_title = $enc[3];
1072
+                    $enc_width = intval($enc[4]);
1073
+                    $enc_height = intval($enc[5]);
1074 1074
 
1075
-					$esth->execute([$enc_url, $enc_type, $entry_ref_id]);
1075
+                    $esth->execute([$enc_url, $enc_type, $entry_ref_id]);
1076 1076
 
1077
-					if (!$esth->fetch()) {
1078
-						$usth->execute([$enc_url, $enc_type, (string)$enc_title, $enc_dur, $entry_ref_id, $enc_width, $enc_height]);
1079
-					}
1080
-				}
1077
+                    if (!$esth->fetch()) {
1078
+                        $usth->execute([$enc_url, $enc_type, (string)$enc_title, $enc_dur, $entry_ref_id, $enc_width, $enc_height]);
1079
+                    }
1080
+                }
1081 1081
 
1082
-				// check for manual tags (we have to do it here since they're loaded from filters)
1082
+                // check for manual tags (we have to do it here since they're loaded from filters)
1083 1083
 
1084
-				foreach ($article_filters as $f) {
1085
-					if ($f["type"] == "tag") {
1084
+                foreach ($article_filters as $f) {
1085
+                    if ($f["type"] == "tag") {
1086 1086
 
1087
-						$manual_tags = trim_array(explode(",", $f["param"]));
1087
+                        $manual_tags = trim_array(explode(",", $f["param"]));
1088 1088
 
1089
-						foreach ($manual_tags as $tag) {
1090
-							array_push($entry_tags, $tag);
1091
-						}
1092
-					}
1093
-				}
1089
+                        foreach ($manual_tags as $tag) {
1090
+                            array_push($entry_tags, $tag);
1091
+                        }
1092
+                    }
1093
+                }
1094 1094
 
1095
-				// Skip boring tags
1095
+                // Skip boring tags
1096 1096
 
1097
-				$boring_tags = trim_array(explode(",", mb_strtolower(get_pref(
1098
-					'BLACKLISTED_TAGS', $owner_uid, ''), 'utf-8')));
1097
+                $boring_tags = trim_array(explode(",", mb_strtolower(get_pref(
1098
+                    'BLACKLISTED_TAGS', $owner_uid, ''), 'utf-8')));
1099 1099
 
1100
-				$filtered_tags = array();
1101
-				$tags_to_cache = array();
1100
+                $filtered_tags = array();
1101
+                $tags_to_cache = array();
1102 1102
 
1103
-				foreach ($entry_tags as $tag) {
1104
-					if (array_search($tag, $boring_tags) === false) {
1105
-						array_push($filtered_tags, $tag);
1106
-					}
1107
-				}
1103
+                foreach ($entry_tags as $tag) {
1104
+                    if (array_search($tag, $boring_tags) === false) {
1105
+                        array_push($filtered_tags, $tag);
1106
+                    }
1107
+                }
1108 1108
 
1109
-				$filtered_tags = array_unique($filtered_tags);
1109
+                $filtered_tags = array_unique($filtered_tags);
1110 1110
 
1111
-				if (Debug::get_loglevel() >= Debug::$LOG_VERBOSE) {
1112
-					Debug::log("filtered tags: " . implode(", ", $filtered_tags), Debug::$LOG_VERBOSE);
1111
+                if (Debug::get_loglevel() >= Debug::$LOG_VERBOSE) {
1112
+                    Debug::log("filtered tags: " . implode(", ", $filtered_tags), Debug::$LOG_VERBOSE);
1113 1113
 
1114
-				}
1114
+                }
1115 1115
 
1116
-				// Save article tags in the database
1116
+                // Save article tags in the database
1117 1117
 
1118
-				if (count($filtered_tags) > 0) {
1118
+                if (count($filtered_tags) > 0) {
1119 1119
 
1120
-					$tsth = $pdo->prepare("SELECT id FROM ttrss_tags
1120
+                    $tsth = $pdo->prepare("SELECT id FROM ttrss_tags
1121 1121
 							WHERE tag_name = ? AND post_int_id = ? AND
1122 1122
 							owner_uid = ? LIMIT 1");
1123 1123
 
1124
-					$usth = $pdo->prepare("INSERT INTO ttrss_tags
1124
+                    $usth = $pdo->prepare("INSERT INTO ttrss_tags
1125 1125
 									(owner_uid,tag_name,post_int_id)
1126 1126
 									VALUES (?, ?, ?)");
1127 1127
 
1128
-					$filtered_tags = FeedItem_Common::normalize_categories($filtered_tags);
1128
+                    $filtered_tags = FeedItem_Common::normalize_categories($filtered_tags);
1129 1129
 
1130
-					foreach ($filtered_tags as $tag) {
1131
-						$tsth->execute([$tag, $entry_int_id, $owner_uid]);
1130
+                    foreach ($filtered_tags as $tag) {
1131
+                        $tsth->execute([$tag, $entry_int_id, $owner_uid]);
1132 1132
 
1133
-						if (!$tsth->fetch()) {
1134
-							$usth->execute([$owner_uid, $tag, $entry_int_id]);
1135
-						}
1133
+                        if (!$tsth->fetch()) {
1134
+                            $usth->execute([$owner_uid, $tag, $entry_int_id]);
1135
+                        }
1136 1136
 
1137
-						array_push($tags_to_cache, $tag);
1138
-					}
1137
+                        array_push($tags_to_cache, $tag);
1138
+                    }
1139 1139
 
1140
-					/* update the cache */
1141
-					$tags_str = join(",", $tags_to_cache);
1140
+                    /* update the cache */
1141
+                    $tags_str = join(",", $tags_to_cache);
1142 1142
 
1143
-					$tsth = $pdo->prepare("UPDATE ttrss_user_entries
1143
+                    $tsth = $pdo->prepare("UPDATE ttrss_user_entries
1144 1144
 						SET tag_cache = ? WHERE ref_id = ?
1145 1145
 						AND owner_uid = ?");
1146
-					$tsth->execute([$tags_str, $entry_ref_id, $owner_uid]);
1147
-				}
1146
+                    $tsth->execute([$tags_str, $entry_ref_id, $owner_uid]);
1147
+                }
1148 1148
 
1149
-				Debug::log("article processed", Debug::$LOG_VERBOSE);
1149
+                Debug::log("article processed", Debug::$LOG_VERBOSE);
1150 1150
 
1151
-				$pdo->commit();
1152
-			}
1151
+                $pdo->commit();
1152
+            }
1153 1153
 
1154
-			Debug::log("purging feed...", Debug::$LOG_VERBOSE);
1154
+            Debug::log("purging feed...", Debug::$LOG_VERBOSE);
1155 1155
 
1156
-			Feeds::purge_feed($feed, 0);
1156
+            Feeds::purge_feed($feed, 0);
1157 1157
 
1158
-			$sth = $pdo->prepare("UPDATE ttrss_feeds
1158
+            $sth = $pdo->prepare("UPDATE ttrss_feeds
1159 1159
 				SET last_updated = NOW(), last_unconditional = NOW(), last_error = '' WHERE id = ?");
1160
-			$sth->execute([$feed]);
1160
+            $sth->execute([$feed]);
1161 1161
 
1162
-		} else {
1162
+        } else {
1163 1163
 
1164
-			$error_msg = mb_substr($rss->error(), 0, 245);
1164
+            $error_msg = mb_substr($rss->error(), 0, 245);
1165 1165
 
1166
-			Debug::log("fetch error: $error_msg", Debug::$LOG_VERBOSE);
1166
+            Debug::log("fetch error: $error_msg", Debug::$LOG_VERBOSE);
1167 1167
 
1168
-			if (count($rss->errors()) > 1) {
1169
-				foreach ($rss->errors() as $error) {
1170
-					Debug::log("+ $error", Debug::$LOG_VERBOSE);
1171
-				}
1172
-			}
1168
+            if (count($rss->errors()) > 1) {
1169
+                foreach ($rss->errors() as $error) {
1170
+                    Debug::log("+ $error", Debug::$LOG_VERBOSE);
1171
+                }
1172
+            }
1173 1173
 
1174
-			$sth = $pdo->prepare("UPDATE ttrss_feeds SET last_error = ?,
1174
+            $sth = $pdo->prepare("UPDATE ttrss_feeds SET last_error = ?,
1175 1175
 				last_updated = NOW(), last_unconditional = NOW() WHERE id = ?");
1176
-			$sth->execute([$error_msg, $feed]);
1176
+            $sth->execute([$error_msg, $feed]);
1177 1177
 
1178
-			unset($rss);
1178
+            unset($rss);
1179 1179
 
1180
-			Debug::log("update failed.", Debug::$LOG_VERBOSE);
1181
-			return false;
1182
-		}
1180
+            Debug::log("update failed.", Debug::$LOG_VERBOSE);
1181
+            return false;
1182
+        }
1183 1183
 
1184
-		Debug::log("update done.", Debug::$LOG_VERBOSE);
1184
+        Debug::log("update done.", Debug::$LOG_VERBOSE);
1185 1185
 
1186
-		return true;
1187
-	}
1186
+        return true;
1187
+    }
1188 1188
 
1189
-	public static function cache_enclosures($enclosures, $site_url) {
1190
-		$cache = new DiskCache("images");
1189
+    public static function cache_enclosures($enclosures, $site_url) {
1190
+        $cache = new DiskCache("images");
1191 1191
 
1192
-		if ($cache->isWritable()) {
1193
-			foreach ($enclosures as $enc) {
1192
+        if ($cache->isWritable()) {
1193
+            foreach ($enclosures as $enc) {
1194 1194
 
1195
-				if (preg_match("/(image|audio|video)/", $enc[1])) {
1196
-					$src = rewrite_relative_url($site_url, $enc[0]);
1195
+                if (preg_match("/(image|audio|video)/", $enc[1])) {
1196
+                    $src = rewrite_relative_url($site_url, $enc[0]);
1197 1197
 
1198
-					$local_filename = sha1($src);
1198
+                    $local_filename = sha1($src);
1199 1199
 
1200
-					Debug::log("cache_enclosures: downloading: $src to $local_filename", Debug::$LOG_VERBOSE);
1200
+                    Debug::log("cache_enclosures: downloading: $src to $local_filename", Debug::$LOG_VERBOSE);
1201 1201
 
1202
-					if (!$cache->exists($local_filename)) {
1202
+                    if (!$cache->exists($local_filename)) {
1203 1203
 
1204
-						global $fetch_last_error_code;
1205
-						global $fetch_last_error;
1204
+                        global $fetch_last_error_code;
1205
+                        global $fetch_last_error;
1206 1206
 
1207
-						$file_content = fetch_file_contents(array("url" => $src,
1208
-							"http_referrer" => $src,
1209
-							"max_size" => MAX_CACHE_FILE_SIZE));
1207
+                        $file_content = fetch_file_contents(array("url" => $src,
1208
+                            "http_referrer" => $src,
1209
+                            "max_size" => MAX_CACHE_FILE_SIZE));
1210 1210
 
1211
-						if ($file_content) {
1212
-							$cache->put($local_filename, $file_content);
1213
-						} else {
1214
-							Debug::log("cache_enclosures: failed with $fetch_last_error_code: $fetch_last_error");
1215
-						}
1216
-					} else if (is_writable($local_filename)) {
1217
-						$cache->touch($local_filename);
1218
-					}
1219
-				}
1220
-			}
1221
-		}
1222
-	}
1211
+                        if ($file_content) {
1212
+                            $cache->put($local_filename, $file_content);
1213
+                        } else {
1214
+                            Debug::log("cache_enclosures: failed with $fetch_last_error_code: $fetch_last_error");
1215
+                        }
1216
+                    } else if (is_writable($local_filename)) {
1217
+                        $cache->touch($local_filename);
1218
+                    }
1219
+                }
1220
+            }
1221
+        }
1222
+    }
1223 1223
 
1224
-	public static function cache_media($html, $site_url) {
1225
-		$cache = new DiskCache("images");
1224
+    public static function cache_media($html, $site_url) {
1225
+        $cache = new DiskCache("images");
1226 1226
 
1227
-		if ($cache->isWritable()) {
1228
-			$doc = new DOMDocument();
1229
-			if ($doc->loadHTML($html)) {
1230
-				$xpath = new DOMXPath($doc);
1227
+        if ($cache->isWritable()) {
1228
+            $doc = new DOMDocument();
1229
+            if ($doc->loadHTML($html)) {
1230
+                $xpath = new DOMXPath($doc);
1231 1231
 
1232
-				$entries = $xpath->query('(//img[@src])|(//video/source[@src])|(//audio/source[@src])');
1232
+                $entries = $xpath->query('(//img[@src])|(//video/source[@src])|(//audio/source[@src])');
1233 1233
 
1234
-				foreach ($entries as $entry) {
1235
-					if ($entry->hasAttribute('src') && strpos($entry->getAttribute('src'), "data:") !== 0) {
1236
-						$src = rewrite_relative_url($site_url, $entry->getAttribute('src'));
1234
+                foreach ($entries as $entry) {
1235
+                    if ($entry->hasAttribute('src') && strpos($entry->getAttribute('src'), "data:") !== 0) {
1236
+                        $src = rewrite_relative_url($site_url, $entry->getAttribute('src'));
1237 1237
 
1238
-						$local_filename = sha1($src);
1238
+                        $local_filename = sha1($src);
1239 1239
 
1240
-						Debug::log("cache_media: checking $src", Debug::$LOG_VERBOSE);
1240
+                        Debug::log("cache_media: checking $src", Debug::$LOG_VERBOSE);
1241 1241
 
1242
-						if (!$cache->exists($local_filename)) {
1243
-							Debug::log("cache_media: downloading: $src to $local_filename", Debug::$LOG_VERBOSE);
1242
+                        if (!$cache->exists($local_filename)) {
1243
+                            Debug::log("cache_media: downloading: $src to $local_filename", Debug::$LOG_VERBOSE);
1244 1244
 
1245
-							global $fetch_last_error_code;
1246
-							global $fetch_last_error;
1245
+                            global $fetch_last_error_code;
1246
+                            global $fetch_last_error;
1247 1247
 
1248
-							$file_content = fetch_file_contents(array("url" => $src,
1249
-								"http_referrer" => $src,
1250
-								"max_size" => MAX_CACHE_FILE_SIZE));
1248
+                            $file_content = fetch_file_contents(array("url" => $src,
1249
+                                "http_referrer" => $src,
1250
+                                "max_size" => MAX_CACHE_FILE_SIZE));
1251 1251
 
1252
-							if ($file_content) {
1253
-								$cache->put($local_filename, $file_content);
1254
-							} else {
1255
-								Debug::log("cache_media: failed with $fetch_last_error_code: $fetch_last_error");
1256
-							}
1257
-						} else if ($cache->isWritable($local_filename)) {
1258
-							$cache->touch($local_filename);
1259
-						}
1260
-					}
1261
-				}
1262
-			}
1263
-		}
1264
-	}
1252
+                            if ($file_content) {
1253
+                                $cache->put($local_filename, $file_content);
1254
+                            } else {
1255
+                                Debug::log("cache_media: failed with $fetch_last_error_code: $fetch_last_error");
1256
+                            }
1257
+                        } else if ($cache->isWritable($local_filename)) {
1258
+                            $cache->touch($local_filename);
1259
+                        }
1260
+                    }
1261
+                }
1262
+            }
1263
+        }
1264
+    }
1265 1265
 
1266
-	public static function expire_error_log() {
1267
-		Debug::log("Removing old error log entries...");
1266
+    public static function expire_error_log() {
1267
+        Debug::log("Removing old error log entries...");
1268 1268
 
1269
-		$pdo = Db::pdo();
1269
+        $pdo = Db::pdo();
1270 1270
 
1271
-		if (DB_TYPE == "pgsql") {
1272
-			$pdo->query("DELETE FROM ttrss_error_log
1271
+        if (DB_TYPE == "pgsql") {
1272
+            $pdo->query("DELETE FROM ttrss_error_log
1273 1273
 				WHERE created_at < NOW() - INTERVAL '7 days'");
1274
-		} else {
1275
-			$pdo->query("DELETE FROM ttrss_error_log
1274
+        } else {
1275
+            $pdo->query("DELETE FROM ttrss_error_log
1276 1276
 				WHERE created_at < DATE_SUB(NOW(), INTERVAL 7 DAY)");
1277
-		}
1278
-	}
1277
+        }
1278
+    }
1279 1279
 
1280
-	public static function expire_feed_archive() {
1281
-		Debug::log("Removing old archived feeds...");
1280
+    public static function expire_feed_archive() {
1281
+        Debug::log("Removing old archived feeds...");
1282 1282
 
1283
-		$pdo = Db::pdo();
1283
+        $pdo = Db::pdo();
1284 1284
 
1285
-		if (DB_TYPE == "pgsql") {
1286
-			$pdo->query("DELETE FROM ttrss_archived_feeds
1285
+        if (DB_TYPE == "pgsql") {
1286
+            $pdo->query("DELETE FROM ttrss_archived_feeds
1287 1287
 				WHERE created < NOW() - INTERVAL '1 month'");
1288
-		} else {
1289
-			$pdo->query("DELETE FROM ttrss_archived_feeds
1288
+        } else {
1289
+            $pdo->query("DELETE FROM ttrss_archived_feeds
1290 1290
 				WHERE created < DATE_SUB(NOW(), INTERVAL 1 MONTH)");
1291
-		}
1292
-	}
1293
-
1294
-	public static function expire_lock_files() {
1295
-		Debug::log("Removing old lock files...", Debug::$LOG_VERBOSE);
1296
-
1297
-		$num_deleted = 0;
1298
-
1299
-		if (is_writable(LOCK_DIRECTORY)) {
1300
-			$files = glob(LOCK_DIRECTORY . "/*.lock");
1301
-
1302
-			if ($files) {
1303
-				foreach ($files as $file) {
1304
-					if (!file_is_locked(basename($file)) && time() - filemtime($file) > 86400*2) {
1305
-						unlink($file);
1306
-						++$num_deleted;
1307
-					}
1308
-				}
1309
-			}
1310
-		}
1311
-
1312
-		Debug::log("removed $num_deleted old lock files.");
1313
-	}
1314
-
1315
-	/**
1316
-	 * Source: http://www.php.net/manual/en/function.parse-url.php#104527
1317
-	 * Returns the url query as associative array
1318
-	 *
1319
-	 * @param    string    query
1320
-	 * @return    array    params
1321
-	 */
1322
-	public static function convertUrlQuery($query) {
1323
-		$queryParts = explode('&', $query);
1324
-
1325
-		$params = array();
1326
-
1327
-		foreach ($queryParts as $param) {
1328
-			$item = explode('=', $param);
1329
-			$params[$item[0]] = $item[1];
1330
-		}
1331
-
1332
-		return $params;
1333
-	}
1334
-
1335
-	public static function get_article_filters($filters, $title, $content, $link, $author, $tags, &$matched_rules = false, &$matched_filters = false) {
1336
-		$matches = array();
1337
-
1338
-		foreach ($filters as $filter) {
1339
-			$match_any_rule = $filter["match_any_rule"];
1340
-			$inverse = $filter["inverse"];
1341
-			$filter_match = false;
1342
-
1343
-			foreach ($filter["rules"] as $rule) {
1344
-				$match = false;
1345
-				$reg_exp = str_replace('/', '\/', $rule["reg_exp"]);
1346
-				$rule_inverse = $rule["inverse"];
1347
-
1348
-				if (!$reg_exp)
1349
-					continue;
1350
-
1351
-				switch ($rule["type"]) {
1352
-					case "title":
1353
-						$match = @preg_match("/$reg_exp/iu", $title);
1354
-						break;
1355
-					case "content":
1356
-						// we don't need to deal with multiline regexps
1357
-						$content = preg_replace("/[\r\n\t]/", "", $content);
1358
-
1359
-						$match = @preg_match("/$reg_exp/iu", $content);
1360
-						break;
1361
-					case "both":
1362
-						// we don't need to deal with multiline regexps
1363
-						$content = preg_replace("/[\r\n\t]/", "", $content);
1364
-
1365
-						$match = (@preg_match("/$reg_exp/iu", $title) || @preg_match("/$reg_exp/iu", $content));
1366
-						break;
1367
-					case "link":
1368
-						$match = @preg_match("/$reg_exp/iu", $link);
1369
-						break;
1370
-					case "author":
1371
-						$match = @preg_match("/$reg_exp/iu", $author);
1372
-						break;
1373
-					case "tag":
1374
-						foreach ($tags as $tag) {
1375
-							if (@preg_match("/$reg_exp/iu", $tag)) {
1376
-								$match = true;
1377
-								break;
1378
-							}
1379
-						}
1380
-						break;
1381
-				}
1382
-
1383
-				if ($rule_inverse) $match = !$match;
1384
-
1385
-				if ($match_any_rule) {
1386
-					if ($match) {
1387
-						$filter_match = true;
1388
-						break;
1389
-					}
1390
-				} else {
1391
-					$filter_match = $match;
1392
-					if (!$match) {
1393
-						break;
1394
-					}
1395
-				}
1396
-			}
1397
-
1398
-			if ($inverse) $filter_match = !$filter_match;
1399
-
1400
-			if ($filter_match) {
1401
-				if (is_array($matched_rules)) array_push($matched_rules, $rule);
1402
-				if (is_array($matched_filters)) array_push($matched_filters, $filter);
1403
-
1404
-				foreach ($filter["actions"] as $action) {
1405
-					array_push($matches, $action);
1406
-
1407
-					// if Stop action encountered, perform no further processing
1408
-					if (isset($action["type"]) && $action["type"] == "stop") return $matches;
1409
-				}
1410
-			}
1411
-		}
1412
-
1413
-		return $matches;
1414
-	}
1415
-
1416
-	public static function find_article_filter($filters, $filter_name) {
1417
-		foreach ($filters as $f) {
1418
-			if ($f["type"] == $filter_name) {
1419
-				return $f;
1420
-			};
1421
-		}
1422
-		return false;
1423
-	}
1424
-
1425
-	public static function find_article_filters($filters, $filter_name) {
1426
-		$results = array();
1427
-
1428
-		foreach ($filters as $f) {
1429
-			if ($f["type"] == $filter_name) {
1430
-				array_push($results, $f);
1431
-			};
1432
-		}
1433
-		return $results;
1434
-	}
1435
-
1436
-	public static function calculate_article_score($filters) {
1437
-		$score = 0;
1438
-
1439
-		foreach ($filters as $f) {
1440
-			if ($f["type"] == "score") {
1441
-				$score += $f["param"];
1442
-			};
1443
-		}
1444
-		return $score;
1445
-	}
1446
-
1447
-	public static function labels_contains_caption($labels, $caption) {
1448
-		foreach ($labels as $label) {
1449
-			if ($label[1] == $caption) {
1450
-				return true;
1451
-			}
1452
-		}
1453
-
1454
-		return false;
1455
-	}
1456
-
1457
-	public static function assign_article_to_label_filters($id, $filters, $owner_uid, $article_labels) {
1458
-		foreach ($filters as $f) {
1459
-			if ($f["type"] == "label") {
1460
-				if (!RSSUtils::labels_contains_caption($article_labels, $f["param"])) {
1461
-					Labels::add_article($id, $f["param"], $owner_uid);
1462
-				}
1463
-			}
1464
-		}
1465
-	}
1466
-
1467
-	public static function make_guid_from_title($title) {
1468
-		return preg_replace("/[ \"\',.:;]/", "-",
1469
-			mb_strtolower(strip_tags($title), 'utf-8'));
1470
-	}
1471
-
1472
-	public static function cleanup_counters_cache() {
1473
-		$pdo = Db::pdo();
1474
-
1475
-		$res = $pdo->query("DELETE FROM ttrss_counters_cache
1291
+        }
1292
+    }
1293
+
1294
+    public static function expire_lock_files() {
1295
+        Debug::log("Removing old lock files...", Debug::$LOG_VERBOSE);
1296
+
1297
+        $num_deleted = 0;
1298
+
1299
+        if (is_writable(LOCK_DIRECTORY)) {
1300
+            $files = glob(LOCK_DIRECTORY . "/*.lock");
1301
+
1302
+            if ($files) {
1303
+                foreach ($files as $file) {
1304
+                    if (!file_is_locked(basename($file)) && time() - filemtime($file) > 86400*2) {
1305
+                        unlink($file);
1306
+                        ++$num_deleted;
1307
+                    }
1308
+                }
1309
+            }
1310
+        }
1311
+
1312
+        Debug::log("removed $num_deleted old lock files.");
1313
+    }
1314
+
1315
+    /**
1316
+     * Source: http://www.php.net/manual/en/function.parse-url.php#104527
1317
+     * Returns the url query as associative array
1318
+     *
1319
+     * @param    string    query
1320
+     * @return    array    params
1321
+     */
1322
+    public static function convertUrlQuery($query) {
1323
+        $queryParts = explode('&', $query);
1324
+
1325
+        $params = array();
1326
+
1327
+        foreach ($queryParts as $param) {
1328
+            $item = explode('=', $param);
1329
+            $params[$item[0]] = $item[1];
1330
+        }
1331
+
1332
+        return $params;
1333
+    }
1334
+
1335
+    public static function get_article_filters($filters, $title, $content, $link, $author, $tags, &$matched_rules = false, &$matched_filters = false) {
1336
+        $matches = array();
1337
+
1338
+        foreach ($filters as $filter) {
1339
+            $match_any_rule = $filter["match_any_rule"];
1340
+            $inverse = $filter["inverse"];
1341
+            $filter_match = false;
1342
+
1343
+            foreach ($filter["rules"] as $rule) {
1344
+                $match = false;
1345
+                $reg_exp = str_replace('/', '\/', $rule["reg_exp"]);
1346
+                $rule_inverse = $rule["inverse"];
1347
+
1348
+                if (!$reg_exp)
1349
+                    continue;
1350
+
1351
+                switch ($rule["type"]) {
1352
+                    case "title":
1353
+                        $match = @preg_match("/$reg_exp/iu", $title);
1354
+                        break;
1355
+                    case "content":
1356
+                        // we don't need to deal with multiline regexps
1357
+                        $content = preg_replace("/[\r\n\t]/", "", $content);
1358
+
1359
+                        $match = @preg_match("/$reg_exp/iu", $content);
1360
+                        break;
1361
+                    case "both":
1362
+                        // we don't need to deal with multiline regexps
1363
+                        $content = preg_replace("/[\r\n\t]/", "", $content);
1364
+
1365
+                        $match = (@preg_match("/$reg_exp/iu", $title) || @preg_match("/$reg_exp/iu", $content));
1366
+                        break;
1367
+                    case "link":
1368
+                        $match = @preg_match("/$reg_exp/iu", $link);
1369
+                        break;
1370
+                    case "author":
1371
+                        $match = @preg_match("/$reg_exp/iu", $author);
1372
+                        break;
1373
+                    case "tag":
1374
+                        foreach ($tags as $tag) {
1375
+                            if (@preg_match("/$reg_exp/iu", $tag)) {
1376
+                                $match = true;
1377
+                                break;
1378
+                            }
1379
+                        }
1380
+                        break;
1381
+                }
1382
+
1383
+                if ($rule_inverse) $match = !$match;
1384
+
1385
+                if ($match_any_rule) {
1386
+                    if ($match) {
1387
+                        $filter_match = true;
1388
+                        break;
1389
+                    }
1390
+                } else {
1391
+                    $filter_match = $match;
1392
+                    if (!$match) {
1393
+                        break;
1394
+                    }
1395
+                }
1396
+            }
1397
+
1398
+            if ($inverse) $filter_match = !$filter_match;
1399
+
1400
+            if ($filter_match) {
1401
+                if (is_array($matched_rules)) array_push($matched_rules, $rule);
1402
+                if (is_array($matched_filters)) array_push($matched_filters, $filter);
1403
+
1404
+                foreach ($filter["actions"] as $action) {
1405
+                    array_push($matches, $action);
1406
+
1407
+                    // if Stop action encountered, perform no further processing
1408
+                    if (isset($action["type"]) && $action["type"] == "stop") return $matches;
1409
+                }
1410
+            }
1411
+        }
1412
+
1413
+        return $matches;
1414
+    }
1415
+
1416
+    public static function find_article_filter($filters, $filter_name) {
1417
+        foreach ($filters as $f) {
1418
+            if ($f["type"] == $filter_name) {
1419
+                return $f;
1420
+            };
1421
+        }
1422
+        return false;
1423
+    }
1424
+
1425
+    public static function find_article_filters($filters, $filter_name) {
1426
+        $results = array();
1427
+
1428
+        foreach ($filters as $f) {
1429
+            if ($f["type"] == $filter_name) {
1430
+                array_push($results, $f);
1431
+            };
1432
+        }
1433
+        return $results;
1434
+    }
1435
+
1436
+    public static function calculate_article_score($filters) {
1437
+        $score = 0;
1438
+
1439
+        foreach ($filters as $f) {
1440
+            if ($f["type"] == "score") {
1441
+                $score += $f["param"];
1442
+            };
1443
+        }
1444
+        return $score;
1445
+    }
1446
+
1447
+    public static function labels_contains_caption($labels, $caption) {
1448
+        foreach ($labels as $label) {
1449
+            if ($label[1] == $caption) {
1450
+                return true;
1451
+            }
1452
+        }
1453
+
1454
+        return false;
1455
+    }
1456
+
1457
+    public static function assign_article_to_label_filters($id, $filters, $owner_uid, $article_labels) {
1458
+        foreach ($filters as $f) {
1459
+            if ($f["type"] == "label") {
1460
+                if (!RSSUtils::labels_contains_caption($article_labels, $f["param"])) {
1461
+                    Labels::add_article($id, $f["param"], $owner_uid);
1462
+                }
1463
+            }
1464
+        }
1465
+    }
1466
+
1467
+    public static function make_guid_from_title($title) {
1468
+        return preg_replace("/[ \"\',.:;]/", "-",
1469
+            mb_strtolower(strip_tags($title), 'utf-8'));
1470
+    }
1471
+
1472
+    public static function cleanup_counters_cache() {
1473
+        $pdo = Db::pdo();
1474
+
1475
+        $res = $pdo->query("DELETE FROM ttrss_counters_cache
1476 1476
 			WHERE feed_id > 0 AND
1477 1477
 			(SELECT COUNT(id) FROM ttrss_feeds WHERE
1478 1478
 				id = feed_id AND
1479 1479
 				ttrss_counters_cache.owner_uid = ttrss_feeds.owner_uid) = 0");
1480 1480
 
1481
-		$frows = $res->rowCount();
1481
+        $frows = $res->rowCount();
1482 1482
 
1483
-		$res = $pdo->query("DELETE FROM ttrss_cat_counters_cache
1483
+        $res = $pdo->query("DELETE FROM ttrss_cat_counters_cache
1484 1484
 			WHERE feed_id > 0 AND
1485 1485
 			(SELECT COUNT(id) FROM ttrss_feed_categories WHERE
1486 1486
 				id = feed_id AND
1487 1487
 				ttrss_cat_counters_cache.owner_uid = ttrss_feed_categories.owner_uid) = 0");
1488 1488
 
1489
-		$crows = $res->rowCount();
1490
-
1491
-		Debug::log("removed $frows (feeds) $crows (cats) orphaned counter cache entries.");
1492
-	}
1493
-
1494
-	public static function housekeeping_user($owner_uid) {
1495
-		$tmph = new PluginHost();
1496
-
1497
-		load_user_plugins($owner_uid, $tmph);
1498
-
1499
-		$tmph->run_hooks(PluginHost::HOOK_HOUSE_KEEPING, "hook_house_keeping", "");
1500
-	}
1501
-
1502
-	public static function housekeeping_common() {
1503
-		DiskCache::expire();
1504
-
1505
-		RSSUtils::expire_lock_files();
1506
-		RSSUtils::expire_error_log();
1507
-		RSSUtils::expire_feed_archive();
1508
-		RSSUtils::cleanup_feed_browser();
1509
-
1510
-		Article::purge_orphans();
1511
-		RSSUtils::cleanup_counters_cache();
1512
-
1513
-		PluginHost::getInstance()->run_hooks(PluginHost::HOOK_HOUSE_KEEPING, "hook_house_keeping", "");
1514
-	}
1515
-
1516
-	public static function check_feed_favicon($site_url, $feed) {
1517
-		#		print "FAVICON [$site_url]: $favicon_url\n";
1518
-
1519
-		$icon_file = ICONS_DIR . "/$feed.ico";
1520
-
1521
-		if (!file_exists($icon_file)) {
1522
-			$favicon_url = RSSUtils::get_favicon_url($site_url);
1523
-
1524
-			if ($favicon_url) {
1525
-				// Limiting to "image" type misses those served with text/plain
1526
-				$contents = fetch_file_contents($favicon_url); // , "image");
1527
-
1528
-				if ($contents) {
1529
-					// Crude image type matching.
1530
-					// Patterns gleaned from the file(1) source code.
1531
-					if (preg_match('/^\x00\x00\x01\x00/', $contents)) {
1532
-						// 0       string  \000\000\001\000        MS Windows icon resource
1533
-						//error_log("check_feed_favicon: favicon_url=$favicon_url isa MS Windows icon resource");
1534
-					}
1535
-					elseif (preg_match('/^GIF8/', $contents)) {
1536
-						// 0       string          GIF8            GIF image data
1537
-						//error_log("check_feed_favicon: favicon_url=$favicon_url isa GIF image");
1538
-					}
1539
-					elseif (preg_match('/^\x89PNG\x0d\x0a\x1a\x0a/', $contents)) {
1540
-						// 0       string          \x89PNG\x0d\x0a\x1a\x0a         PNG image data
1541
-						//error_log("check_feed_favicon: favicon_url=$favicon_url isa PNG image");
1542
-					}
1543
-					elseif (preg_match('/^\xff\xd8/', $contents)) {
1544
-						// 0       beshort         0xffd8          JPEG image data
1545
-						//error_log("check_feed_favicon: favicon_url=$favicon_url isa JPG image");
1546
-					}
1547
-					elseif (preg_match('/^BM/', $contents)) {
1548
-						// 0	string		BM	PC bitmap (OS2, Windows BMP files)
1549
-						//error_log("check_feed_favicon, favicon_url=$favicon_url isa BMP image");
1550
-					}
1551
-					else {
1552
-						//error_log("check_feed_favicon: favicon_url=$favicon_url isa UNKNOWN type");
1553
-						$contents = "";
1554
-					}
1555
-				}
1556
-
1557
-				if ($contents) {
1558
-					$fp = @fopen($icon_file, "w");
1559
-
1560
-					if ($fp) {
1561
-						fwrite($fp, $contents);
1562
-						fclose($fp);
1563
-						chmod($icon_file, 0644);
1564
-					}
1565
-				}
1566
-			}
1567
-			return $icon_file;
1568
-		}
1569
-	}
1570
-
1571
-	public static function is_gzipped($feed_data) {
1572
-		return strpos(substr($feed_data, 0, 3),
1573
-				"\x1f" . "\x8b" . "\x08", 0) === 0;
1574
-	}
1575
-
1576
-	public static function load_filters($feed_id, $owner_uid) {
1577
-		$filters = array();
1578
-
1579
-		$feed_id = (int) $feed_id;
1580
-		$cat_id = (int)Feeds::getFeedCategory($feed_id);
1581
-
1582
-		if ($cat_id == 0)
1583
-			$null_cat_qpart = "cat_id IS NULL OR";
1584
-		else
1585
-			$null_cat_qpart = "";
1586
-
1587
-		$pdo = Db::pdo();
1588
-
1589
-		$sth = $pdo->prepare("SELECT * FROM ttrss_filters2 WHERE
1489
+        $crows = $res->rowCount();
1490
+
1491
+        Debug::log("removed $frows (feeds) $crows (cats) orphaned counter cache entries.");
1492
+    }
1493
+
1494
+    public static function housekeeping_user($owner_uid) {
1495
+        $tmph = new PluginHost();
1496
+
1497
+        load_user_plugins($owner_uid, $tmph);
1498
+
1499
+        $tmph->run_hooks(PluginHost::HOOK_HOUSE_KEEPING, "hook_house_keeping", "");
1500
+    }
1501
+
1502
+    public static function housekeeping_common() {
1503
+        DiskCache::expire();
1504
+
1505
+        RSSUtils::expire_lock_files();
1506
+        RSSUtils::expire_error_log();
1507
+        RSSUtils::expire_feed_archive();
1508
+        RSSUtils::cleanup_feed_browser();
1509
+
1510
+        Article::purge_orphans();
1511
+        RSSUtils::cleanup_counters_cache();
1512
+
1513
+        PluginHost::getInstance()->run_hooks(PluginHost::HOOK_HOUSE_KEEPING, "hook_house_keeping", "");
1514
+    }
1515
+
1516
+    public static function check_feed_favicon($site_url, $feed) {
1517
+        #		print "FAVICON [$site_url]: $favicon_url\n";
1518
+
1519
+        $icon_file = ICONS_DIR . "/$feed.ico";
1520
+
1521
+        if (!file_exists($icon_file)) {
1522
+            $favicon_url = RSSUtils::get_favicon_url($site_url);
1523
+
1524
+            if ($favicon_url) {
1525
+                // Limiting to "image" type misses those served with text/plain
1526
+                $contents = fetch_file_contents($favicon_url); // , "image");
1527
+
1528
+                if ($contents) {
1529
+                    // Crude image type matching.
1530
+                    // Patterns gleaned from the file(1) source code.
1531
+                    if (preg_match('/^\x00\x00\x01\x00/', $contents)) {
1532
+                        // 0       string  \000\000\001\000        MS Windows icon resource
1533
+                        //error_log("check_feed_favicon: favicon_url=$favicon_url isa MS Windows icon resource");
1534
+                    }
1535
+                    elseif (preg_match('/^GIF8/', $contents)) {
1536
+                        // 0       string          GIF8            GIF image data
1537
+                        //error_log("check_feed_favicon: favicon_url=$favicon_url isa GIF image");
1538
+                    }
1539
+                    elseif (preg_match('/^\x89PNG\x0d\x0a\x1a\x0a/', $contents)) {
1540
+                        // 0       string          \x89PNG\x0d\x0a\x1a\x0a         PNG image data
1541
+                        //error_log("check_feed_favicon: favicon_url=$favicon_url isa PNG image");
1542
+                    }
1543
+                    elseif (preg_match('/^\xff\xd8/', $contents)) {
1544
+                        // 0       beshort         0xffd8          JPEG image data
1545
+                        //error_log("check_feed_favicon: favicon_url=$favicon_url isa JPG image");
1546
+                    }
1547
+                    elseif (preg_match('/^BM/', $contents)) {
1548
+                        // 0	string		BM	PC bitmap (OS2, Windows BMP files)
1549
+                        //error_log("check_feed_favicon, favicon_url=$favicon_url isa BMP image");
1550
+                    }
1551
+                    else {
1552
+                        //error_log("check_feed_favicon: favicon_url=$favicon_url isa UNKNOWN type");
1553
+                        $contents = "";
1554
+                    }
1555
+                }
1556
+
1557
+                if ($contents) {
1558
+                    $fp = @fopen($icon_file, "w");
1559
+
1560
+                    if ($fp) {
1561
+                        fwrite($fp, $contents);
1562
+                        fclose($fp);
1563
+                        chmod($icon_file, 0644);
1564
+                    }
1565
+                }
1566
+            }
1567
+            return $icon_file;
1568
+        }
1569
+    }
1570
+
1571
+    public static function is_gzipped($feed_data) {
1572
+        return strpos(substr($feed_data, 0, 3),
1573
+                "\x1f" . "\x8b" . "\x08", 0) === 0;
1574
+    }
1575
+
1576
+    public static function load_filters($feed_id, $owner_uid) {
1577
+        $filters = array();
1578
+
1579
+        $feed_id = (int) $feed_id;
1580
+        $cat_id = (int)Feeds::getFeedCategory($feed_id);
1581
+
1582
+        if ($cat_id == 0)
1583
+            $null_cat_qpart = "cat_id IS NULL OR";
1584
+        else
1585
+            $null_cat_qpart = "";
1586
+
1587
+        $pdo = Db::pdo();
1588
+
1589
+        $sth = $pdo->prepare("SELECT * FROM ttrss_filters2 WHERE
1590 1590
 				owner_uid = ? AND enabled = true ORDER BY order_id, title");
1591
-		$sth->execute([$owner_uid]);
1591
+        $sth->execute([$owner_uid]);
1592 1592
 
1593
-		$check_cats = array_merge(
1594
-			Feeds::getParentCategories($cat_id, $owner_uid),
1595
-			[$cat_id]);
1593
+        $check_cats = array_merge(
1594
+            Feeds::getParentCategories($cat_id, $owner_uid),
1595
+            [$cat_id]);
1596 1596
 
1597
-		$check_cats_str = join(",", $check_cats);
1598
-		$check_cats_fullids = array_map(function($a) { return "CAT:$a"; }, $check_cats);
1597
+        $check_cats_str = join(",", $check_cats);
1598
+        $check_cats_fullids = array_map(function($a) { return "CAT:$a"; }, $check_cats);
1599 1599
 
1600
-		while ($line = $sth->fetch()) {
1601
-			$filter_id = $line["id"];
1600
+        while ($line = $sth->fetch()) {
1601
+            $filter_id = $line["id"];
1602 1602
 
1603
-			$match_any_rule = sql_bool_to_bool($line["match_any_rule"]);
1603
+            $match_any_rule = sql_bool_to_bool($line["match_any_rule"]);
1604 1604
 
1605
-			$sth2 = $pdo->prepare("SELECT
1605
+            $sth2 = $pdo->prepare("SELECT
1606 1606
 					r.reg_exp, r.inverse, r.feed_id, r.cat_id, r.cat_filter, r.match_on, t.name AS type_name
1607 1607
 					FROM ttrss_filters2_rules AS r,
1608 1608
 					ttrss_filter_types AS t
@@ -1611,117 +1611,117 @@  discard block
 block discarded – undo
1611 1611
 						  (($null_cat_qpart (cat_id IS NULL AND cat_filter = false) OR cat_id IN ($check_cats_str)) AND
1612 1612
 						  (feed_id IS NULL OR feed_id = ?))) AND
1613 1613
 						filter_type = t.id AND filter_id = ?");
1614
-			$sth2->execute([$feed_id, $filter_id]);
1614
+            $sth2->execute([$feed_id, $filter_id]);
1615 1615
 
1616
-			$rules = array();
1617
-			$actions = array();
1616
+            $rules = array();
1617
+            $actions = array();
1618 1618
 
1619
-			while ($rule_line = $sth2->fetch()) {
1620
-				#				print_r($rule_line);
1619
+            while ($rule_line = $sth2->fetch()) {
1620
+                #				print_r($rule_line);
1621 1621
 
1622
-				if ($rule_line["match_on"]) {
1623
-					$match_on = json_decode($rule_line["match_on"], true);
1622
+                if ($rule_line["match_on"]) {
1623
+                    $match_on = json_decode($rule_line["match_on"], true);
1624 1624
 
1625
-					if (in_array("0", $match_on) || in_array($feed_id, $match_on) || count(array_intersect($check_cats_fullids, $match_on)) > 0) {
1625
+                    if (in_array("0", $match_on) || in_array($feed_id, $match_on) || count(array_intersect($check_cats_fullids, $match_on)) > 0) {
1626 1626
 
1627
-						$rule = array();
1628
-						$rule["reg_exp"] = $rule_line["reg_exp"];
1629
-						$rule["type"] = $rule_line["type_name"];
1630
-						$rule["inverse"] = sql_bool_to_bool($rule_line["inverse"]);
1627
+                        $rule = array();
1628
+                        $rule["reg_exp"] = $rule_line["reg_exp"];
1629
+                        $rule["type"] = $rule_line["type_name"];
1630
+                        $rule["inverse"] = sql_bool_to_bool($rule_line["inverse"]);
1631 1631
 
1632
-						array_push($rules, $rule);
1633
-					} else if (!$match_any_rule) {
1634
-						// this filter contains a rule that doesn't match to this feed/category combination
1635
-						// thus filter has to be rejected
1632
+                        array_push($rules, $rule);
1633
+                    } else if (!$match_any_rule) {
1634
+                        // this filter contains a rule that doesn't match to this feed/category combination
1635
+                        // thus filter has to be rejected
1636 1636
 
1637
-						$rules = [];
1638
-						break;
1639
-					}
1637
+                        $rules = [];
1638
+                        break;
1639
+                    }
1640 1640
 
1641
-				} else {
1641
+                } else {
1642 1642
 
1643
-					$rule = array();
1644
-					$rule["reg_exp"] = $rule_line["reg_exp"];
1645
-					$rule["type"] = $rule_line["type_name"];
1646
-					$rule["inverse"] = sql_bool_to_bool($rule_line["inverse"]);
1643
+                    $rule = array();
1644
+                    $rule["reg_exp"] = $rule_line["reg_exp"];
1645
+                    $rule["type"] = $rule_line["type_name"];
1646
+                    $rule["inverse"] = sql_bool_to_bool($rule_line["inverse"]);
1647 1647
 
1648
-					array_push($rules, $rule);
1649
-				}
1650
-			}
1648
+                    array_push($rules, $rule);
1649
+                }
1650
+            }
1651 1651
 
1652
-			if (count($rules) > 0) {
1653
-				$sth2 = $pdo->prepare("SELECT a.action_param,t.name AS type_name
1652
+            if (count($rules) > 0) {
1653
+                $sth2 = $pdo->prepare("SELECT a.action_param,t.name AS type_name
1654 1654
 						FROM ttrss_filters2_actions AS a,
1655 1655
 						ttrss_filter_actions AS t
1656 1656
 						WHERE
1657 1657
 							action_id = t.id AND filter_id = ?");
1658
-				$sth2->execute([$filter_id]);
1659
-
1660
-				while ($action_line = $sth2->fetch()) {
1661
-					#				print_r($action_line);
1662
-
1663
-					$action = array();
1664
-					$action["type"] = $action_line["type_name"];
1665
-					$action["param"] = $action_line["action_param"];
1666
-
1667
-					array_push($actions, $action);
1668
-				}
1669
-			}
1670
-
1671
-			$filter = [];
1672
-			$filter["id"] = $filter_id;
1673
-			$filter["match_any_rule"] = sql_bool_to_bool($line["match_any_rule"]);
1674
-			$filter["inverse"] = sql_bool_to_bool($line["inverse"]);
1675
-			$filter["rules"] = $rules;
1676
-			$filter["actions"] = $actions;
1677
-
1678
-			if (count($rules) > 0 && count($actions) > 0) {
1679
-				array_push($filters, $filter);
1680
-			}
1681
-		}
1682
-
1683
-		return $filters;
1684
-	}
1685
-
1686
-	/**
1687
-	 * Try to determine the favicon URL for a feed.
1688
-	 * adapted from wordpress favicon plugin by Jeff Minard (http://thecodepro.com/)
1689
-	 * http://dev.wp-plugins.org/file/favatars/trunk/favatars.php
1690
-	 *
1691
-	 * @param string $url A feed or page URL
1692
-	 * @access public
1693
-	 * @return mixed The favicon URL, or false if none was found.
1694
-	 */
1695
-	public static function get_favicon_url($url) {
1696
-
1697
-		$favicon_url = false;
1698
-
1699
-		if ($html = @fetch_file_contents($url)) {
1700
-
1701
-			$doc = new DOMDocument();
1702
-			if ($doc->loadHTML($html)) {
1703
-				$xpath = new DOMXPath($doc);
1704
-
1705
-				$base = $xpath->query('/html/head/base[@href]');
1706
-				foreach ($base as $b) {
1707
-					$url = rewrite_relative_url($url, $b->getAttribute("href"));
1708
-					break;
1709
-				}
1710
-
1711
-				$entries = $xpath->query('/html/head/link[@rel="shortcut icon" or @rel="icon"]');
1712
-				if (count($entries) > 0) {
1713
-					foreach ($entries as $entry) {
1714
-						$favicon_url = rewrite_relative_url($url, $entry->getAttribute("href"));
1715
-						break;
1716
-					}
1717
-				}
1718
-			}
1719
-		}
1720
-
1721
-		if (!$favicon_url)
1722
-			$favicon_url = rewrite_relative_url($url, "/favicon.ico");
1723
-
1724
-		return $favicon_url;
1725
-	}
1658
+                $sth2->execute([$filter_id]);
1659
+
1660
+                while ($action_line = $sth2->fetch()) {
1661
+                    #				print_r($action_line);
1662
+
1663
+                    $action = array();
1664
+                    $action["type"] = $action_line["type_name"];
1665
+                    $action["param"] = $action_line["action_param"];
1666
+
1667
+                    array_push($actions, $action);
1668
+                }
1669
+            }
1670
+
1671
+            $filter = [];
1672
+            $filter["id"] = $filter_id;
1673
+            $filter["match_any_rule"] = sql_bool_to_bool($line["match_any_rule"]);
1674
+            $filter["inverse"] = sql_bool_to_bool($line["inverse"]);
1675
+            $filter["rules"] = $rules;
1676
+            $filter["actions"] = $actions;
1677
+
1678
+            if (count($rules) > 0 && count($actions) > 0) {
1679
+                array_push($filters, $filter);
1680
+            }
1681
+        }
1682
+
1683
+        return $filters;
1684
+    }
1685
+
1686
+    /**
1687
+     * Try to determine the favicon URL for a feed.
1688
+     * adapted from wordpress favicon plugin by Jeff Minard (http://thecodepro.com/)
1689
+     * http://dev.wp-plugins.org/file/favatars/trunk/favatars.php
1690
+     *
1691
+     * @param string $url A feed or page URL
1692
+     * @access public
1693
+     * @return mixed The favicon URL, or false if none was found.
1694
+     */
1695
+    public static function get_favicon_url($url) {
1696
+
1697
+        $favicon_url = false;
1698
+
1699
+        if ($html = @fetch_file_contents($url)) {
1700
+
1701
+            $doc = new DOMDocument();
1702
+            if ($doc->loadHTML($html)) {
1703
+                $xpath = new DOMXPath($doc);
1704
+
1705
+                $base = $xpath->query('/html/head/base[@href]');
1706
+                foreach ($base as $b) {
1707
+                    $url = rewrite_relative_url($url, $b->getAttribute("href"));
1708
+                    break;
1709
+                }
1710
+
1711
+                $entries = $xpath->query('/html/head/link[@rel="shortcut icon" or @rel="icon"]');
1712
+                if (count($entries) > 0) {
1713
+                    foreach ($entries as $entry) {
1714
+                        $favicon_url = rewrite_relative_url($url, $entry->getAttribute("href"));
1715
+                        break;
1716
+                    }
1717
+                }
1718
+            }
1719
+        }
1720
+
1721
+        if (!$favicon_url)
1722
+            $favicon_url = rewrite_relative_url($url, "/favicon.ico");
1723
+
1724
+        return $favicon_url;
1725
+    }
1726 1726
 
1727 1727
 }
Please login to merge, or discard this patch.
classes/article.php 1 patch
Indentation   +521 added lines, -521 removed lines patch added patch discarded remove patch
@@ -1,620 +1,620 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 class Article extends Handler_Protected {
3 3
 
4
-	public function csrf_ignore($method) {
5
-		$csrf_ignored = array("redirect", "editarticletags");
4
+    public function csrf_ignore($method) {
5
+        $csrf_ignored = array("redirect", "editarticletags");
6 6
 
7
-		return array_search($method, $csrf_ignored) !== false;
8
-	}
7
+        return array_search($method, $csrf_ignored) !== false;
8
+    }
9 9
 
10
-	public function redirect() {
11
-		$id = clean($_REQUEST['id']);
10
+    public function redirect() {
11
+        $id = clean($_REQUEST['id']);
12 12
 
13
-		$sth = $this->pdo->prepare("SELECT link FROM ttrss_entries, ttrss_user_entries
13
+        $sth = $this->pdo->prepare("SELECT link FROM ttrss_entries, ttrss_user_entries
14 14
 						WHERE id = ? AND id = ref_id AND owner_uid = ?
15 15
 						LIMIT 1");
16 16
         $sth->execute([$id, $_SESSION['uid']]);
17 17
 
18
-		if ($row = $sth->fetch()) {
19
-			$article_url = $row['link'];
20
-			$article_url = str_replace("\n", "", $article_url);
18
+        if ($row = $sth->fetch()) {
19
+            $article_url = $row['link'];
20
+            $article_url = str_replace("\n", "", $article_url);
21 21
 
22
-			header("Location: $article_url");
23
-			return;
22
+            header("Location: $article_url");
23
+            return;
24 24
 
25
-		} else {
26
-			print_error(__("Article not found."));
27
-		}
28
-	}
25
+        } else {
26
+            print_error(__("Article not found."));
27
+        }
28
+    }
29 29
 
30
-	public static function create_published_article($title, $url, $content, $labels_str,
31
-			$owner_uid) {
30
+    public static function create_published_article($title, $url, $content, $labels_str,
31
+            $owner_uid) {
32 32
 
33
-		$guid = 'SHA1:' . sha1("ttshared:" . $url . $owner_uid); // include owner_uid to prevent global GUID clash
33
+        $guid = 'SHA1:' . sha1("ttshared:" . $url . $owner_uid); // include owner_uid to prevent global GUID clash
34 34
 
35
-		if (!$content) {
36
-			$pluginhost = new PluginHost();
37
-			$pluginhost->load_all(PluginHost::KIND_ALL, $owner_uid);
38
-			$pluginhost->load_data();
35
+        if (!$content) {
36
+            $pluginhost = new PluginHost();
37
+            $pluginhost->load_all(PluginHost::KIND_ALL, $owner_uid);
38
+            $pluginhost->load_data();
39 39
 
40
-			foreach ($pluginhost->get_hooks(PluginHost::HOOK_GET_FULL_TEXT) as $p) {
41
-				$extracted_content = $p->hook_get_full_text($url);
40
+            foreach ($pluginhost->get_hooks(PluginHost::HOOK_GET_FULL_TEXT) as $p) {
41
+                $extracted_content = $p->hook_get_full_text($url);
42 42
 
43
-				if ($extracted_content) {
44
-					$content = $extracted_content;
45
-					break;
46
-				}
47
-			}
48
-		}
43
+                if ($extracted_content) {
44
+                    $content = $extracted_content;
45
+                    break;
46
+                }
47
+            }
48
+        }
49 49
 
50
-		$content_hash = sha1($content);
50
+        $content_hash = sha1($content);
51 51
 
52
-		if ($labels_str != "") {
53
-			$labels = explode(",", $labels_str);
54
-		} else {
55
-			$labels = array();
56
-		}
52
+        if ($labels_str != "") {
53
+            $labels = explode(",", $labels_str);
54
+        } else {
55
+            $labels = array();
56
+        }
57 57
 
58
-		$rc = false;
58
+        $rc = false;
59 59
 
60
-		if (!$title) $title = $url;
61
-		if (!$title && !$url) return false;
60
+        if (!$title) $title = $url;
61
+        if (!$title && !$url) return false;
62 62
 
63
-		if (filter_var($url, FILTER_VALIDATE_URL) === false) return false;
63
+        if (filter_var($url, FILTER_VALIDATE_URL) === false) return false;
64 64
 
65
-		$pdo = Db::pdo();
65
+        $pdo = Db::pdo();
66 66
 
67
-		$pdo->beginTransaction();
67
+        $pdo->beginTransaction();
68 68
 
69
-		// only check for our user data here, others might have shared this with different content etc
70
-		$sth = $pdo->prepare("SELECT id FROM ttrss_entries, ttrss_user_entries WHERE
69
+        // only check for our user data here, others might have shared this with different content etc
70
+        $sth = $pdo->prepare("SELECT id FROM ttrss_entries, ttrss_user_entries WHERE
71 71
 			guid = ? AND ref_id = id AND owner_uid = ? LIMIT 1");
72
-		$sth->execute([$guid, $owner_uid]);
72
+        $sth->execute([$guid, $owner_uid]);
73 73
 
74
-		if ($row = $sth->fetch()) {
75
-			$ref_id = $row['id'];
74
+        if ($row = $sth->fetch()) {
75
+            $ref_id = $row['id'];
76 76
 
77
-			$sth = $pdo->prepare("SELECT int_id FROM ttrss_user_entries WHERE
77
+            $sth = $pdo->prepare("SELECT int_id FROM ttrss_user_entries WHERE
78 78
 				ref_id = ? AND owner_uid = ? LIMIT 1");
79 79
             $sth->execute([$ref_id, $owner_uid]);
80 80
 
81
-			if ($row = $sth->fetch()) {
82
-				$int_id = $row['int_id'];
81
+            if ($row = $sth->fetch()) {
82
+                $int_id = $row['int_id'];
83 83
 
84
-				$sth = $pdo->prepare("UPDATE ttrss_entries SET
84
+                $sth = $pdo->prepare("UPDATE ttrss_entries SET
85 85
 					content = ?, content_hash = ? WHERE id = ?");
86
-				$sth->execute([$content, $content_hash, $ref_id]);
86
+                $sth->execute([$content, $content_hash, $ref_id]);
87 87
 
88
-				if (DB_TYPE == "pgsql"){
89
-					$sth = $pdo->prepare("UPDATE ttrss_entries
88
+                if (DB_TYPE == "pgsql"){
89
+                    $sth = $pdo->prepare("UPDATE ttrss_entries
90 90
 					SET tsvector_combined = to_tsvector( :ts_content)
91 91
 					WHERE id = :id");
92
-					$params = [
93
-						":ts_content" => mb_substr(strip_tags($content ), 0, 900000),
94
-						":id" => $ref_id];
95
-					$sth->execute($params);
96
-				}
92
+                    $params = [
93
+                        ":ts_content" => mb_substr(strip_tags($content ), 0, 900000),
94
+                        ":id" => $ref_id];
95
+                    $sth->execute($params);
96
+                }
97 97
 
98
-				$sth = $pdo->prepare("UPDATE ttrss_user_entries SET published = true,
98
+                $sth = $pdo->prepare("UPDATE ttrss_user_entries SET published = true,
99 99
 						last_published = NOW() WHERE
100 100
 						int_id = ? AND owner_uid = ?");
101
-				$sth->execute([$int_id, $owner_uid]);
101
+                $sth->execute([$int_id, $owner_uid]);
102 102
 
103
-			} else {
103
+            } else {
104 104
 
105
-				$sth = $pdo->prepare("INSERT INTO ttrss_user_entries
105
+                $sth = $pdo->prepare("INSERT INTO ttrss_user_entries
106 106
 					(ref_id, uuid, feed_id, orig_feed_id, owner_uid, published, tag_cache, label_cache,
107 107
 						last_read, note, unread, last_published)
108 108
 					VALUES
109 109
 					(?, '', NULL, NULL, ?, true, '', '', NOW(), '', false, NOW())");
110
-				$sth->execute([$ref_id, $owner_uid]);
111
-			}
110
+                $sth->execute([$ref_id, $owner_uid]);
111
+            }
112 112
 
113
-			if (count($labels) != 0) {
114
-				foreach ($labels as $label) {
115
-					Labels::add_article($ref_id, trim($label), $owner_uid);
116
-				}
117
-			}
113
+            if (count($labels) != 0) {
114
+                foreach ($labels as $label) {
115
+                    Labels::add_article($ref_id, trim($label), $owner_uid);
116
+                }
117
+            }
118 118
 
119
-			$rc = true;
119
+            $rc = true;
120 120
 
121
-		} else {
122
-			$sth = $pdo->prepare("INSERT INTO ttrss_entries
121
+        } else {
122
+            $sth = $pdo->prepare("INSERT INTO ttrss_entries
123 123
 				(title, guid, link, updated, content, content_hash, date_entered, date_updated)
124 124
 				VALUES
125 125
 				(?, ?, ?, NOW(), ?, ?, NOW(), NOW())");
126
-			$sth->execute([$title, $guid, $url, $content, $content_hash]);
126
+            $sth->execute([$title, $guid, $url, $content, $content_hash]);
127 127
 
128
-			$sth = $pdo->prepare("SELECT id FROM ttrss_entries WHERE guid = ?");
129
-			$sth->execute([$guid]);
128
+            $sth = $pdo->prepare("SELECT id FROM ttrss_entries WHERE guid = ?");
129
+            $sth->execute([$guid]);
130 130
 
131
-			if ($row = $sth->fetch()) {
132
-				$ref_id = $row["id"];
133
-				if (DB_TYPE == "pgsql"){
134
-					$sth = $pdo->prepare("UPDATE ttrss_entries
131
+            if ($row = $sth->fetch()) {
132
+                $ref_id = $row["id"];
133
+                if (DB_TYPE == "pgsql"){
134
+                    $sth = $pdo->prepare("UPDATE ttrss_entries
135 135
 					SET tsvector_combined = to_tsvector( :ts_content)
136 136
 					WHERE id = :id");
137
-					$params = [
138
-						":ts_content" => mb_substr(strip_tags($content ), 0, 900000),
139
-						":id" => $ref_id];
140
-					$sth->execute($params);
141
-				}
142
-				$sth = $pdo->prepare("INSERT INTO ttrss_user_entries
137
+                    $params = [
138
+                        ":ts_content" => mb_substr(strip_tags($content ), 0, 900000),
139
+                        ":id" => $ref_id];
140
+                    $sth->execute($params);
141
+                }
142
+                $sth = $pdo->prepare("INSERT INTO ttrss_user_entries
143 143
 					(ref_id, uuid, feed_id, orig_feed_id, owner_uid, published, tag_cache, label_cache,
144 144
 						last_read, note, unread, last_published)
145 145
 					VALUES
146 146
 					(?, '', NULL, NULL, ?, true, '', '', NOW(), '', false, NOW())");
147
-				$sth->execute([$ref_id, $owner_uid]);
147
+                $sth->execute([$ref_id, $owner_uid]);
148 148
 
149
-				if (count($labels) != 0) {
150
-					foreach ($labels as $label) {
151
-						Labels::add_article($ref_id, trim($label), $owner_uid);
152
-					}
153
-				}
149
+                if (count($labels) != 0) {
150
+                    foreach ($labels as $label) {
151
+                        Labels::add_article($ref_id, trim($label), $owner_uid);
152
+                    }
153
+                }
154 154
 
155
-				$rc = true;
156
-			}
157
-		}
155
+                $rc = true;
156
+            }
157
+        }
158 158
 
159
-		$pdo->commit();
159
+        $pdo->commit();
160 160
 
161
-		return $rc;
162
-	}
161
+        return $rc;
162
+    }
163 163
 
164
-	public function editArticleTags() {
164
+    public function editArticleTags() {
165 165
 
166
-		$param = clean($_REQUEST['param']);
166
+        $param = clean($_REQUEST['param']);
167 167
 
168
-		$tags = Article::get_article_tags($param);
168
+        $tags = Article::get_article_tags($param);
169 169
 
170
-		$tags_str = join(", ", $tags);
170
+        $tags_str = join(", ", $tags);
171 171
 
172
-		print_hidden("id", "$param");
173
-		print_hidden("op", "article");
174
-		print_hidden("method", "setArticleTags");
172
+        print_hidden("id", "$param");
173
+        print_hidden("op", "article");
174
+        print_hidden("method", "setArticleTags");
175 175
 
176
-		print "<header class='horizontal'>" . __("Tags for this article (separated by commas):")."</header>";
176
+        print "<header class='horizontal'>" . __("Tags for this article (separated by commas):")."</header>";
177 177
 
178
-		print "<section>";
179
-		print "<textarea dojoType='dijit.form.SimpleTextarea' rows='4'
178
+        print "<section>";
179
+        print "<textarea dojoType='dijit.form.SimpleTextarea' rows='4'
180 180
 			style='height : 100px; font-size : 12px; width : 98%' id='tags_str'
181 181
 			name='tags_str'>$tags_str</textarea>
182 182
 		<div class='autocomplete' id='tags_choices'
183 183
 				style='display:none'></div>";
184
-		print "</section>";
184
+        print "</section>";
185 185
 
186
-		print "<footer>";
187
-		print "<button dojoType='dijit.form.Button'
186
+        print "<footer>";
187
+        print "<button dojoType='dijit.form.Button'
188 188
 			type='submit' class='alt-primary' onclick=\"dijit.byId('editTagsDlg').execute()\">".__('Save')."</button> ";
189
-		print "<button dojoType='dijit.form.Button'
189
+        print "<button dojoType='dijit.form.Button'
190 190
 			onclick=\"dijit.byId('editTagsDlg').hide()\">".__('Cancel')."</button>";
191
-		print "</footer>";
191
+        print "</footer>";
192 192
 
193
-	}
193
+    }
194 194
 
195
-	public function setScore() {
196
-		$ids = explode(",", clean($_REQUEST['id']));
197
-		$score = (int)clean($_REQUEST['score']);
195
+    public function setScore() {
196
+        $ids = explode(",", clean($_REQUEST['id']));
197
+        $score = (int)clean($_REQUEST['score']);
198 198
 
199
-		$ids_qmarks = arr_qmarks($ids);
199
+        $ids_qmarks = arr_qmarks($ids);
200 200
 
201
-		$sth = $this->pdo->prepare("UPDATE ttrss_user_entries SET
201
+        $sth = $this->pdo->prepare("UPDATE ttrss_user_entries SET
202 202
 			score = ? WHERE ref_id IN ($ids_qmarks) AND owner_uid = ?");
203 203
 
204
-		$sth->execute(array_merge([$score], $ids, [$_SESSION['uid']]));
204
+        $sth->execute(array_merge([$score], $ids, [$_SESSION['uid']]));
205 205
 
206
-		print json_encode(["id" => $ids, "score" => (int)$score]);
207
-	}
206
+        print json_encode(["id" => $ids, "score" => (int)$score]);
207
+    }
208 208
 
209
-	public function getScore() {
210
-		$id = clean($_REQUEST['id']);
209
+    public function getScore() {
210
+        $id = clean($_REQUEST['id']);
211 211
 
212
-		$sth = $this->pdo->prepare("SELECT score FROM ttrss_user_entries WHERE ref_id = ? AND owner_uid = ?");
213
-		$sth->execute([$id, $_SESSION['uid']]);
214
-		$row = $sth->fetch();
212
+        $sth = $this->pdo->prepare("SELECT score FROM ttrss_user_entries WHERE ref_id = ? AND owner_uid = ?");
213
+        $sth->execute([$id, $_SESSION['uid']]);
214
+        $row = $sth->fetch();
215 215
 
216
-		$score = $row['score'];
216
+        $score = $row['score'];
217 217
 
218
-		print json_encode(["id" => $id, "score" => (int)$score]);
219
-	}
218
+        print json_encode(["id" => $id, "score" => (int)$score]);
219
+    }
220 220
 
221 221
 
222
-	public function setArticleTags() {
222
+    public function setArticleTags() {
223 223
 
224
-		$id = clean($_REQUEST["id"]);
224
+        $id = clean($_REQUEST["id"]);
225 225
 
226
-		$tags_str = clean($_REQUEST["tags_str"]);
227
-		$tags = array_unique(trim_array(explode(",", $tags_str)));
226
+        $tags_str = clean($_REQUEST["tags_str"]);
227
+        $tags = array_unique(trim_array(explode(",", $tags_str)));
228 228
 
229
-		$this->pdo->beginTransaction();
229
+        $this->pdo->beginTransaction();
230 230
 
231
-		$sth = $this->pdo->prepare("SELECT int_id FROM ttrss_user_entries WHERE
231
+        $sth = $this->pdo->prepare("SELECT int_id FROM ttrss_user_entries WHERE
232 232
 				ref_id = ? AND owner_uid = ? LIMIT 1");
233
-		$sth->execute([$id, $_SESSION['uid']]);
233
+        $sth->execute([$id, $_SESSION['uid']]);
234 234
 
235
-		if ($row = $sth->fetch()) {
235
+        if ($row = $sth->fetch()) {
236 236
 
237
-			$tags_to_cache = array();
237
+            $tags_to_cache = array();
238 238
 
239
-			$int_id = $row['int_id'];
239
+            $int_id = $row['int_id'];
240 240
 
241
-			$sth = $this->pdo->prepare("DELETE FROM ttrss_tags WHERE
241
+            $sth = $this->pdo->prepare("DELETE FROM ttrss_tags WHERE
242 242
 				post_int_id = ? AND owner_uid = ?");
243
-			$sth->execute([$int_id, $_SESSION['uid']]);
243
+            $sth->execute([$int_id, $_SESSION['uid']]);
244 244
 
245
-			$tags = FeedItem_Common::normalize_categories($tags);
245
+            $tags = FeedItem_Common::normalize_categories($tags);
246 246
 
247
-			foreach ($tags as $tag) {
248
-				if ($tag != '') {
249
-					$sth = $this->pdo->prepare("INSERT INTO ttrss_tags
247
+            foreach ($tags as $tag) {
248
+                if ($tag != '') {
249
+                    $sth = $this->pdo->prepare("INSERT INTO ttrss_tags
250 250
 								(post_int_id, owner_uid, tag_name)
251 251
 								VALUES (?, ?, ?)");
252 252
 
253
-					$sth->execute([$int_id, $_SESSION['uid'], $tag]);
254
-				}
253
+                    $sth->execute([$int_id, $_SESSION['uid'], $tag]);
254
+                }
255 255
 
256
-				array_push($tags_to_cache, $tag);
257
-			}
256
+                array_push($tags_to_cache, $tag);
257
+            }
258 258
 
259
-			/* update tag cache */
259
+            /* update tag cache */
260 260
 
261
-			$tags_str = join(",", $tags_to_cache);
261
+            $tags_str = join(",", $tags_to_cache);
262 262
 
263
-			$sth = $this->pdo->prepare("UPDATE ttrss_user_entries
263
+            $sth = $this->pdo->prepare("UPDATE ttrss_user_entries
264 264
 				SET tag_cache = ? WHERE ref_id = ? AND owner_uid = ?");
265
-			$sth->execute([$tags_str, $id, $_SESSION['uid']]);
266
-		}
265
+            $sth->execute([$tags_str, $id, $_SESSION['uid']]);
266
+        }
267 267
 
268
-		$this->pdo->commit();
268
+        $this->pdo->commit();
269 269
 
270
-		$tags = Article::get_article_tags($id);
271
-		$tags_str = $this->format_tags_string($tags);
272
-		$tags_str_full = join(", ", $tags);
270
+        $tags = Article::get_article_tags($id);
271
+        $tags_str = $this->format_tags_string($tags);
272
+        $tags_str_full = join(", ", $tags);
273 273
 
274
-		if (!$tags_str_full) $tags_str_full = __("no tags");
274
+        if (!$tags_str_full) $tags_str_full = __("no tags");
275 275
 
276
-		print json_encode([
277
-			"id" => (int) $id,
278
-			"content" => $tags_str,
279
-			"content_full" => $tags_str_full
280
-		]);
281
-	}
276
+        print json_encode([
277
+            "id" => (int) $id,
278
+            "content" => $tags_str,
279
+            "content_full" => $tags_str_full
280
+        ]);
281
+    }
282 282
 
283 283
 
284
-	public function completeTags() {
285
-		$search = clean($_REQUEST["search"]);
284
+    public function completeTags() {
285
+        $search = clean($_REQUEST["search"]);
286 286
 
287
-		$sth = $this->pdo->prepare("SELECT DISTINCT tag_name FROM ttrss_tags
287
+        $sth = $this->pdo->prepare("SELECT DISTINCT tag_name FROM ttrss_tags
288 288
 				WHERE owner_uid = ? AND
289 289
 				tag_name LIKE ? ORDER BY tag_name
290 290
 				LIMIT 10");
291 291
 
292
-		$sth->execute([$_SESSION['uid'], "$search%"]);
292
+        $sth->execute([$_SESSION['uid'], "$search%"]);
293 293
 
294
-		print "<ul>";
295
-		while ($line = $sth->fetch()) {
296
-			print "<li>" . $line["tag_name"] . "</li>";
297
-		}
298
-		print "</ul>";
299
-	}
294
+        print "<ul>";
295
+        while ($line = $sth->fetch()) {
296
+            print "<li>" . $line["tag_name"] . "</li>";
297
+        }
298
+        print "</ul>";
299
+    }
300 300
 
301
-	public function assigntolabel() {
302
-		return $this->labelops(true);
303
-	}
301
+    public function assigntolabel() {
302
+        return $this->labelops(true);
303
+    }
304 304
 
305
-	public function removefromlabel() {
306
-		return $this->labelops(false);
307
-	}
305
+    public function removefromlabel() {
306
+        return $this->labelops(false);
307
+    }
308 308
 
309
-	private function labelops($assign) {
310
-		$reply = array();
309
+    private function labelops($assign) {
310
+        $reply = array();
311 311
 
312
-		$ids = explode(",", clean($_REQUEST["ids"]));
313
-		$label_id = clean($_REQUEST["lid"]);
312
+        $ids = explode(",", clean($_REQUEST["ids"]));
313
+        $label_id = clean($_REQUEST["lid"]);
314 314
 
315
-		$label = Labels::find_caption($label_id, $_SESSION["uid"]);
315
+        $label = Labels::find_caption($label_id, $_SESSION["uid"]);
316 316
 
317
-		$reply["info-for-headlines"] = array();
317
+        $reply["info-for-headlines"] = array();
318 318
 
319
-		if ($label) {
319
+        if ($label) {
320 320
 
321
-			foreach ($ids as $id) {
321
+            foreach ($ids as $id) {
322 322
 
323
-				if ($assign)
324
-					Labels::add_article($id, $label, $_SESSION["uid"]);
325
-				else
326
-					Labels::remove_article($id, $label, $_SESSION["uid"]);
323
+                if ($assign)
324
+                    Labels::add_article($id, $label, $_SESSION["uid"]);
325
+                else
326
+                    Labels::remove_article($id, $label, $_SESSION["uid"]);
327 327
 
328
-				$labels = $this->get_article_labels($id, $_SESSION["uid"]);
328
+                $labels = $this->get_article_labels($id, $_SESSION["uid"]);
329 329
 
330
-				array_push($reply["info-for-headlines"],
331
-				array("id" => $id, "labels" => $this->format_article_labels($labels)));
330
+                array_push($reply["info-for-headlines"],
331
+                array("id" => $id, "labels" => $this->format_article_labels($labels)));
332 332
 
333
-			}
334
-		}
333
+            }
334
+        }
335 335
 
336
-		$reply["message"] = "UPDATE_COUNTERS";
336
+        $reply["message"] = "UPDATE_COUNTERS";
337 337
 
338
-		print json_encode($reply);
339
-	}
338
+        print json_encode($reply);
339
+    }
340 340
 
341
-	public function getArticleFeed($id) {
342
-		$sth = $this->pdo->prepare("SELECT feed_id FROM ttrss_user_entries
341
+    public function getArticleFeed($id) {
342
+        $sth = $this->pdo->prepare("SELECT feed_id FROM ttrss_user_entries
343 343
 			WHERE ref_id = ? AND owner_uid = ?");
344
-		$sth->execute([$id, $_SESSION['uid']]);
344
+        $sth->execute([$id, $_SESSION['uid']]);
345 345
 
346
-		if ($row = $sth->fetch()) {
347
-			return $row["feed_id"];
348
-		} else {
349
-			return 0;
350
-		}
351
-	}
346
+        if ($row = $sth->fetch()) {
347
+            return $row["feed_id"];
348
+        } else {
349
+            return 0;
350
+        }
351
+    }
352 352
 
353
-	public static function format_article_enclosures($id, $always_display_enclosures,
354
-									   $article_content, $hide_images = false) {
353
+    public static function format_article_enclosures($id, $always_display_enclosures,
354
+                                        $article_content, $hide_images = false) {
355 355
 
356
-		$result = Article::get_article_enclosures($id);
357
-		$rv = '';
356
+        $result = Article::get_article_enclosures($id);
357
+        $rv = '';
358 358
 
359
-		foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_FORMAT_ENCLOSURES) as $plugin) {
360
-			$retval = $plugin->hook_format_enclosures($rv, $result, $id, $always_display_enclosures, $article_content, $hide_images);
361
-			if (is_array($retval)) {
362
-				$rv = $retval[0];
363
-				$result = $retval[1];
364
-			} else {
365
-				$rv = $retval;
366
-			}
367
-		}
368
-		unset($retval); // Unset to prevent breaking render if there are no HOOK_RENDER_ENCLOSURE hooks below.
359
+        foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_FORMAT_ENCLOSURES) as $plugin) {
360
+            $retval = $plugin->hook_format_enclosures($rv, $result, $id, $always_display_enclosures, $article_content, $hide_images);
361
+            if (is_array($retval)) {
362
+                $rv = $retval[0];
363
+                $result = $retval[1];
364
+            } else {
365
+                $rv = $retval;
366
+            }
367
+        }
368
+        unset($retval); // Unset to prevent breaking render if there are no HOOK_RENDER_ENCLOSURE hooks below.
369 369
 
370
-		if ($rv === '' && !empty($result)) {
371
-			$entries_html = array();
372
-			$entries = array();
373
-			$entries_inline = array();
370
+        if ($rv === '' && !empty($result)) {
371
+            $entries_html = array();
372
+            $entries = array();
373
+            $entries_inline = array();
374 374
 
375
-			foreach ($result as $line) {
375
+            foreach ($result as $line) {
376 376
 
377
-				foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_ENCLOSURE_ENTRY) as $plugin) {
378
-					$line = $plugin->hook_enclosure_entry($line, $id);
379
-				}
377
+                foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_ENCLOSURE_ENTRY) as $plugin) {
378
+                    $line = $plugin->hook_enclosure_entry($line, $id);
379
+                }
380 380
 
381
-				$url = $line["content_url"];
382
-				$ctype = $line["content_type"];
383
-				$title = $line["title"];
384
-				$width = $line["width"];
385
-				$height = $line["height"];
381
+                $url = $line["content_url"];
382
+                $ctype = $line["content_type"];
383
+                $title = $line["title"];
384
+                $width = $line["width"];
385
+                $height = $line["height"];
386 386
 
387
-				if (!$ctype) $ctype = __("unknown type");
387
+                if (!$ctype) $ctype = __("unknown type");
388 388
 
389
-				//$filename = substr($url, strrpos($url, "/")+1);
390
-				$filename = basename($url);
389
+                //$filename = substr($url, strrpos($url, "/")+1);
390
+                $filename = basename($url);
391 391
 
392
-				$player = format_inline_player($url, $ctype);
392
+                $player = format_inline_player($url, $ctype);
393 393
 
394
-				if ($player) array_push($entries_inline, $player);
394
+                if ($player) array_push($entries_inline, $player);
395 395
 
396 396
 #				$entry .= " <a target=\"_blank\" href=\"" . htmlspecialchars($url) . "\" rel=\"noopener noreferrer\">" .
397 397
 #					$filename . " (" . $ctype . ")" . "</a>";
398 398
 
399
-				$entry = "<div onclick=\"popupOpenUrl('".htmlspecialchars($url)."')\"
399
+                $entry = "<div onclick=\"popupOpenUrl('".htmlspecialchars($url)."')\"
400 400
 					dojoType=\"dijit.MenuItem\">$filename ($ctype)</div>";
401 401
 
402
-				array_push($entries_html, $entry);
402
+                array_push($entries_html, $entry);
403 403
 
404
-				$entry = array();
404
+                $entry = array();
405 405
 
406
-				$entry["type"] = $ctype;
407
-				$entry["filename"] = $filename;
408
-				$entry["url"] = $url;
409
-				$entry["title"] = $title;
410
-				$entry["width"] = $width;
411
-				$entry["height"] = $height;
406
+                $entry["type"] = $ctype;
407
+                $entry["filename"] = $filename;
408
+                $entry["url"] = $url;
409
+                $entry["title"] = $title;
410
+                $entry["width"] = $width;
411
+                $entry["height"] = $height;
412 412
 
413
-				array_push($entries, $entry);
414
-			}
413
+                array_push($entries, $entry);
414
+            }
415 415
 
416
-			if ($_SESSION['uid'] && !get_pref("STRIP_IMAGES") && !$_SESSION["bw_limit"]) {
417
-				if ($always_display_enclosures ||
418
-					!preg_match("/<img/i", $article_content)) {
416
+            if ($_SESSION['uid'] && !get_pref("STRIP_IMAGES") && !$_SESSION["bw_limit"]) {
417
+                if ($always_display_enclosures ||
418
+                    !preg_match("/<img/i", $article_content)) {
419 419
 
420
-					foreach ($entries as $entry) {
420
+                    foreach ($entries as $entry) {
421 421
 
422
-						foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_RENDER_ENCLOSURE) as $plugin)
423
-							$retval = $plugin->hook_render_enclosure($entry, $hide_images);
422
+                        foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_RENDER_ENCLOSURE) as $plugin)
423
+                            $retval = $plugin->hook_render_enclosure($entry, $hide_images);
424 424
 
425 425
 
426
-						if ($retval) {
427
-							$rv .= $retval;
428
-						} else {
426
+                        if ($retval) {
427
+                            $rv .= $retval;
428
+                        } else {
429 429
 
430
-							if (preg_match("/image/", $entry["type"])) {
430
+                            if (preg_match("/image/", $entry["type"])) {
431 431
 
432
-								if (!$hide_images) {
433
-									$encsize = '';
434
-									if ($entry['height'] > 0)
435
-										$encsize .= ' height="' . intval($entry['height']) . '"';
436
-									if ($entry['width'] > 0)
437
-										$encsize .= ' width="' . intval($entry['width']) . '"';
438
-									$rv .= "<p><img
432
+                                if (!$hide_images) {
433
+                                    $encsize = '';
434
+                                    if ($entry['height'] > 0)
435
+                                        $encsize .= ' height="' . intval($entry['height']) . '"';
436
+                                    if ($entry['width'] > 0)
437
+                                        $encsize .= ' width="' . intval($entry['width']) . '"';
438
+                                    $rv .= "<p><img
439 439
 										alt=\"".htmlspecialchars($entry["filename"])."\"
440 440
 										src=\"" .htmlspecialchars($entry["url"]) . "\"
441 441
 										" . $encsize . " /></p>";
442
-								} else {
443
-									$rv .= "<p><a target=\"_blank\" rel=\"noopener noreferrer\"
442
+                                } else {
443
+                                    $rv .= "<p><a target=\"_blank\" rel=\"noopener noreferrer\"
444 444
 										href=\"".htmlspecialchars($entry["url"])."\"
445 445
 										>" .htmlspecialchars($entry["url"]) . "</a></p>";
446
-								}
447
-
448
-								if ($entry['title']) {
449
-									$rv.= "<div class=\"enclosure_title\">${entry['title']}</div>";
450
-								}
451
-							}
452
-						}
453
-					}
454
-				}
455
-			}
456
-
457
-			if (count($entries_inline) > 0) {
458
-				//$rv .= "<hr clear='both'/>";
459
-				foreach ($entries_inline as $entry) { $rv .= $entry; };
460
-				$rv .= "<br clear='both'/>";
461
-			}
462
-
463
-			$rv .= "<div class=\"attachments\" dojoType=\"fox.form.DropDownButton\">".
464
-				"<span>" . __('Attachments')."</span>";
465
-
466
-			$rv .= "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
467
-
468
-			foreach ($entries as $entry) {
469
-				if ($entry["title"])
470
-					$title = " &mdash; " . truncate_string($entry["title"], 30);
471
-				else
472
-					$title = "";
473
-
474
-				if ($entry["filename"])
475
-					$filename = truncate_middle(htmlspecialchars($entry["filename"]), 60);
476
-				else
477
-					$filename = "";
478
-
479
-				$rv .= "<div onclick='popupOpenUrl(\"".htmlspecialchars($entry["url"])."\")'
446
+                                }
447
+
448
+                                if ($entry['title']) {
449
+                                    $rv.= "<div class=\"enclosure_title\">${entry['title']}</div>";
450
+                                }
451
+                            }
452
+                        }
453
+                    }
454
+                }
455
+            }
456
+
457
+            if (count($entries_inline) > 0) {
458
+                //$rv .= "<hr clear='both'/>";
459
+                foreach ($entries_inline as $entry) { $rv .= $entry; };
460
+                $rv .= "<br clear='both'/>";
461
+            }
462
+
463
+            $rv .= "<div class=\"attachments\" dojoType=\"fox.form.DropDownButton\">".
464
+                "<span>" . __('Attachments')."</span>";
465
+
466
+            $rv .= "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
467
+
468
+            foreach ($entries as $entry) {
469
+                if ($entry["title"])
470
+                    $title = " &mdash; " . truncate_string($entry["title"], 30);
471
+                else
472
+                    $title = "";
473
+
474
+                if ($entry["filename"])
475
+                    $filename = truncate_middle(htmlspecialchars($entry["filename"]), 60);
476
+                else
477
+                    $filename = "";
478
+
479
+                $rv .= "<div onclick='popupOpenUrl(\"".htmlspecialchars($entry["url"])."\")'
480 480
 					dojoType=\"dijit.MenuItem\">".$filename . $title."</div>";
481 481
 
482
-			};
482
+            };
483 483
 
484
-			$rv .= "</div>";
485
-			$rv .= "</div>";
486
-		}
484
+            $rv .= "</div>";
485
+            $rv .= "</div>";
486
+        }
487 487
 
488
-		return $rv;
489
-	}
488
+        return $rv;
489
+    }
490 490
 
491
-	public static function get_article_tags($id, $owner_uid = 0, $tag_cache = false) {
491
+    public static function get_article_tags($id, $owner_uid = 0, $tag_cache = false) {
492 492
 
493
-		$a_id = $id;
493
+        $a_id = $id;
494 494
 
495
-		if (!$owner_uid) $owner_uid = $_SESSION["uid"];
495
+        if (!$owner_uid) $owner_uid = $_SESSION["uid"];
496 496
 
497
-		$pdo = Db::pdo();
497
+        $pdo = Db::pdo();
498 498
 
499
-		$sth = $pdo->prepare("SELECT DISTINCT tag_name,
499
+        $sth = $pdo->prepare("SELECT DISTINCT tag_name,
500 500
 			owner_uid as owner FROM	ttrss_tags
501 501
 			WHERE post_int_id = (SELECT int_id FROM ttrss_user_entries WHERE
502 502
 			ref_id = ? AND owner_uid = ? LIMIT 1) ORDER BY tag_name");
503 503
 
504
-		$tags = array();
504
+        $tags = array();
505 505
 
506
-		/* check cache first */
506
+        /* check cache first */
507 507
 
508
-		if ($tag_cache === false) {
509
-			$csth = $pdo->prepare("SELECT tag_cache FROM ttrss_user_entries
508
+        if ($tag_cache === false) {
509
+            $csth = $pdo->prepare("SELECT tag_cache FROM ttrss_user_entries
510 510
 				WHERE ref_id = ? AND owner_uid = ?");
511
-			$csth->execute([$id, $owner_uid]);
511
+            $csth->execute([$id, $owner_uid]);
512 512
 
513
-			if ($row = $csth->fetch()) $tag_cache = $row["tag_cache"];
514
-		}
513
+            if ($row = $csth->fetch()) $tag_cache = $row["tag_cache"];
514
+        }
515 515
 
516
-		if ($tag_cache) {
517
-			$tags = explode(",", $tag_cache);
518
-		} else {
516
+        if ($tag_cache) {
517
+            $tags = explode(",", $tag_cache);
518
+        } else {
519 519
 
520
-			/* do it the hard way */
520
+            /* do it the hard way */
521 521
 
522
-			$sth->execute([$a_id, $owner_uid]);
522
+            $sth->execute([$a_id, $owner_uid]);
523 523
 
524
-			while ($tmp_line = $sth->fetch()) {
525
-				array_push($tags, $tmp_line["tag_name"]);
526
-			}
524
+            while ($tmp_line = $sth->fetch()) {
525
+                array_push($tags, $tmp_line["tag_name"]);
526
+            }
527 527
 
528
-			/* update the cache */
528
+            /* update the cache */
529 529
 
530
-			$tags_str = join(",", $tags);
530
+            $tags_str = join(",", $tags);
531 531
 
532
-			$sth = $pdo->prepare("UPDATE ttrss_user_entries
532
+            $sth = $pdo->prepare("UPDATE ttrss_user_entries
533 533
 				SET tag_cache = ? WHERE ref_id = ?
534 534
 				AND owner_uid = ?");
535
-			$sth->execute([$tags_str, $id, $owner_uid]);
536
-		}
535
+            $sth->execute([$tags_str, $id, $owner_uid]);
536
+        }
537 537
 
538
-		return $tags;
539
-	}
538
+        return $tags;
539
+    }
540 540
 
541
-	public static function format_tags_string($tags) {
542
-		if (!is_array($tags) || count($tags) == 0) {
543
-			return __("no tags");
544
-		} else {
545
-			$maxtags = min(5, count($tags));
546
-			$tags_str = "";
541
+    public static function format_tags_string($tags) {
542
+        if (!is_array($tags) || count($tags) == 0) {
543
+            return __("no tags");
544
+        } else {
545
+            $maxtags = min(5, count($tags));
546
+            $tags_str = "";
547 547
 
548
-			for ($i = 0; $i < $maxtags; $i++) {
549
-				$tags_str .= "<a class=\"tag\" href=\"#\" onclick=\"Feeds.open({feed:'".$tags[$i]."'})\">" . $tags[$i] . "</a>, ";
550
-			}
548
+            for ($i = 0; $i < $maxtags; $i++) {
549
+                $tags_str .= "<a class=\"tag\" href=\"#\" onclick=\"Feeds.open({feed:'".$tags[$i]."'})\">" . $tags[$i] . "</a>, ";
550
+            }
551 551
 
552
-			$tags_str = mb_substr($tags_str, 0, mb_strlen($tags_str)-2);
552
+            $tags_str = mb_substr($tags_str, 0, mb_strlen($tags_str)-2);
553 553
 
554
-			if (count($tags) > $maxtags)
555
-				$tags_str .= ", &hellip;";
554
+            if (count($tags) > $maxtags)
555
+                $tags_str .= ", &hellip;";
556 556
 
557
-			return $tags_str;
558
-		}
559
-	}
557
+            return $tags_str;
558
+        }
559
+    }
560 560
 
561
-	public static function format_article_labels($labels) {
561
+    public static function format_article_labels($labels) {
562 562
 
563
-		if (!is_array($labels)) return '';
563
+        if (!is_array($labels)) return '';
564 564
 
565
-		$labels_str = "";
565
+        $labels_str = "";
566 566
 
567
-		foreach ($labels as $l) {
568
-			$labels_str .= sprintf("<div class='label'
567
+        foreach ($labels as $l) {
568
+            $labels_str .= sprintf("<div class='label'
569 569
 				style='color : %s; background-color : %s'>%s</div>",
570
-				$l[2], $l[3], $l[1]);
571
-		}
570
+                $l[2], $l[3], $l[1]);
571
+        }
572 572
 
573
-		return $labels_str;
573
+        return $labels_str;
574 574
 
575
-	}
575
+    }
576 576
 
577
-	public static function format_article_note($id, $note, $allow_edit = true) {
577
+    public static function format_article_note($id, $note, $allow_edit = true) {
578 578
 
579
-		if ($allow_edit) {
580
-			$onclick = "onclick='Plugins.Note.edit($id)'";
581
-			$note_class = 'editable';
582
-		} else {
583
-			$onclick = '';
584
-			$note_class = '';
585
-		}
579
+        if ($allow_edit) {
580
+            $onclick = "onclick='Plugins.Note.edit($id)'";
581
+            $note_class = 'editable';
582
+        } else {
583
+            $onclick = '';
584
+            $note_class = '';
585
+        }
586 586
 
587
-		return "<div class='article-note $note_class'>
587
+        return "<div class='article-note $note_class'>
588 588
 			<i class='material-icons'>note</i>
589 589
 			<div $onclick class='body'>$note</div>
590 590
 			</div>";
591
-	}
591
+    }
592 592
 
593
-	public static function get_article_enclosures($id) {
593
+    public static function get_article_enclosures($id) {
594 594
 
595
-		$pdo = Db::pdo();
595
+        $pdo = Db::pdo();
596 596
 
597
-		$sth = $pdo->prepare("SELECT * FROM ttrss_enclosures
597
+        $sth = $pdo->prepare("SELECT * FROM ttrss_enclosures
598 598
 			WHERE post_id = ? AND content_url != ''");
599
-		$sth->execute([$id]);
599
+        $sth->execute([$id]);
600 600
 
601
-		$rv = array();
601
+        $rv = array();
602 602
 
603
-		$cache = new DiskCache("images");
603
+        $cache = new DiskCache("images");
604 604
 
605
-		while ($line = $sth->fetch()) {
605
+        while ($line = $sth->fetch()) {
606 606
 
607
-			if ($cache->exists(sha1($line["content_url"]))) {
608
-				$line["content_url"] = $cache->getUrl(sha1($line["content_url"]));
609
-			}
607
+            if ($cache->exists(sha1($line["content_url"]))) {
608
+                $line["content_url"] = $cache->getUrl(sha1($line["content_url"]));
609
+            }
610 610
 
611
-			array_push($rv, $line);
612
-		}
611
+            array_push($rv, $line);
612
+        }
613 613
 
614
-		return $rv;
615
-	}
614
+        return $rv;
615
+    }
616 616
 
617
-	public static function purge_orphans() {
617
+    public static function purge_orphans() {
618 618
 
619 619
         // purge orphaned posts in main content table
620 620
 
@@ -633,169 +633,169 @@  discard block
 block discarded – undo
633 633
         }
634 634
     }
635 635
 
636
-	public static function catchupArticlesById($ids, $cmode, $owner_uid = false) {
636
+    public static function catchupArticlesById($ids, $cmode, $owner_uid = false) {
637 637
 
638
-		if (!$owner_uid) $owner_uid = $_SESSION["uid"];
638
+        if (!$owner_uid) $owner_uid = $_SESSION["uid"];
639 639
 
640
-		$pdo = Db::pdo();
640
+        $pdo = Db::pdo();
641 641
 
642
-		$ids_qmarks = arr_qmarks($ids);
642
+        $ids_qmarks = arr_qmarks($ids);
643 643
 
644
-		if ($cmode == 1) {
645
-			$sth = $pdo->prepare("UPDATE ttrss_user_entries SET
644
+        if ($cmode == 1) {
645
+            $sth = $pdo->prepare("UPDATE ttrss_user_entries SET
646 646
 				unread = true
647 647
 					WHERE ref_id IN ($ids_qmarks) AND owner_uid = ?");
648
-		} else if ($cmode == 2) {
649
-			$sth = $pdo->prepare("UPDATE ttrss_user_entries SET
648
+        } else if ($cmode == 2) {
649
+            $sth = $pdo->prepare("UPDATE ttrss_user_entries SET
650 650
 				unread = NOT unread,last_read = NOW()
651 651
 					WHERE ref_id IN ($ids_qmarks) AND owner_uid = ?");
652
-		} else {
653
-			$sth = $pdo->prepare("UPDATE ttrss_user_entries SET
652
+        } else {
653
+            $sth = $pdo->prepare("UPDATE ttrss_user_entries SET
654 654
 				unread = false,last_read = NOW()
655 655
 					WHERE ref_id IN ($ids_qmarks) AND owner_uid = ?");
656
-		}
656
+        }
657 657
 
658
-		$sth->execute(array_merge($ids, [$owner_uid]));
658
+        $sth->execute(array_merge($ids, [$owner_uid]));
659 659
 
660
-		/* update ccache */
660
+        /* update ccache */
661 661
 
662
-		$sth = $pdo->prepare("SELECT DISTINCT feed_id FROM ttrss_user_entries
662
+        $sth = $pdo->prepare("SELECT DISTINCT feed_id FROM ttrss_user_entries
663 663
 			WHERE ref_id IN ($ids_qmarks) AND owner_uid = ?");
664
-		$sth->execute(array_merge($ids, [$owner_uid]));
664
+        $sth->execute(array_merge($ids, [$owner_uid]));
665 665
 
666
-		while ($line = $sth->fetch()) {
667
-			CCache::update($line["feed_id"], $owner_uid);
668
-		}
669
-	}
666
+        while ($line = $sth->fetch()) {
667
+            CCache::update($line["feed_id"], $owner_uid);
668
+        }
669
+    }
670 670
 
671
-	public static function getLastArticleId() {
672
-		$pdo = DB::pdo();
671
+    public static function getLastArticleId() {
672
+        $pdo = DB::pdo();
673 673
 
674
-		$sth = $pdo->prepare("SELECT ref_id AS id FROM ttrss_user_entries
674
+        $sth = $pdo->prepare("SELECT ref_id AS id FROM ttrss_user_entries
675 675
 			WHERE owner_uid = ? ORDER BY ref_id DESC LIMIT 1");
676
-		$sth->execute([$_SESSION['uid']]);
676
+        $sth->execute([$_SESSION['uid']]);
677 677
 
678
-		if ($row = $sth->fetch()) {
679
-			return $row['id'];
680
-		} else {
681
-			return -1;
682
-		}
683
-	}
678
+        if ($row = $sth->fetch()) {
679
+            return $row['id'];
680
+        } else {
681
+            return -1;
682
+        }
683
+    }
684 684
 
685
-	public static function get_article_labels($id, $owner_uid = false) {
686
-		$rv = array();
685
+    public static function get_article_labels($id, $owner_uid = false) {
686
+        $rv = array();
687 687
 
688
-		if (!$owner_uid) $owner_uid = $_SESSION["uid"];
688
+        if (!$owner_uid) $owner_uid = $_SESSION["uid"];
689 689
 
690
-		$pdo = Db::pdo();
690
+        $pdo = Db::pdo();
691 691
 
692
-		$sth = $pdo->prepare("SELECT label_cache FROM
692
+        $sth = $pdo->prepare("SELECT label_cache FROM
693 693
 			ttrss_user_entries WHERE ref_id = ? AND owner_uid = ?");
694
-		$sth->execute([$id, $owner_uid]);
694
+        $sth->execute([$id, $owner_uid]);
695 695
 
696
-		if ($row = $sth->fetch()) {
697
-			$label_cache = $row["label_cache"];
696
+        if ($row = $sth->fetch()) {
697
+            $label_cache = $row["label_cache"];
698 698
 
699
-			if ($label_cache) {
700
-				$tmp = json_decode($label_cache, true);
699
+            if ($label_cache) {
700
+                $tmp = json_decode($label_cache, true);
701 701
 
702
-				if (!$tmp || $tmp["no-labels"] == 1)
703
-					return $rv;
704
-				else
705
-					return $tmp;
706
-			}
707
-		}
702
+                if (!$tmp || $tmp["no-labels"] == 1)
703
+                    return $rv;
704
+                else
705
+                    return $tmp;
706
+            }
707
+        }
708 708
 
709
-		$sth = $pdo->prepare("SELECT DISTINCT label_id,caption,fg_color,bg_color
709
+        $sth = $pdo->prepare("SELECT DISTINCT label_id,caption,fg_color,bg_color
710 710
 				FROM ttrss_labels2, ttrss_user_labels2
711 711
 			WHERE id = label_id
712 712
 				AND article_id = ?
713 713
 				AND owner_uid = ?
714 714
 			ORDER BY caption");
715
-		$sth->execute([$id, $owner_uid]);
716
-
717
-		while ($line = $sth->fetch()) {
718
-			$rk = array(Labels::label_to_feed_id($line["label_id"]),
719
-				$line["caption"], $line["fg_color"],
720
-				$line["bg_color"]);
721
-			array_push($rv, $rk);
722
-		}
723
-
724
-		if (count($rv) > 0)
725
-			Labels::update_cache($owner_uid, $id, $rv);
726
-		else
727
-			Labels::update_cache($owner_uid, $id, array("no-labels" => 1));
728
-
729
-		return $rv;
730
-	}
731
-
732
-	public static function get_article_image($enclosures, $content, $site_url) {
733
-
734
-		$article_image = "";
735
-		$article_stream = "";
736
-
737
-		foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_ARTICLE_IMAGE) as $p) {
738
-			list ($article_image, $article_stream, $content) = $p->hook_article_image($enclosures, $content, $site_url);
739
-		}
740
-
741
-		if (!$article_image && !$article_stream) {
742
-			$tmpdoc = new DOMDocument();
743
-
744
-			if (@$tmpdoc->loadHTML('<?xml encoding="UTF-8">' . mb_substr($content, 0, 131070))) {
745
-				$tmpxpath = new DOMXPath($tmpdoc);
746
-				$elems = $tmpxpath->query('(//img[@src]|//video[@poster]|//iframe[contains(@src , "youtube.com/embed/")])');
747
-
748
-				foreach ($elems as $e) {
749
-					if ($e->nodeName == "iframe") {
750
-						$matches = [];
751
-						if (preg_match("/\/embed\/([\w-]+)/", $e->getAttribute("src"), $matches)) {
752
-							$article_image = "https://img.youtube.com/vi/" . $matches[1] . "/hqdefault.jpg";
753
-							$article_stream = "https://youtu.be/" . $matches[1];
754
-							break;
755
-						}
756
-					} else if ($e->nodeName == "video") {
757
-						$article_image = $e->getAttribute("poster");
758
-
759
-						$src = $tmpxpath->query("//source[@src]", $e)->item(0);
760
-
761
-						if ($src) {
762
-							$article_stream = $src->getAttribute("src");
763
-						}
764
-
765
-						break;
766
-					} else if ($e->nodeName == 'img') {
767
-						if (mb_strpos($e->getAttribute("src"), "data:") !== 0) {
768
-							$article_image = $e->getAttribute("src");
769
-						}
770
-						break;
771
-					}
772
-				}
773
-			}
774
-
775
-			if (!$article_image)
776
-				foreach ($enclosures as $enc) {
777
-					if (strpos($enc["content_type"], "image/") !== false) {
778
-						$article_image = $enc["content_url"];
779
-						break;
780
-					}
781
-				}
782
-
783
-			if ($article_image)
784
-				$article_image = rewrite_relative_url($site_url, $article_image);
785
-
786
-			if ($article_stream)
787
-				$article_stream = rewrite_relative_url($site_url, $article_stream);
788
-		}
789
-
790
-		$cache = new DiskCache("images");
791
-
792
-		if ($article_image && $cache->exists(sha1($article_image)))
793
-			$article_image = $cache->getUrl(sha1($article_image));
794
-
795
-		if ($article_stream && $cache->exists(sha1($article_stream)))
796
-			$article_stream = $cache->getUrl(sha1($article_stream));
797
-
798
-		return [$article_image, $article_stream];
799
-	}
715
+        $sth->execute([$id, $owner_uid]);
716
+
717
+        while ($line = $sth->fetch()) {
718
+            $rk = array(Labels::label_to_feed_id($line["label_id"]),
719
+                $line["caption"], $line["fg_color"],
720
+                $line["bg_color"]);
721
+            array_push($rv, $rk);
722
+        }
723
+
724
+        if (count($rv) > 0)
725
+            Labels::update_cache($owner_uid, $id, $rv);
726
+        else
727
+            Labels::update_cache($owner_uid, $id, array("no-labels" => 1));
728
+
729
+        return $rv;
730
+    }
731
+
732
+    public static function get_article_image($enclosures, $content, $site_url) {
733
+
734
+        $article_image = "";
735
+        $article_stream = "";
736
+
737
+        foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_ARTICLE_IMAGE) as $p) {
738
+            list ($article_image, $article_stream, $content) = $p->hook_article_image($enclosures, $content, $site_url);
739
+        }
740
+
741
+        if (!$article_image && !$article_stream) {
742
+            $tmpdoc = new DOMDocument();
743
+
744
+            if (@$tmpdoc->loadHTML('<?xml encoding="UTF-8">' . mb_substr($content, 0, 131070))) {
745
+                $tmpxpath = new DOMXPath($tmpdoc);
746
+                $elems = $tmpxpath->query('(//img[@src]|//video[@poster]|//iframe[contains(@src , "youtube.com/embed/")])');
747
+
748
+                foreach ($elems as $e) {
749
+                    if ($e->nodeName == "iframe") {
750
+                        $matches = [];
751
+                        if (preg_match("/\/embed\/([\w-]+)/", $e->getAttribute("src"), $matches)) {
752
+                            $article_image = "https://img.youtube.com/vi/" . $matches[1] . "/hqdefault.jpg";
753
+                            $article_stream = "https://youtu.be/" . $matches[1];
754
+                            break;
755
+                        }
756
+                    } else if ($e->nodeName == "video") {
757
+                        $article_image = $e->getAttribute("poster");
758
+
759
+                        $src = $tmpxpath->query("//source[@src]", $e)->item(0);
760
+
761
+                        if ($src) {
762
+                            $article_stream = $src->getAttribute("src");
763
+                        }
764
+
765
+                        break;
766
+                    } else if ($e->nodeName == 'img') {
767
+                        if (mb_strpos($e->getAttribute("src"), "data:") !== 0) {
768
+                            $article_image = $e->getAttribute("src");
769
+                        }
770
+                        break;
771
+                    }
772
+                }
773
+            }
774
+
775
+            if (!$article_image)
776
+                foreach ($enclosures as $enc) {
777
+                    if (strpos($enc["content_type"], "image/") !== false) {
778
+                        $article_image = $enc["content_url"];
779
+                        break;
780
+                    }
781
+                }
782
+
783
+            if ($article_image)
784
+                $article_image = rewrite_relative_url($site_url, $article_image);
785
+
786
+            if ($article_stream)
787
+                $article_stream = rewrite_relative_url($site_url, $article_stream);
788
+        }
789
+
790
+        $cache = new DiskCache("images");
791
+
792
+        if ($article_image && $cache->exists(sha1($article_image)))
793
+            $article_image = $cache->getUrl(sha1($article_image));
794
+
795
+        if ($article_stream && $cache->exists(sha1($article_stream)))
796
+            $article_stream = $cache->getUrl(sha1($article_stream));
797
+
798
+        return [$article_image, $article_stream];
799
+    }
800 800
 
801 801
 }
Please login to merge, or discard this patch.
classes/diskcache.php 1 patch
Indentation   +148 added lines, -148 removed lines patch added patch discarded remove patch
@@ -1,151 +1,151 @@
 block discarded – undo
1 1
 <?php
2 2
 class DiskCache {
3
-	private $dir;
4
-
5
-	public function __construct($dir) {
6
-		$this->dir = CACHE_DIR . "/" . clean_filename($dir);
7
-	}
8
-
9
-	public function getDir() {
10
-		return $this->dir;
11
-	}
12
-
13
-	public function makeDir() {
14
-		if (!is_dir($this->dir)) {
15
-			return mkdir($this->dir);
16
-		}
17
-	}
18
-
19
-	public function isWritable($filename = "") {
20
-		if ($filename) {
21
-			if (file_exists($this->getFullPath($filename)))
22
-				return is_writable($this->getFullPath($filename));
23
-			else
24
-				return is_writable($this->dir);
25
-		} else {
26
-			return is_writable($this->dir);
27
-		}
28
-	}
29
-
30
-	public function exists($filename) {
31
-		return file_exists($this->getFullPath($filename));
32
-	}
33
-
34
-	public function getSize($filename) {
35
-		if ($this->exists($filename))
36
-			return filesize($this->getFullPath($filename));
37
-		else
38
-			return -1;
39
-	}
40
-
41
-	public function getFullPath($filename) {
42
-		$filename = clean_filename($filename);
43
-
44
-		return $this->dir . "/" . $filename;
45
-	}
46
-
47
-	public function put($filename, $data) {
48
-		return file_put_contents($this->getFullPath($filename), $data);
49
-	}
50
-
51
-	public function touch($filename) {
52
-		return touch($this->getFullPath($filename));
53
-	}
54
-
55
-	public function get($filename) {
56
-		if ($this->exists($filename))
57
-			return file_get_contents($this->getFullPath($filename));
58
-		else
59
-			return null;
60
-	}
61
-
62
-	public function getMimeType($filename) {
63
-		if ($this->exists($filename))
64
-			return mime_content_type($this->getFullPath($filename));
65
-		else
66
-			return null;
67
-	}
68
-
69
-	public function send($filename) {
70
-		header("Content-Disposition: inline; filename=\"$filename\"");
71
-
72
-		return send_local_file($this->getFullPath($filename));
73
-	}
74
-
75
-	public function getUrl($filename) {
76
-		return get_self_url_prefix() . "/public.php?op=cached_url&file=" . basename($this->dir) . "/" . $filename;
77
-	}
78
-
79
-	// check for locally cached (media) URLs and rewrite to local versions
80
-	// this is called separately after sanitize() and plugin render article hooks to allow
81
-	// plugins work on original source URLs used before caching
82
-	static public function rewriteUrls($str)
83
-	{
84
-		$res = trim($str);
85
-		if (!$res) return '';
86
-
87
-		$doc = new DOMDocument();
88
-		if ($doc->loadHTML('<?xml encoding="UTF-8">' . $res)) {
89
-			$xpath = new DOMXPath($doc);
90
-			$cache = new DiskCache("images");
91
-
92
-			$entries = $xpath->query('(//img[@src]|//picture/source[@src]|//video[@poster]|//video/source[@src]|//audio/source[@src])');
93
-
94
-			$need_saving = false;
95
-
96
-			foreach ($entries as $entry) {
97
-
98
-				if ($entry->hasAttribute('src') || $entry->hasAttribute('poster')) {
99
-
100
-					// should be already absolutized because this is called after sanitize()
101
-					$src = $entry->hasAttribute('poster') ? $entry->getAttribute('poster') : $entry->getAttribute('src');
102
-					$cached_filename = sha1($src);
103
-
104
-					if ($cache->exists($cached_filename)) {
105
-
106
-						$src = $cache->getUrl(sha1($src));
107
-
108
-						if ($entry->hasAttribute('poster'))
109
-							$entry->setAttribute('poster', $src);
110
-						else {
111
-							$entry->setAttribute('src', $src);
112
-							$entry->removeAttribute("srcset");
113
-						}
114
-
115
-						$need_saving = true;
116
-					}
117
-				}
118
-			}
119
-
120
-			if ($need_saving) {
121
-				$doc->removeChild($doc->firstChild); //remove doctype
122
-				$res = $doc->saveHTML();
123
-			}
124
-		}
125
-		return $res;
126
-	}
127
-
128
-	public static function expire() {
129
-		$dirs = array_filter(glob(CACHE_DIR . "/*"), "is_dir");
130
-
131
-		foreach ($dirs as $cache_dir) {
132
-			$num_deleted = 0;
133
-
134
-			if (is_writable($cache_dir) && !file_exists("$cache_dir/.no-auto-expiry")) {
135
-				$files = glob("$cache_dir/*");
136
-
137
-				if ($files) {
138
-					foreach ($files as $file) {
139
-						if (time() - filemtime($file) > 86400*CACHE_MAX_DAYS) {
140
-							unlink($file);
141
-
142
-							++$num_deleted;
143
-						}
144
-					}
145
-				}
146
-
147
-				Debug::log("expired $cache_dir: removed $num_deleted files.");
148
-			}
149
-		}
150
-	}
3
+    private $dir;
4
+
5
+    public function __construct($dir) {
6
+        $this->dir = CACHE_DIR . "/" . clean_filename($dir);
7
+    }
8
+
9
+    public function getDir() {
10
+        return $this->dir;
11
+    }
12
+
13
+    public function makeDir() {
14
+        if (!is_dir($this->dir)) {
15
+            return mkdir($this->dir);
16
+        }
17
+    }
18
+
19
+    public function isWritable($filename = "") {
20
+        if ($filename) {
21
+            if (file_exists($this->getFullPath($filename)))
22
+                return is_writable($this->getFullPath($filename));
23
+            else
24
+                return is_writable($this->dir);
25
+        } else {
26
+            return is_writable($this->dir);
27
+        }
28
+    }
29
+
30
+    public function exists($filename) {
31
+        return file_exists($this->getFullPath($filename));
32
+    }
33
+
34
+    public function getSize($filename) {
35
+        if ($this->exists($filename))
36
+            return filesize($this->getFullPath($filename));
37
+        else
38
+            return -1;
39
+    }
40
+
41
+    public function getFullPath($filename) {
42
+        $filename = clean_filename($filename);
43
+
44
+        return $this->dir . "/" . $filename;
45
+    }
46
+
47
+    public function put($filename, $data) {
48
+        return file_put_contents($this->getFullPath($filename), $data);
49
+    }
50
+
51
+    public function touch($filename) {
52
+        return touch($this->getFullPath($filename));
53
+    }
54
+
55
+    public function get($filename) {
56
+        if ($this->exists($filename))
57
+            return file_get_contents($this->getFullPath($filename));
58
+        else
59
+            return null;
60
+    }
61
+
62
+    public function getMimeType($filename) {
63
+        if ($this->exists($filename))
64
+            return mime_content_type($this->getFullPath($filename));
65
+        else
66
+            return null;
67
+    }
68
+
69
+    public function send($filename) {
70
+        header("Content-Disposition: inline; filename=\"$filename\"");
71
+
72
+        return send_local_file($this->getFullPath($filename));
73
+    }
74
+
75
+    public function getUrl($filename) {
76
+        return get_self_url_prefix() . "/public.php?op=cached_url&file=" . basename($this->dir) . "/" . $filename;
77
+    }
78
+
79
+    // check for locally cached (media) URLs and rewrite to local versions
80
+    // this is called separately after sanitize() and plugin render article hooks to allow
81
+    // plugins work on original source URLs used before caching
82
+    static public function rewriteUrls($str)
83
+    {
84
+        $res = trim($str);
85
+        if (!$res) return '';
86
+
87
+        $doc = new DOMDocument();
88
+        if ($doc->loadHTML('<?xml encoding="UTF-8">' . $res)) {
89
+            $xpath = new DOMXPath($doc);
90
+            $cache = new DiskCache("images");
91
+
92
+            $entries = $xpath->query('(//img[@src]|//picture/source[@src]|//video[@poster]|//video/source[@src]|//audio/source[@src])');
93
+
94
+            $need_saving = false;
95
+
96
+            foreach ($entries as $entry) {
97
+
98
+                if ($entry->hasAttribute('src') || $entry->hasAttribute('poster')) {
99
+
100
+                    // should be already absolutized because this is called after sanitize()
101
+                    $src = $entry->hasAttribute('poster') ? $entry->getAttribute('poster') : $entry->getAttribute('src');
102
+                    $cached_filename = sha1($src);
103
+
104
+                    if ($cache->exists($cached_filename)) {
105
+
106
+                        $src = $cache->getUrl(sha1($src));
107
+
108
+                        if ($entry->hasAttribute('poster'))
109
+                            $entry->setAttribute('poster', $src);
110
+                        else {
111
+                            $entry->setAttribute('src', $src);
112
+                            $entry->removeAttribute("srcset");
113
+                        }
114
+
115
+                        $need_saving = true;
116
+                    }
117
+                }
118
+            }
119
+
120
+            if ($need_saving) {
121
+                $doc->removeChild($doc->firstChild); //remove doctype
122
+                $res = $doc->saveHTML();
123
+            }
124
+        }
125
+        return $res;
126
+    }
127
+
128
+    public static function expire() {
129
+        $dirs = array_filter(glob(CACHE_DIR . "/*"), "is_dir");
130
+
131
+        foreach ($dirs as $cache_dir) {
132
+            $num_deleted = 0;
133
+
134
+            if (is_writable($cache_dir) && !file_exists("$cache_dir/.no-auto-expiry")) {
135
+                $files = glob("$cache_dir/*");
136
+
137
+                if ($files) {
138
+                    foreach ($files as $file) {
139
+                        if (time() - filemtime($file) > 86400*CACHE_MAX_DAYS) {
140
+                            unlink($file);
141
+
142
+                            ++$num_deleted;
143
+                        }
144
+                    }
145
+                }
146
+
147
+                Debug::log("expired $cache_dir: removed $num_deleted files.");
148
+            }
149
+        }
150
+    }
151 151
 }
Please login to merge, or discard this patch.
plugins/af_readability/init.php 1 patch
Indentation   +188 added lines, -188 removed lines patch added patch discarded remove patch
@@ -4,65 +4,65 @@  discard block
 block discarded – undo
4 4
 
5 5
 class Af_Readability extends Plugin {
6 6
 
7
-	/* @var PluginHost $host */
8
-	private $host;
7
+    /* @var PluginHost $host */
8
+    private $host;
9 9
 
10
-	public function about() {
11
-		return array(1.0,
12
-			"Try to inline article content using Readability",
13
-			"fox");
14
-	}
10
+    public function about() {
11
+        return array(1.0,
12
+            "Try to inline article content using Readability",
13
+            "fox");
14
+    }
15 15
 
16
-	public function flags() {
17
-		return array("needs_curl" => true);
18
-	}
16
+    public function flags() {
17
+        return array("needs_curl" => true);
18
+    }
19 19
 
20
-	public function save() {
21
-		$enable_share_anything = checkbox_to_sql_bool($_POST["enable_share_anything"]);
20
+    public function save() {
21
+        $enable_share_anything = checkbox_to_sql_bool($_POST["enable_share_anything"]);
22 22
 
23
-		$this->host->set($this, "enable_share_anything", $enable_share_anything);
23
+        $this->host->set($this, "enable_share_anything", $enable_share_anything);
24 24
 
25
-		echo __("Data saved.");
26
-	}
25
+        echo __("Data saved.");
26
+    }
27 27
 
28
-	public function init($host)
29
-	{
30
-		$this->host = $host;
28
+    public function init($host)
29
+    {
30
+        $this->host = $host;
31 31
 
32
-		if (version_compare(PHP_VERSION, '7.0.0', '<')) {
33
-			user_error("af_readability requires PHP 7.0", E_USER_WARNING);
34
-			return;
35
-		}
32
+        if (version_compare(PHP_VERSION, '7.0.0', '<')) {
33
+            user_error("af_readability requires PHP 7.0", E_USER_WARNING);
34
+            return;
35
+        }
36 36
 
37
-		$host->add_hook($host::HOOK_ARTICLE_FILTER, $this);
38
-		$host->add_hook($host::HOOK_PREFS_TAB, $this);
39
-		$host->add_hook($host::HOOK_PREFS_EDIT_FEED, $this);
40
-		$host->add_hook($host::HOOK_PREFS_SAVE_FEED, $this);
37
+        $host->add_hook($host::HOOK_ARTICLE_FILTER, $this);
38
+        $host->add_hook($host::HOOK_PREFS_TAB, $this);
39
+        $host->add_hook($host::HOOK_PREFS_EDIT_FEED, $this);
40
+        $host->add_hook($host::HOOK_PREFS_SAVE_FEED, $this);
41 41
 
42
-		// Note: we have to install the hook even if disabled because init() is being run before plugin data has loaded
43
-		// so we can't check for our storage-set options here
44
-		$host->add_hook($host::HOOK_GET_FULL_TEXT, $this);
42
+        // Note: we have to install the hook even if disabled because init() is being run before plugin data has loaded
43
+        // so we can't check for our storage-set options here
44
+        $host->add_hook($host::HOOK_GET_FULL_TEXT, $this);
45 45
 
46
-		$host->add_filter_action($this, "action_inline", __("Inline content"));
47
-	}
46
+        $host->add_filter_action($this, "action_inline", __("Inline content"));
47
+    }
48 48
 
49
-	public function hook_prefs_tab($args) {
50
-		if ($args != "prefFeeds") return;
49
+    public function hook_prefs_tab($args) {
50
+        if ($args != "prefFeeds") return;
51 51
 
52
-		print "<div dojoType='dijit.layout.AccordionPane'
52
+        print "<div dojoType='dijit.layout.AccordionPane'
53 53
 			title=\"<i class='material-icons'>extension</i> ".__('Readability settings (af_readability)')."\">";
54 54
 
55
-		if (version_compare(PHP_VERSION, '7.0.0', '<')) {
56
-			print_error("This plugin requires PHP 7.0.");
57
-		} else {
55
+        if (version_compare(PHP_VERSION, '7.0.0', '<')) {
56
+            print_error("This plugin requires PHP 7.0.");
57
+        } else {
58 58
 
59
-			print "<h2>" . __("Global settings") . "</h2>";
59
+            print "<h2>" . __("Global settings") . "</h2>";
60 60
 
61
-			print_notice("Enable for specific feeds in the feed editor.");
61
+            print_notice("Enable for specific feeds in the feed editor.");
62 62
 
63
-			print "<form dojoType='dijit.form.Form'>";
63
+            print "<form dojoType='dijit.form.Form'>";
64 64
 
65
-			print "<script type='dojo/method' event='onSubmit' args='evt'>
65
+            print "<script type='dojo/method' event='onSubmit' args='evt'>
66 66
 			evt.preventDefault();
67 67
 			if (this.validate()) {
68 68
 				console.log(dojo.objectToQuery(this.getValues()));
@@ -76,212 +76,212 @@  discard block
 block discarded – undo
76 76
 			}
77 77
 			</script>";
78 78
 
79
-			print_hidden("op", "pluginhandler");
80
-			print_hidden("method", "save");
81
-			print_hidden("plugin", "af_readability");
79
+            print_hidden("op", "pluginhandler");
80
+            print_hidden("method", "save");
81
+            print_hidden("plugin", "af_readability");
82 82
 
83
-			$enable_share_anything = $this->host->get($this, "enable_share_anything");
83
+            $enable_share_anything = $this->host->get($this, "enable_share_anything");
84 84
 
85
-			print "<fieldset>";
86
-			print "<label class='checkbox'> ";
87
-			print_checkbox("enable_share_anything", $enable_share_anything);
88
-			print " " . __("Provide full-text services to core code (bookmarklets) and other plugins");
89
-			print "</label>";
90
-			print "</fieldset>";
85
+            print "<fieldset>";
86
+            print "<label class='checkbox'> ";
87
+            print_checkbox("enable_share_anything", $enable_share_anything);
88
+            print " " . __("Provide full-text services to core code (bookmarklets) and other plugins");
89
+            print "</label>";
90
+            print "</fieldset>";
91 91
 
92
-			print_button("submit", __("Save"), "class='alt-primary'");
93
-			print "</form>";
92
+            print_button("submit", __("Save"), "class='alt-primary'");
93
+            print "</form>";
94 94
 
95
-			$enabled_feeds = $this->host->get($this, "enabled_feeds");
96
-			if (!is_array($enabled_feeds)) $enabled_feeds = array();
95
+            $enabled_feeds = $this->host->get($this, "enabled_feeds");
96
+            if (!is_array($enabled_feeds)) $enabled_feeds = array();
97 97
 
98
-			$enabled_feeds = $this->filter_unknown_feeds($enabled_feeds);
99
-			$this->host->set($this, "enabled_feeds", $enabled_feeds);
98
+            $enabled_feeds = $this->filter_unknown_feeds($enabled_feeds);
99
+            $this->host->set($this, "enabled_feeds", $enabled_feeds);
100 100
 
101
-			if (count($enabled_feeds) > 0) {
102
-				print "<h3>" . __("Currently enabled for (click to edit):") . "</h3>";
101
+            if (count($enabled_feeds) > 0) {
102
+                print "<h3>" . __("Currently enabled for (click to edit):") . "</h3>";
103 103
 
104
-				print "<ul class='panel panel-scrollable list list-unstyled'>";
105
-				foreach ($enabled_feeds as $f) {
106
-					print "<li><i class='material-icons'>rss_feed</i> <a href='#'
104
+                print "<ul class='panel panel-scrollable list list-unstyled'>";
105
+                foreach ($enabled_feeds as $f) {
106
+                    print "<li><i class='material-icons'>rss_feed</i> <a href='#'
107 107
 						onclick='CommonDialogs.editFeed($f)'>".
108
-						Feeds::getFeedTitle($f) . "</a></li>";
109
-				}
110
-				print "</ul>";
111
-			}
108
+                        Feeds::getFeedTitle($f) . "</a></li>";
109
+                }
110
+                print "</ul>";
111
+            }
112 112
 
113
-		}
113
+        }
114 114
 
115
-		print "</div>";
116
-	}
115
+        print "</div>";
116
+    }
117 117
 
118
-	public function hook_prefs_edit_feed($feed_id) {
119
-		print "<header>".__("Readability")."</header>";
120
-		print "<section>";
118
+    public function hook_prefs_edit_feed($feed_id) {
119
+        print "<header>".__("Readability")."</header>";
120
+        print "<section>";
121 121
 
122
-		$enabled_feeds = $this->host->get($this, "enabled_feeds");
123
-		if (!is_array($enabled_feeds)) $enabled_feeds = array();
122
+        $enabled_feeds = $this->host->get($this, "enabled_feeds");
123
+        if (!is_array($enabled_feeds)) $enabled_feeds = array();
124 124
 
125
-		$key = array_search($feed_id, $enabled_feeds);
126
-		$checked = $key !== false ? "checked" : "";
125
+        $key = array_search($feed_id, $enabled_feeds);
126
+        $checked = $key !== false ? "checked" : "";
127 127
 
128
-		print "<fieldset>";
128
+        print "<fieldset>";
129 129
 
130
-		print "<label class='checkbox'><input dojoType='dijit.form.CheckBox' type='checkbox' id='af_readability_enabled'
130
+        print "<label class='checkbox'><input dojoType='dijit.form.CheckBox' type='checkbox' id='af_readability_enabled'
131 131
 			name='af_readability_enabled' $checked>&nbsp;".__('Inline article content')."</label>";
132 132
 
133
-		print "</fieldset>";
133
+        print "</fieldset>";
134 134
 
135
-		print "</section>";
136
-	}
135
+        print "</section>";
136
+    }
137 137
 
138
-	public function hook_prefs_save_feed($feed_id) {
139
-		$enabled_feeds = $this->host->get($this, "enabled_feeds");
140
-		if (!is_array($enabled_feeds)) $enabled_feeds = array();
138
+    public function hook_prefs_save_feed($feed_id) {
139
+        $enabled_feeds = $this->host->get($this, "enabled_feeds");
140
+        if (!is_array($enabled_feeds)) $enabled_feeds = array();
141 141
 
142
-		$enable = checkbox_to_sql_bool($_POST["af_readability_enabled"]);
143
-		$key = array_search($feed_id, $enabled_feeds);
142
+        $enable = checkbox_to_sql_bool($_POST["af_readability_enabled"]);
143
+        $key = array_search($feed_id, $enabled_feeds);
144 144
 
145
-		if ($enable) {
146
-			if ($key === false) {
147
-				array_push($enabled_feeds, $feed_id);
148
-			}
149
-		} else {
150
-			if ($key !== false) {
151
-				unset($enabled_feeds[$key]);
152
-			}
153
-		}
145
+        if ($enable) {
146
+            if ($key === false) {
147
+                array_push($enabled_feeds, $feed_id);
148
+            }
149
+        } else {
150
+            if ($key !== false) {
151
+                unset($enabled_feeds[$key]);
152
+            }
153
+        }
154 154
 
155
-		$this->host->set($this, "enabled_feeds", $enabled_feeds);
156
-	}
155
+        $this->host->set($this, "enabled_feeds", $enabled_feeds);
156
+    }
157 157
 
158
-	/**
159
-	 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
160
-	 */
161
-	public function hook_article_filter_action($article, $action) {
162
-		return $this->process_article($article);
163
-	}
158
+    /**
159
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
160
+     */
161
+    public function hook_article_filter_action($article, $action) {
162
+        return $this->process_article($article);
163
+    }
164 164
 
165
-	public function extract_content($url) {
165
+    public function extract_content($url) {
166 166
 
167
-		global $fetch_effective_url;
167
+        global $fetch_effective_url;
168 168
 
169
-		$tmp = fetch_file_contents([
170
-			"url" => $url,
171
-			"http_accept" => "text/*",
172
-			"type" => "text/html"]);
169
+        $tmp = fetch_file_contents([
170
+            "url" => $url,
171
+            "http_accept" => "text/*",
172
+            "type" => "text/html"]);
173 173
 
174
-		if ($tmp && mb_strlen($tmp) < 1024 * 500) {
175
-			$tmpdoc = new DOMDocument("1.0", "UTF-8");
174
+        if ($tmp && mb_strlen($tmp) < 1024 * 500) {
175
+            $tmpdoc = new DOMDocument("1.0", "UTF-8");
176 176
 
177
-			if (!@$tmpdoc->loadHTML($tmp))
178
-				return false;
177
+            if (!@$tmpdoc->loadHTML($tmp))
178
+                return false;
179 179
 
180
-			// this is the worst hack yet :(
181
-			if (strtolower($tmpdoc->encoding) != 'utf-8') {
182
-				$tmp = preg_replace("/<meta.*?charset.*?\/?>/i", "", $tmp);
183
-				if (empty($tmpdoc->encoding)) {
184
-					$tmp = mb_convert_encoding($tmp, 'utf-8');
185
-				} else {
186
-					$tmp = mb_convert_encoding($tmp, 'utf-8', $tmpdoc->encoding);
187
-				}
188
-			}
180
+            // this is the worst hack yet :(
181
+            if (strtolower($tmpdoc->encoding) != 'utf-8') {
182
+                $tmp = preg_replace("/<meta.*?charset.*?\/?>/i", "", $tmp);
183
+                if (empty($tmpdoc->encoding)) {
184
+                    $tmp = mb_convert_encoding($tmp, 'utf-8');
185
+                } else {
186
+                    $tmp = mb_convert_encoding($tmp, 'utf-8', $tmpdoc->encoding);
187
+                }
188
+            }
189 189
 
190
-			try {
191
-				$r = new Readability(new Configuration());
190
+            try {
191
+                $r = new Readability(new Configuration());
192 192
 
193
-				if ($r->parse($tmp)) {
193
+                if ($r->parse($tmp)) {
194 194
 
195
-					$tmpxpath = new DOMXPath($r->getDOMDOcument());
196
-					$entries = $tmpxpath->query('(//a[@href]|//img[@src])');
195
+                    $tmpxpath = new DOMXPath($r->getDOMDOcument());
196
+                    $entries = $tmpxpath->query('(//a[@href]|//img[@src])');
197 197
 
198
-					foreach ($entries as $entry) {
199
-						if ($entry->hasAttribute("href")) {
200
-							$entry->setAttribute("href",
201
-									rewrite_relative_url($fetch_effective_url, $entry->getAttribute("href")));
198
+                    foreach ($entries as $entry) {
199
+                        if ($entry->hasAttribute("href")) {
200
+                            $entry->setAttribute("href",
201
+                                    rewrite_relative_url($fetch_effective_url, $entry->getAttribute("href")));
202 202
 
203
-						}
203
+                        }
204 204
 
205
-						if ($entry->hasAttribute("src")) {
206
-							$entry->setAttribute("src",
207
-									rewrite_relative_url($fetch_effective_url, $entry->getAttribute("src")));
205
+                        if ($entry->hasAttribute("src")) {
206
+                            $entry->setAttribute("src",
207
+                                    rewrite_relative_url($fetch_effective_url, $entry->getAttribute("src")));
208 208
 
209
-						}
210
-					}
209
+                        }
210
+                    }
211 211
 
212
-					return $r->getContent();
213
-				}
212
+                    return $r->getContent();
213
+                }
214 214
 
215
-			} catch (Exception $e) {
216
-				return false;
217
-			}
218
-		}
215
+            } catch (Exception $e) {
216
+                return false;
217
+            }
218
+        }
219 219
 
220
-		return false;
221
-	}
220
+        return false;
221
+    }
222 222
 
223
-	public function process_article($article) {
223
+    public function process_article($article) {
224 224
 
225
-		$extracted_content = $this->extract_content($article["link"]);
225
+        $extracted_content = $this->extract_content($article["link"]);
226 226
 
227
-		# let's see if there's anything of value in there
228
-		$content_test = trim(strip_tags(sanitize($extracted_content)));
227
+        # let's see if there's anything of value in there
228
+        $content_test = trim(strip_tags(sanitize($extracted_content)));
229 229
 
230
-		if ($content_test) {
231
-			$article["content"] = $extracted_content;
232
-		}
230
+        if ($content_test) {
231
+            $article["content"] = $extracted_content;
232
+        }
233 233
 
234
-		return $article;
235
-	}
234
+        return $article;
235
+    }
236 236
 
237
-	public function hook_article_filter($article) {
237
+    public function hook_article_filter($article) {
238 238
 
239
-		$enabled_feeds = $this->host->get($this, "enabled_feeds");
240
-		if (!is_array($enabled_feeds)) return $article;
239
+        $enabled_feeds = $this->host->get($this, "enabled_feeds");
240
+        if (!is_array($enabled_feeds)) return $article;
241 241
 
242
-		$key = array_search($article["feed"]["id"], $enabled_feeds);
243
-		if ($key === false) return $article;
242
+        $key = array_search($article["feed"]["id"], $enabled_feeds);
243
+        if ($key === false) return $article;
244 244
 
245
-		return $this->process_article($article);
245
+        return $this->process_article($article);
246 246
 
247
-	}
247
+    }
248 248
 
249
-	public function hook_get_full_text($link)
250
-	{
251
-		$enable_share_anything = $this->host->get($this, "enable_share_anything");
249
+    public function hook_get_full_text($link)
250
+    {
251
+        $enable_share_anything = $this->host->get($this, "enable_share_anything");
252 252
 
253
-		if ($enable_share_anything) {
254
-			$extracted_content = $this->extract_content($link);
253
+        if ($enable_share_anything) {
254
+            $extracted_content = $this->extract_content($link);
255 255
 
256
-			# let's see if there's anything of value in there
257
-			$content_test = trim(strip_tags(sanitize($extracted_content)));
256
+            # let's see if there's anything of value in there
257
+            $content_test = trim(strip_tags(sanitize($extracted_content)));
258 258
 
259
-			if ($content_test) {
260
-				return $extracted_content;
261
-			}
262
-		}
259
+            if ($content_test) {
260
+                return $extracted_content;
261
+            }
262
+        }
263 263
 
264
-		return false;
265
-	}
264
+        return false;
265
+    }
266 266
 
267
-	public function api_version() {
268
-		return 2;
269
-	}
267
+    public function api_version() {
268
+        return 2;
269
+    }
270 270
 
271
-	private function filter_unknown_feeds($enabled_feeds) {
272
-		$tmp = array();
271
+    private function filter_unknown_feeds($enabled_feeds) {
272
+        $tmp = array();
273 273
 
274
-		foreach ($enabled_feeds as $feed) {
274
+        foreach ($enabled_feeds as $feed) {
275 275
 
276
-			$sth = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE id = ? AND owner_uid = ?");
277
-			$sth->execute([$feed, $_SESSION['uid']]);
276
+            $sth = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE id = ? AND owner_uid = ?");
277
+            $sth->execute([$feed, $_SESSION['uid']]);
278 278
 
279
-			if ($row = $sth->fetch()) {
280
-				array_push($tmp, $feed);
281
-			}
282
-		}
279
+            if ($row = $sth->fetch()) {
280
+                array_push($tmp, $feed);
281
+            }
282
+        }
283 283
 
284
-		return $tmp;
285
-	}
284
+        return $tmp;
285
+    }
286 286
 
287 287
 }
Please login to merge, or discard this patch.