Passed
Pull Request — master (#5)
by Cody
03:17
created
classes/counters.php 1 patch
Indentation   +122 added lines, -122 removed lines patch added patch discarded remove patch
@@ -1,171 +1,171 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 class Counters {
3 3
 
4
-	public static function getAllCounters() {
5
-		$data = Counters::getGlobalCounters();
4
+    public static function getAllCounters() {
5
+        $data = Counters::getGlobalCounters();
6 6
 
7
-		$data = array_merge($data, Counters::getVirtCounters());
8
-		$data = array_merge($data, Counters::getLabelCounters());
9
-		$data = array_merge($data, Counters::getFeedCounters());
10
-		$data = array_merge($data, Counters::getCategoryCounters());
7
+        $data = array_merge($data, Counters::getVirtCounters());
8
+        $data = array_merge($data, Counters::getLabelCounters());
9
+        $data = array_merge($data, Counters::getFeedCounters());
10
+        $data = array_merge($data, Counters::getCategoryCounters());
11 11
 
12
-		return $data;
13
-	}
12
+        return $data;
13
+    }
14 14
 
15
-	public static function getCategoryCounters() {
16
-		$ret_arr = array();
15
+    public static function getCategoryCounters() {
16
+        $ret_arr = array();
17 17
 
18
-		/* Labels category */
18
+        /* Labels category */
19 19
 
20
-		$cv = array("id" => -2, "kind" => "cat",
21
-			"counter" => Feeds::getCategoryUnread(-2));
20
+        $cv = array("id" => -2, "kind" => "cat",
21
+            "counter" => Feeds::getCategoryUnread(-2));
22 22
 
23
-		array_push($ret_arr, $cv);
23
+        array_push($ret_arr, $cv);
24 24
 
25
-		$pdo = DB::pdo();
25
+        $pdo = DB::pdo();
26 26
 
27
-		$sth = $pdo->prepare("SELECT ttrss_feed_categories.id AS cat_id, value AS unread,
27
+        $sth = $pdo->prepare("SELECT ttrss_feed_categories.id AS cat_id, value AS unread,
28 28
 			(SELECT COUNT(id) FROM ttrss_feed_categories AS c2
29 29
 				WHERE c2.parent_cat = ttrss_feed_categories.id) AS num_children
30 30
 			FROM ttrss_feed_categories, ttrss_cat_counters_cache
31 31
 			WHERE ttrss_cat_counters_cache.feed_id = ttrss_feed_categories.id AND
32 32
 			ttrss_cat_counters_cache.owner_uid = ttrss_feed_categories.owner_uid AND
33 33
 			ttrss_feed_categories.owner_uid = ?");
34
-		$sth->execute([$_SESSION['uid']]);
34
+        $sth->execute([$_SESSION['uid']]);
35 35
 
36
-		while ($line = $sth->fetch()) {
37
-			$line["cat_id"] = (int) $line["cat_id"];
36
+        while ($line = $sth->fetch()) {
37
+            $line["cat_id"] = (int) $line["cat_id"];
38 38
 
39
-			if ($line["num_children"] > 0) {
40
-				$child_counter = Feeds::getCategoryChildrenUnread($line["cat_id"], $_SESSION["uid"]);
41
-			} else {
42
-				$child_counter = 0;
43
-			}
39
+            if ($line["num_children"] > 0) {
40
+                $child_counter = Feeds::getCategoryChildrenUnread($line["cat_id"], $_SESSION["uid"]);
41
+            } else {
42
+                $child_counter = 0;
43
+            }
44 44
 
45
-			$cv = array("id" => $line["cat_id"], "kind" => "cat",
46
-				"counter" => $line["unread"] + $child_counter);
45
+            $cv = array("id" => $line["cat_id"], "kind" => "cat",
46
+                "counter" => $line["unread"] + $child_counter);
47 47
 
48
-			array_push($ret_arr, $cv);
49
-		}
48
+            array_push($ret_arr, $cv);
49
+        }
50 50
 
51
-		/* Special case: NULL category doesn't actually exist in the DB */
51
+        /* Special case: NULL category doesn't actually exist in the DB */
52 52
 
53
-		$cv = array("id" => 0, "kind" => "cat",
54
-			"counter" => (int) CCache::find(0, $_SESSION["uid"], true));
53
+        $cv = array("id" => 0, "kind" => "cat",
54
+            "counter" => (int) CCache::find(0, $_SESSION["uid"], true));
55 55
 
56
-		array_push($ret_arr, $cv);
56
+        array_push($ret_arr, $cv);
57 57
 
58
-		return $ret_arr;
59
-	}
58
+        return $ret_arr;
59
+    }
60 60
 
61
-	public static function getGlobalCounters($global_unread = -1) {
62
-		$ret_arr = array();
61
+    public static function getGlobalCounters($global_unread = -1) {
62
+        $ret_arr = array();
63 63
 
64
-		if ($global_unread == -1) {
65
-			$global_unread = Feeds::getGlobalUnread();
66
-		}
64
+        if ($global_unread == -1) {
65
+            $global_unread = Feeds::getGlobalUnread();
66
+        }
67 67
 
68
-		$cv = array("id" => "global-unread",
69
-			"counter" => (int) $global_unread);
68
+        $cv = array("id" => "global-unread",
69
+            "counter" => (int) $global_unread);
70 70
 
71
-		array_push($ret_arr, $cv);
71
+        array_push($ret_arr, $cv);
72 72
 
73
-		$pdo = Db::pdo();
73
+        $pdo = Db::pdo();
74 74
 
75
-		$sth = $pdo->prepare("SELECT COUNT(id) AS fn FROM
75
+        $sth = $pdo->prepare("SELECT COUNT(id) AS fn FROM
76 76
 			ttrss_feeds WHERE owner_uid = ?");
77
-		$sth->execute([$_SESSION['uid']]);
78
-		$row = $sth->fetch();
77
+        $sth->execute([$_SESSION['uid']]);
78
+        $row = $sth->fetch();
79 79
 
80
-		$subscribed_feeds = $row["fn"];
80
+        $subscribed_feeds = $row["fn"];
81 81
 
82
-		$cv = array("id" => "subscribed-feeds",
83
-			"counter" => (int) $subscribed_feeds);
82
+        $cv = array("id" => "subscribed-feeds",
83
+            "counter" => (int) $subscribed_feeds);
84 84
 
85
-		array_push($ret_arr, $cv);
85
+        array_push($ret_arr, $cv);
86 86
 
87
-		return $ret_arr;
88
-	}
87
+        return $ret_arr;
88
+    }
89 89
 
90
-	public static function getVirtCounters() {
90
+    public static function getVirtCounters() {
91 91
 
92
-		$ret_arr = array();
92
+        $ret_arr = array();
93 93
 
94
-		for ($i = 0; $i >= -4; $i--) {
94
+        for ($i = 0; $i >= -4; $i--) {
95 95
 
96
-			$count = getFeedUnread($i);
96
+            $count = getFeedUnread($i);
97 97
 
98
-			if ($i == 0 || $i == -1 || $i == -2)
99
-				$auxctr = Feeds::getFeedArticles($i, false);
100
-			else
101
-				$auxctr = 0;
98
+            if ($i == 0 || $i == -1 || $i == -2)
99
+                $auxctr = Feeds::getFeedArticles($i, false);
100
+            else
101
+                $auxctr = 0;
102 102
 
103
-			$cv = array("id" => $i,
104
-				"counter" => (int) $count,
105
-				"auxcounter" => (int) $auxctr);
103
+            $cv = array("id" => $i,
104
+                "counter" => (int) $count,
105
+                "auxcounter" => (int) $auxctr);
106 106
 
107 107
 //			if (get_pref('EXTENDED_FEEDLIST'))
108 108
 //				$cv["xmsg"] = getFeedArticles($i)." ".__("total");
109 109
 
110
-			array_push($ret_arr, $cv);
111
-		}
110
+            array_push($ret_arr, $cv);
111
+        }
112 112
 
113
-		$feeds = PluginHost::getInstance()->get_feeds(-1);
113
+        $feeds = PluginHost::getInstance()->get_feeds(-1);
114 114
 
115
-		if (is_array($feeds)) {
116
-			foreach ($feeds as $feed) {
117
-				$cv = array("id" => PluginHost::pfeed_to_feed_id($feed['id']),
118
-					"counter" => $feed['sender']->get_unread($feed['id']));
115
+        if (is_array($feeds)) {
116
+            foreach ($feeds as $feed) {
117
+                $cv = array("id" => PluginHost::pfeed_to_feed_id($feed['id']),
118
+                    "counter" => $feed['sender']->get_unread($feed['id']));
119 119
 
120
-				if (method_exists($feed['sender'], 'get_total'))
121
-					$cv["auxcounter"] = $feed['sender']->get_total($feed['id']);
120
+                if (method_exists($feed['sender'], 'get_total'))
121
+                    $cv["auxcounter"] = $feed['sender']->get_total($feed['id']);
122 122
 
123
-				array_push($ret_arr, $cv);
124
-			}
125
-		}
123
+                array_push($ret_arr, $cv);
124
+            }
125
+        }
126 126
 
127
-		return $ret_arr;
128
-	}
127
+        return $ret_arr;
128
+    }
129 129
 
130
-	public static function getLabelCounters($descriptions = false) {
130
+    public static function getLabelCounters($descriptions = false) {
131 131
 
132
-		$ret_arr = array();
132
+        $ret_arr = array();
133 133
 
134
-		$pdo = Db::pdo();
134
+        $pdo = Db::pdo();
135 135
 
136
-		$sth = $pdo->prepare("SELECT id,caption,SUM(CASE WHEN u1.unread = true THEN 1 ELSE 0 END) AS unread, COUNT(u1.unread) AS total
136
+        $sth = $pdo->prepare("SELECT id,caption,SUM(CASE WHEN u1.unread = true THEN 1 ELSE 0 END) AS unread, COUNT(u1.unread) AS total
137 137
 			FROM ttrss_labels2 LEFT JOIN ttrss_user_labels2 ON
138 138
 				(ttrss_labels2.id = label_id)
139 139
 				LEFT JOIN ttrss_user_entries AS u1 ON u1.ref_id = article_id
140 140
 				WHERE ttrss_labels2.owner_uid = :uid AND u1.owner_uid = :uid
141 141
 				GROUP BY ttrss_labels2.id,
142 142
 					ttrss_labels2.caption");
143
-		$sth->execute([":uid" => $_SESSION['uid']]);
143
+        $sth->execute([":uid" => $_SESSION['uid']]);
144 144
 
145
-		while ($line = $sth->fetch()) {
145
+        while ($line = $sth->fetch()) {
146 146
 
147
-			$id = Labels::label_to_feed_id($line["id"]);
147
+            $id = Labels::label_to_feed_id($line["id"]);
148 148
 
149
-			$cv = array("id" => $id,
150
-				"counter" => (int) $line["unread"],
151
-				"auxcounter" => (int) $line["total"]);
149
+            $cv = array("id" => $id,
150
+                "counter" => (int) $line["unread"],
151
+                "auxcounter" => (int) $line["total"]);
152 152
 
153
-			if ($descriptions)
154
-				$cv["description"] = $line["caption"];
153
+            if ($descriptions)
154
+                $cv["description"] = $line["caption"];
155 155
 
156
-			array_push($ret_arr, $cv);
157
-		}
156
+            array_push($ret_arr, $cv);
157
+        }
158 158
 
159
-		return $ret_arr;
160
-	}
159
+        return $ret_arr;
160
+    }
161 161
 
162
-	public static function getFeedCounters($active_feed = false) {
162
+    public static function getFeedCounters($active_feed = false) {
163 163
 
164
-		$ret_arr = array();
164
+        $ret_arr = array();
165 165
 
166
-		$pdo = Db::pdo();
166
+        $pdo = Db::pdo();
167 167
 
168
-		$sth = $pdo->prepare("SELECT ttrss_feeds.id,
168
+        $sth = $pdo->prepare("SELECT ttrss_feeds.id,
169 169
 				ttrss_feeds.title,
170 170
 				".SUBSTRING_FOR_DATE."(ttrss_feeds.last_updated,1,19) AS last_updated,
171 171
 				last_error, value AS count
@@ -173,44 +173,44 @@  discard block
 block discarded – undo
173 173
 			WHERE ttrss_feeds.owner_uid = ?
174 174
 				AND ttrss_counters_cache.owner_uid = ttrss_feeds.owner_uid
175 175
 				AND ttrss_counters_cache.feed_id = ttrss_feeds.id");
176
-		$sth->execute([$_SESSION['uid']]);
176
+        $sth->execute([$_SESSION['uid']]);
177 177
 
178
-		while ($line = $sth->fetch()) {
178
+        while ($line = $sth->fetch()) {
179 179
 
180
-			$id = $line["id"];
181
-			$count = $line["count"];
182
-			$last_error = htmlspecialchars($line["last_error"]);
180
+            $id = $line["id"];
181
+            $count = $line["count"];
182
+            $last_error = htmlspecialchars($line["last_error"]);
183 183
 
184
-			$last_updated = make_local_datetime($line['last_updated'], false);
184
+            $last_updated = make_local_datetime($line['last_updated'], false);
185 185
 
186
-			if (Feeds::feedHasIcon($id)) {
187
-				$has_img = filemtime(Feeds::getIconFile($id));
188
-			} else {
189
-				$has_img = false;
190
-			}
186
+            if (Feeds::feedHasIcon($id)) {
187
+                $has_img = filemtime(Feeds::getIconFile($id));
188
+            } else {
189
+                $has_img = false;
190
+            }
191 191
 
192
-			if (date('Y') - date('Y', strtotime($line['last_updated'])) > 2)
193
-				$last_updated = '';
192
+            if (date('Y') - date('Y', strtotime($line['last_updated'])) > 2)
193
+                $last_updated = '';
194 194
 
195
-			$cv = array("id" => $id,
196
-				"updated" => $last_updated,
197
-				"counter" => (int) $count,
198
-				"has_img" => (int) $has_img);
195
+            $cv = array("id" => $id,
196
+                "updated" => $last_updated,
197
+                "counter" => (int) $count,
198
+                "has_img" => (int) $has_img);
199 199
 
200
-			if ($last_error)
201
-				$cv["error"] = $last_error;
200
+            if ($last_error)
201
+                $cv["error"] = $last_error;
202 202
 
203 203
 //			if (get_pref('EXTENDED_FEEDLIST'))
204 204
 //				$cv["xmsg"] = getFeedArticles($id)." ".__("total");
205 205
 
206
-			if ($active_feed && $id == $active_feed)
207
-				$cv["title"] = truncate_string($line["title"], 30);
206
+            if ($active_feed && $id == $active_feed)
207
+                $cv["title"] = truncate_string($line["title"], 30);
208 208
 
209
-			array_push($ret_arr, $cv);
209
+            array_push($ret_arr, $cv);
210 210
 
211
-		}
211
+        }
212 212
 
213
-		return $ret_arr;
214
-	}
213
+        return $ret_arr;
214
+    }
215 215
 
216 216
 }
Please login to merge, or discard this patch.
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/handler.php 1 patch
Indentation   +15 added lines, -15 removed lines patch added patch discarded remove patch
@@ -1,23 +1,23 @@
 block discarded – undo
1 1
 <?php
2 2
 class Handler implements IHandler {
3
-	protected $pdo;
4
-	protected $args;
3
+    protected $pdo;
4
+    protected $args;
5 5
 
6
-	public function __construct($args) {
7
-		$this->pdo = Db::pdo();
8
-		$this->args = $args;
9
-	}
6
+    public function __construct($args) {
7
+        $this->pdo = Db::pdo();
8
+        $this->args = $args;
9
+    }
10 10
 
11
-	public function csrf_ignore($method) {
12
-		return true;
13
-	}
11
+    public function csrf_ignore($method) {
12
+        return true;
13
+    }
14 14
 
15
-	public function before($method) {
16
-		return true;
17
-	}
15
+    public function before($method) {
16
+        return true;
17
+    }
18 18
 
19
-	public function after() {
20
-		return true;
21
-	}
19
+    public function after() {
20
+        return true;
21
+    }
22 22
 
23 23
 }
Please login to merge, or discard this patch.
classes/opml.php 1 patch
Indentation   +401 added lines, -401 removed lines patch added patch discarded remove patch
@@ -1,28 +1,28 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 class Opml extends Handler_Protected {
3 3
 
4
-	public function csrf_ignore($method) {
5
-		$csrf_ignored = array("export", "import");
4
+    public function csrf_ignore($method) {
5
+        $csrf_ignored = array("export", "import");
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 export() {
11
-		$output_name = "tt-rss_".date("Y-m-d").".opml";
12
-		$include_settings = $_REQUEST["include_settings"] == "1";
13
-		$owner_uid = $_SESSION["uid"];
10
+    public function export() {
11
+        $output_name = "tt-rss_".date("Y-m-d").".opml";
12
+        $include_settings = $_REQUEST["include_settings"] == "1";
13
+        $owner_uid = $_SESSION["uid"];
14 14
 
15
-		$rc = $this->opml_export($output_name, $owner_uid, false, $include_settings);
15
+        $rc = $this->opml_export($output_name, $owner_uid, false, $include_settings);
16 16
 
17
-		return $rc;
18
-	}
17
+        return $rc;
18
+    }
19 19
 
20
-	public function import() {
21
-		$owner_uid = $_SESSION["uid"];
20
+    public function import() {
21
+        $owner_uid = $_SESSION["uid"];
22 22
 
23
-		header('Content-Type: text/html; charset=utf-8');
23
+        header('Content-Type: text/html; charset=utf-8');
24 24
 
25
-		print "<html>
25
+        print "<html>
26 26
 			<head>
27 27
 				".stylesheet_tag("css/default.css")."
28 28
 				<title>".__("OPML Utility")."</title>
@@ -31,177 +31,177 @@  discard block
 block discarded – undo
31 31
 			<body class='claro ttrss_utility'>
32 32
 			<h1>".__('OPML Utility')."</h1><div class='content'>";
33 33
 
34
-		Feeds::add_feed_category("Imported feeds");
34
+        Feeds::add_feed_category("Imported feeds");
35 35
 
36
-		$this->opml_notice(__("Importing OPML..."));
36
+        $this->opml_notice(__("Importing OPML..."));
37 37
 
38
-		$this->opml_import($owner_uid);
38
+        $this->opml_import($owner_uid);
39 39
 
40
-		print "<br><form method=\"GET\" action=\"prefs.php\">
40
+        print "<br><form method=\"GET\" action=\"prefs.php\">
41 41
 			<input type=\"submit\" value=\"".__("Return to preferences")."\">
42 42
 			</form>";
43 43
 
44
-		print "</div></body></html>";
44
+        print "</div></body></html>";
45 45
 
46 46
 
47
-	}
47
+    }
48 48
 
49
-	// Export
49
+    // Export
50 50
 
51
-	private function opml_export_category($owner_uid, $cat_id, $hide_private_feeds = false, $include_settings = true) {
51
+    private function opml_export_category($owner_uid, $cat_id, $hide_private_feeds = false, $include_settings = true) {
52 52
 
53
-		$cat_id = (int) $cat_id;
53
+        $cat_id = (int) $cat_id;
54 54
 
55
-		if ($hide_private_feeds)
56
-			$hide_qpart = "(private IS false AND auth_login = '' AND auth_pass = '')";
57
-		else
58
-			$hide_qpart = "true";
55
+        if ($hide_private_feeds)
56
+            $hide_qpart = "(private IS false AND auth_login = '' AND auth_pass = '')";
57
+        else
58
+            $hide_qpart = "true";
59 59
 
60
-		$out = "";
60
+        $out = "";
61 61
 
62
-		$ttrss_specific_qpart = "";
62
+        $ttrss_specific_qpart = "";
63 63
 
64
-		if ($cat_id) {
65
-			$sth = $this->pdo->prepare("SELECT title,order_id
64
+        if ($cat_id) {
65
+            $sth = $this->pdo->prepare("SELECT title,order_id
66 66
 				FROM ttrss_feed_categories WHERE id = ?
67 67
 					AND owner_uid = ?");
68
-			$sth->execute([$cat_id, $owner_uid]);
69
-			$row = $sth->fetch();
70
-			$cat_title = htmlspecialchars($row['title']);
68
+            $sth->execute([$cat_id, $owner_uid]);
69
+            $row = $sth->fetch();
70
+            $cat_title = htmlspecialchars($row['title']);
71 71
 
72
-			if ($include_settings) {
73
-				$order_id = (int)$row["order_id"];
74
-				$ttrss_specific_qpart = "ttrssSortOrder=\"$order_id\"";
75
-			}
76
-		} else {
77
-			$cat_title = "";
78
-		}
72
+            if ($include_settings) {
73
+                $order_id = (int)$row["order_id"];
74
+                $ttrss_specific_qpart = "ttrssSortOrder=\"$order_id\"";
75
+            }
76
+        } else {
77
+            $cat_title = "";
78
+        }
79 79
 
80
-		if ($cat_title) $out .= "<outline text=\"$cat_title\" $ttrss_specific_qpart>\n";
80
+        if ($cat_title) $out .= "<outline text=\"$cat_title\" $ttrss_specific_qpart>\n";
81 81
 
82
-		$sth = $this->pdo->prepare("SELECT id,title
82
+        $sth = $this->pdo->prepare("SELECT id,title
83 83
 			FROM ttrss_feed_categories WHERE
84 84
 				(parent_cat = :cat OR (:cat = 0 AND parent_cat IS NULL)) AND
85 85
 				owner_uid = :uid ORDER BY order_id, title");
86 86
 
87
-		$sth->execute([':cat' => $cat_id, ':uid' => $owner_uid]);
87
+        $sth->execute([':cat' => $cat_id, ':uid' => $owner_uid]);
88 88
 
89
-		while ($line = $sth->fetch()) {
90
-			$out .= $this->opml_export_category($owner_uid, $line["id"], $hide_private_feeds, $include_settings);
91
-		}
89
+        while ($line = $sth->fetch()) {
90
+            $out .= $this->opml_export_category($owner_uid, $line["id"], $hide_private_feeds, $include_settings);
91
+        }
92 92
 
93
-		$fsth = $this->pdo->prepare("select title, feed_url, site_url, update_interval, order_id
93
+        $fsth = $this->pdo->prepare("select title, feed_url, site_url, update_interval, order_id
94 94
 				FROM ttrss_feeds WHERE
95 95
 					(cat_id = :cat OR (:cat = 0 AND cat_id IS NULL)) AND owner_uid = :uid AND $hide_qpart
96 96
 				ORDER BY order_id, title");
97 97
 
98
-		$fsth->execute([':cat' => $cat_id, ':uid' => $owner_uid]);
98
+        $fsth->execute([':cat' => $cat_id, ':uid' => $owner_uid]);
99 99
 
100
-		while ($fline = $fsth->fetch()) {
101
-			$title = htmlspecialchars($fline["title"]);
102
-			$url = htmlspecialchars($fline["feed_url"]);
103
-			$site_url = htmlspecialchars($fline["site_url"]);
100
+        while ($fline = $fsth->fetch()) {
101
+            $title = htmlspecialchars($fline["title"]);
102
+            $url = htmlspecialchars($fline["feed_url"]);
103
+            $site_url = htmlspecialchars($fline["site_url"]);
104 104
 
105
-			if ($include_settings) {
106
-				$update_interval = (int)$fline["update_interval"];
107
-				$order_id = (int)$fline["order_id"];
105
+            if ($include_settings) {
106
+                $update_interval = (int)$fline["update_interval"];
107
+                $order_id = (int)$fline["order_id"];
108 108
 
109
-				$ttrss_specific_qpart = "ttrssSortOrder=\"$order_id\" ttrssUpdateInterval=\"$update_interval\"";
110
-			} else {
111
-				$ttrss_specific_qpart = "";
112
-			}
109
+                $ttrss_specific_qpart = "ttrssSortOrder=\"$order_id\" ttrssUpdateInterval=\"$update_interval\"";
110
+            } else {
111
+                $ttrss_specific_qpart = "";
112
+            }
113 113
 
114
-			if ($site_url) {
115
-				$html_url_qpart = "htmlUrl=\"$site_url\"";
116
-			} else {
117
-				$html_url_qpart = "";
118
-			}
114
+            if ($site_url) {
115
+                $html_url_qpart = "htmlUrl=\"$site_url\"";
116
+            } else {
117
+                $html_url_qpart = "";
118
+            }
119 119
 
120
-			$out .= "<outline type=\"rss\" text=\"$title\" xmlUrl=\"$url\" $ttrss_specific_qpart $html_url_qpart/>\n";
121
-		}
120
+            $out .= "<outline type=\"rss\" text=\"$title\" xmlUrl=\"$url\" $ttrss_specific_qpart $html_url_qpart/>\n";
121
+        }
122 122
 
123
-		if ($cat_title) $out .= "</outline>\n";
123
+        if ($cat_title) $out .= "</outline>\n";
124 124
 
125
-		return $out;
126
-	}
125
+        return $out;
126
+    }
127 127
 
128
-	public function opml_export($name, $owner_uid, $hide_private_feeds = false, $include_settings = true) {
129
-		if (!$owner_uid) return;
128
+    public function opml_export($name, $owner_uid, $hide_private_feeds = false, $include_settings = true) {
129
+        if (!$owner_uid) return;
130 130
 
131
-		if (!isset($_REQUEST["debug"])) {
132
-			header("Content-type: application/xml+opml");
133
-			header("Content-Disposition: attachment; filename=" . $name );
134
-		} else {
135
-			header("Content-type: text/xml");
136
-		}
131
+        if (!isset($_REQUEST["debug"])) {
132
+            header("Content-type: application/xml+opml");
133
+            header("Content-Disposition: attachment; filename=" . $name );
134
+        } else {
135
+            header("Content-type: text/xml");
136
+        }
137 137
 
138
-		$out = "<?xml version=\"1.0\" encoding=\"utf-8\"?".">";
138
+        $out = "<?xml version=\"1.0\" encoding=\"utf-8\"?".">";
139 139
 
140
-		$out .= "<opml version=\"1.0\">";
141
-		$out .= "<head>
140
+        $out .= "<opml version=\"1.0\">";
141
+        $out .= "<head>
142 142
 			<dateCreated>" . date("r", time()) . "</dateCreated>
143 143
 			<title>Tiny Tiny RSS Feed Export</title>
144 144
 		</head>";
145
-		$out .= "<body>";
145
+        $out .= "<body>";
146 146
 
147
-		$out .= $this->opml_export_category($owner_uid, 0, $hide_private_feeds, $include_settings);
147
+        $out .= $this->opml_export_category($owner_uid, 0, $hide_private_feeds, $include_settings);
148 148
 
149
-		# export tt-rss settings
149
+        # export tt-rss settings
150 150
 
151
-		if ($include_settings) {
152
-			$out .= "<outline text=\"tt-rss-prefs\" schema-version=\"".SCHEMA_VERSION."\">";
151
+        if ($include_settings) {
152
+            $out .= "<outline text=\"tt-rss-prefs\" schema-version=\"".SCHEMA_VERSION."\">";
153 153
 
154
-			$sth = $this->pdo->prepare("SELECT pref_name, value FROM ttrss_user_prefs WHERE
154
+            $sth = $this->pdo->prepare("SELECT pref_name, value FROM ttrss_user_prefs WHERE
155 155
 			   profile IS NULL AND owner_uid = ? ORDER BY pref_name");
156
-			$sth->execute([$owner_uid]);
156
+            $sth->execute([$owner_uid]);
157 157
 
158
-			while ($line = $sth->fetch()) {
159
-				$name = $line["pref_name"];
160
-				$value = htmlspecialchars($line["value"]);
158
+            while ($line = $sth->fetch()) {
159
+                $name = $line["pref_name"];
160
+                $value = htmlspecialchars($line["value"]);
161 161
 
162
-				$out .= "<outline pref-name=\"$name\" value=\"$value\"/>";
163
-			}
162
+                $out .= "<outline pref-name=\"$name\" value=\"$value\"/>";
163
+            }
164 164
 
165
-			$out .= "</outline>";
165
+            $out .= "</outline>";
166 166
 
167
-			$out .= "<outline text=\"tt-rss-labels\" schema-version=\"".SCHEMA_VERSION."\">";
167
+            $out .= "<outline text=\"tt-rss-labels\" schema-version=\"".SCHEMA_VERSION."\">";
168 168
 
169
-			$sth = $this->pdo->prepare("SELECT * FROM ttrss_labels2 WHERE
169
+            $sth = $this->pdo->prepare("SELECT * FROM ttrss_labels2 WHERE
170 170
 				owner_uid = ?");
171
-			$sth->execute([$owner_uid]);
171
+            $sth->execute([$owner_uid]);
172 172
 
173
-			while ($line = $sth->fetch()) {
174
-				$name = htmlspecialchars($line['caption']);
175
-				$fg_color = htmlspecialchars($line['fg_color']);
176
-				$bg_color = htmlspecialchars($line['bg_color']);
173
+            while ($line = $sth->fetch()) {
174
+                $name = htmlspecialchars($line['caption']);
175
+                $fg_color = htmlspecialchars($line['fg_color']);
176
+                $bg_color = htmlspecialchars($line['bg_color']);
177 177
 
178
-				$out .= "<outline label-name=\"$name\" label-fg-color=\"$fg_color\" label-bg-color=\"$bg_color\"/>";
178
+                $out .= "<outline label-name=\"$name\" label-fg-color=\"$fg_color\" label-bg-color=\"$bg_color\"/>";
179 179
 
180
-			}
180
+            }
181 181
 
182
-			$out .= "</outline>";
182
+            $out .= "</outline>";
183 183
 
184
-			$out .= "<outline text=\"tt-rss-filters\" schema-version=\"".SCHEMA_VERSION."\">";
184
+            $out .= "<outline text=\"tt-rss-filters\" schema-version=\"".SCHEMA_VERSION."\">";
185 185
 
186
-			$sth = $this->pdo->prepare("SELECT * FROM ttrss_filters2
186
+            $sth = $this->pdo->prepare("SELECT * FROM ttrss_filters2
187 187
 				WHERE owner_uid = ? ORDER BY id");
188
-			$sth->execute([$owner_uid]);
188
+            $sth->execute([$owner_uid]);
189 189
 
190
-			while ($line = $sth->fetch()) {
191
-				$line["rules"] = array();
192
-				$line["actions"] = array();
190
+            while ($line = $sth->fetch()) {
191
+                $line["rules"] = array();
192
+                $line["actions"] = array();
193 193
 
194
-				$tmph = $this->pdo->prepare("SELECT * FROM ttrss_filters2_rules
194
+                $tmph = $this->pdo->prepare("SELECT * FROM ttrss_filters2_rules
195 195
 					WHERE filter_id = ?");
196
-				$tmph->execute([$line['id']]);
196
+                $tmph->execute([$line['id']]);
197 197
 
198
-				while ($tmp_line = $tmph->fetch(PDO::FETCH_ASSOC)) {
199
-					unset($tmp_line["id"]);
200
-					unset($tmp_line["filter_id"]);
198
+                while ($tmp_line = $tmph->fetch(PDO::FETCH_ASSOC)) {
199
+                    unset($tmp_line["id"]);
200
+                    unset($tmp_line["filter_id"]);
201 201
 
202
-					$cat_filter = $tmp_line["cat_filter"];
202
+                    $cat_filter = $tmp_line["cat_filter"];
203 203
 
204
-					if (!$tmp_line["match_on"]) {
204
+                    if (!$tmp_line["match_on"]) {
205 205
                         if ($cat_filter && $tmp_line["cat_id"] || $tmp_line["feed_id"]) {
206 206
                             $tmp_line["feed"] = Feeds::getFeedTitle(
207 207
                                 $cat_filter ? $tmp_line["cat_id"] : $tmp_line["feed_id"],
@@ -210,8 +210,8 @@  discard block
 block discarded – undo
210 210
                             $tmp_line["feed"] = "";
211 211
                         }
212 212
                     } else {
213
-					    $match = [];
214
-					    foreach (json_decode($tmp_line["match_on"], true) as $feed_id) {
213
+                        $match = [];
214
+                        foreach (json_decode($tmp_line["match_on"], true) as $feed_id) {
215 215
 
216 216
                             if (strpos($feed_id, "CAT:") === 0) {
217 217
                                 $feed_id = (int)substr($feed_id, 4);
@@ -230,56 +230,56 @@  discard block
 block discarded – undo
230 230
                         }
231 231
 
232 232
                         $tmp_line["match"] = $match;
233
-					    unset($tmp_line["match_on"]);
233
+                        unset($tmp_line["match_on"]);
234 234
                     }
235 235
 
236
-					unset($tmp_line["feed_id"]);
237
-					unset($tmp_line["cat_id"]);
236
+                    unset($tmp_line["feed_id"]);
237
+                    unset($tmp_line["cat_id"]);
238 238
 
239
-					array_push($line["rules"], $tmp_line);
240
-				}
239
+                    array_push($line["rules"], $tmp_line);
240
+                }
241 241
 
242
-				$tmph = $this->pdo->prepare("SELECT * FROM ttrss_filters2_actions
242
+                $tmph = $this->pdo->prepare("SELECT * FROM ttrss_filters2_actions
243 243
 					WHERE filter_id = ?");
244
-				$tmph->execute([$line['id']]);
244
+                $tmph->execute([$line['id']]);
245 245
 
246
-				while ($tmp_line = $tmph->fetch(PDO::FETCH_ASSOC)) {
247
-					unset($tmp_line["id"]);
248
-					unset($tmp_line["filter_id"]);
246
+                while ($tmp_line = $tmph->fetch(PDO::FETCH_ASSOC)) {
247
+                    unset($tmp_line["id"]);
248
+                    unset($tmp_line["filter_id"]);
249 249
 
250
-					array_push($line["actions"], $tmp_line);
251
-				}
250
+                    array_push($line["actions"], $tmp_line);
251
+                }
252 252
 
253
-				unset($line["id"]);
254
-				unset($line["owner_uid"]);
255
-				$filter = json_encode($line);
253
+                unset($line["id"]);
254
+                unset($line["owner_uid"]);
255
+                $filter = json_encode($line);
256 256
 
257
-				$out .= "<outline filter-type=\"2\"><![CDATA[$filter]]></outline>";
257
+                $out .= "<outline filter-type=\"2\"><![CDATA[$filter]]></outline>";
258 258
 
259
-			}
259
+            }
260 260
 
261 261
 
262
-			$out .= "</outline>";
263
-		}
262
+            $out .= "</outline>";
263
+        }
264 264
 
265
-		$out .= "</body></opml>";
265
+        $out .= "</body></opml>";
266 266
 
267
-		// Format output.
268
-		$doc = new DOMDocument();
269
-		$doc->formatOutput = true;
270
-		$doc->preserveWhiteSpace = false;
271
-		$doc->loadXML($out);
267
+        // Format output.
268
+        $doc = new DOMDocument();
269
+        $doc->formatOutput = true;
270
+        $doc->preserveWhiteSpace = false;
271
+        $doc->loadXML($out);
272 272
 
273
-		$xpath = new DOMXpath($doc);
274
-		$outlines = $xpath->query("//outline[@title]");
273
+        $xpath = new DOMXpath($doc);
274
+        $outlines = $xpath->query("//outline[@title]");
275 275
 
276
-		// cleanup empty categories
277
-		foreach ($outlines as $node) {
278
-			if ($node->getElementsByTagName('outline')->length == 0)
279
-				$node->parentNode->removeChild($node);
280
-		}
276
+        // cleanup empty categories
277
+        foreach ($outlines as $node) {
278
+            if ($node->getElementsByTagName('outline')->length == 0)
279
+                $node->parentNode->removeChild($node);
280
+        }
281 281
 
282
-		$res = $doc->saveXML();
282
+        $res = $doc->saveXML();
283 283
 
284 284
 /*		// saveXML uses a two-space indent.  Change to tabs.
285 285
 		$res = preg_replace_callback('/^(?:  )+/mu',
@@ -288,128 +288,128 @@  discard block
 block discarded – undo
288 288
 				'return str_repeat("\t", intval(strlen($matches[0])/2));'),
289 289
 			$res); */
290 290
 
291
-		print $res;
292
-	}
291
+        print $res;
292
+    }
293 293
 
294
-	// Import
294
+    // Import
295 295
 
296
-	private function opml_import_feed($node, $cat_id, $owner_uid) {
297
-		$attrs = $node->attributes;
296
+    private function opml_import_feed($node, $cat_id, $owner_uid) {
297
+        $attrs = $node->attributes;
298 298
 
299
-		$feed_title = mb_substr($attrs->getNamedItem('text')->nodeValue, 0, 250);
300
-		if (!$feed_title) $feed_title = mb_substr($attrs->getNamedItem('title')->nodeValue, 0, 250);
299
+        $feed_title = mb_substr($attrs->getNamedItem('text')->nodeValue, 0, 250);
300
+        if (!$feed_title) $feed_title = mb_substr($attrs->getNamedItem('title')->nodeValue, 0, 250);
301 301
 
302
-		$feed_url = $attrs->getNamedItem('xmlUrl')->nodeValue;
303
-		if (!$feed_url) $feed_url = $attrs->getNamedItem('xmlURL')->nodeValue;
302
+        $feed_url = $attrs->getNamedItem('xmlUrl')->nodeValue;
303
+        if (!$feed_url) $feed_url = $attrs->getNamedItem('xmlURL')->nodeValue;
304 304
 
305
-		$site_url = mb_substr($attrs->getNamedItem('htmlUrl')->nodeValue, 0, 250);
305
+        $site_url = mb_substr($attrs->getNamedItem('htmlUrl')->nodeValue, 0, 250);
306 306
 
307
-		if ($feed_url) {
308
-			$sth = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE
307
+        if ($feed_url) {
308
+            $sth = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE
309 309
 				feed_url = ? AND owner_uid = ?");
310
-			$sth->execute([$feed_url, $owner_uid]);
310
+            $sth->execute([$feed_url, $owner_uid]);
311 311
 
312
-			if (!$feed_title) $feed_title = '[Unknown]';
312
+            if (!$feed_title) $feed_title = '[Unknown]';
313 313
 
314
-			if (!$sth->fetch()) {
315
-				#$this->opml_notice("[FEED] [$feed_title/$feed_url] dst_CAT=$cat_id");
316
-				$this->opml_notice(T_sprintf("Adding feed: %s", $feed_title == '[Unknown]' ? $feed_url : $feed_title));
314
+            if (!$sth->fetch()) {
315
+                #$this->opml_notice("[FEED] [$feed_title/$feed_url] dst_CAT=$cat_id");
316
+                $this->opml_notice(T_sprintf("Adding feed: %s", $feed_title == '[Unknown]' ? $feed_url : $feed_title));
317 317
 
318
-				if (!$cat_id) $cat_id = null;
318
+                if (!$cat_id) $cat_id = null;
319 319
 
320
-				$update_interval = (int) $attrs->getNamedItem('ttrssUpdateInterval')->nodeValue;
321
-				if (!$update_interval) $update_interval = 0;
320
+                $update_interval = (int) $attrs->getNamedItem('ttrssUpdateInterval')->nodeValue;
321
+                if (!$update_interval) $update_interval = 0;
322 322
 
323
-				$order_id = (int) $attrs->getNamedItem('ttrssSortOrder')->nodeValue;
324
-				if (!$order_id) $order_id = 0;
323
+                $order_id = (int) $attrs->getNamedItem('ttrssSortOrder')->nodeValue;
324
+                if (!$order_id) $order_id = 0;
325 325
 
326
-				$sth = $this->pdo->prepare("INSERT INTO ttrss_feeds
326
+                $sth = $this->pdo->prepare("INSERT INTO ttrss_feeds
327 327
 					(title, feed_url, owner_uid, cat_id, site_url, order_id, update_interval) VALUES
328 328
 					(?, ?, ?, ?, ?, ?, ?)");
329 329
 
330
-				$sth->execute([$feed_title, $feed_url, $owner_uid, $cat_id, $site_url, $order_id, $update_interval]);
330
+                $sth->execute([$feed_title, $feed_url, $owner_uid, $cat_id, $site_url, $order_id, $update_interval]);
331 331
 
332
-			} else {
333
-				$this->opml_notice(T_sprintf("Duplicate feed: %s", $feed_title == '[Unknown]' ? $feed_url : $feed_title));
334
-			}
335
-		}
336
-	}
332
+            } else {
333
+                $this->opml_notice(T_sprintf("Duplicate feed: %s", $feed_title == '[Unknown]' ? $feed_url : $feed_title));
334
+            }
335
+        }
336
+    }
337 337
 
338
-	private function opml_import_label($node, $owner_uid) {
339
-		$attrs = $node->attributes;
340
-		$label_name = $attrs->getNamedItem('label-name')->nodeValue;
338
+    private function opml_import_label($node, $owner_uid) {
339
+        $attrs = $node->attributes;
340
+        $label_name = $attrs->getNamedItem('label-name')->nodeValue;
341 341
 
342
-		if ($label_name) {
343
-			$fg_color = $attrs->getNamedItem('label-fg-color')->nodeValue;
344
-			$bg_color = $attrs->getNamedItem('label-bg-color')->nodeValue;
342
+        if ($label_name) {
343
+            $fg_color = $attrs->getNamedItem('label-fg-color')->nodeValue;
344
+            $bg_color = $attrs->getNamedItem('label-bg-color')->nodeValue;
345 345
 
346
-			if (!Labels::find_id($label_name, $_SESSION['uid'])) {
347
-				$this->opml_notice(T_sprintf("Adding label %s", htmlspecialchars($label_name)));
348
-				Labels::create($label_name, $fg_color, $bg_color, $owner_uid);
349
-			} else {
350
-				$this->opml_notice(T_sprintf("Duplicate label: %s", htmlspecialchars($label_name)));
351
-			}
352
-		}
353
-	}
346
+            if (!Labels::find_id($label_name, $_SESSION['uid'])) {
347
+                $this->opml_notice(T_sprintf("Adding label %s", htmlspecialchars($label_name)));
348
+                Labels::create($label_name, $fg_color, $bg_color, $owner_uid);
349
+            } else {
350
+                $this->opml_notice(T_sprintf("Duplicate label: %s", htmlspecialchars($label_name)));
351
+            }
352
+        }
353
+    }
354 354
 
355
-	private function opml_import_preference($node) {
356
-		$attrs = $node->attributes;
357
-		$pref_name = $attrs->getNamedItem('pref-name')->nodeValue;
355
+    private function opml_import_preference($node) {
356
+        $attrs = $node->attributes;
357
+        $pref_name = $attrs->getNamedItem('pref-name')->nodeValue;
358 358
 
359
-		if ($pref_name) {
360
-			$pref_value = $attrs->getNamedItem('value')->nodeValue;
359
+        if ($pref_name) {
360
+            $pref_value = $attrs->getNamedItem('value')->nodeValue;
361 361
 
362
-			$this->opml_notice(T_sprintf("Setting preference key %s to %s",
363
-				$pref_name, $pref_value));
362
+            $this->opml_notice(T_sprintf("Setting preference key %s to %s",
363
+                $pref_name, $pref_value));
364 364
 
365
-			set_pref($pref_name, $pref_value);
366
-		}
367
-	}
365
+            set_pref($pref_name, $pref_value);
366
+        }
367
+    }
368 368
 
369
-	private function opml_import_filter($node) {
370
-		$attrs = $node->attributes;
369
+    private function opml_import_filter($node) {
370
+        $attrs = $node->attributes;
371 371
 
372
-		$filter_type = $attrs->getNamedItem('filter-type')->nodeValue;
372
+        $filter_type = $attrs->getNamedItem('filter-type')->nodeValue;
373 373
 
374
-		if ($filter_type == '2') {
375
-			$filter = json_decode($node->nodeValue, true);
374
+        if ($filter_type == '2') {
375
+            $filter = json_decode($node->nodeValue, true);
376 376
 
377
-			if ($filter) {
378
-				$match_any_rule = bool_to_sql_bool($filter["match_any_rule"]);
379
-				$enabled = bool_to_sql_bool($filter["enabled"]);
380
-				$inverse = bool_to_sql_bool($filter["inverse"]);
381
-				$title = $filter["title"];
377
+            if ($filter) {
378
+                $match_any_rule = bool_to_sql_bool($filter["match_any_rule"]);
379
+                $enabled = bool_to_sql_bool($filter["enabled"]);
380
+                $inverse = bool_to_sql_bool($filter["inverse"]);
381
+                $title = $filter["title"];
382 382
 
383
-				//print "F: $title, $inverse, $enabled, $match_any_rule";
383
+                //print "F: $title, $inverse, $enabled, $match_any_rule";
384 384
 
385
-				$sth = $this->pdo->prepare("INSERT INTO ttrss_filters2 (match_any_rule,enabled,inverse,title,owner_uid)
385
+                $sth = $this->pdo->prepare("INSERT INTO ttrss_filters2 (match_any_rule,enabled,inverse,title,owner_uid)
386 386
 					VALUES (?, ?, ?, ?, ?)");
387 387
 
388
-				$sth->execute([$match_any_rule, $enabled, $inverse, $title, $_SESSION['uid']]);
388
+                $sth->execute([$match_any_rule, $enabled, $inverse, $title, $_SESSION['uid']]);
389 389
 
390
-				$sth = $this->pdo->prepare("SELECT MAX(id) AS id FROM ttrss_filters2 WHERE
390
+                $sth = $this->pdo->prepare("SELECT MAX(id) AS id FROM ttrss_filters2 WHERE
391 391
 					owner_uid = ?");
392
-				$sth->execute([$_SESSION['uid']]);
392
+                $sth->execute([$_SESSION['uid']]);
393 393
 
394
-				$row = $sth->fetch();
395
-				$filter_id = $row['id'];
394
+                $row = $sth->fetch();
395
+                $filter_id = $row['id'];
396 396
 
397
-				if ($filter_id) {
398
-					$this->opml_notice(T_sprintf("Adding filter %s...", $title));
397
+                if ($filter_id) {
398
+                    $this->opml_notice(T_sprintf("Adding filter %s...", $title));
399 399
 
400
-					foreach ($filter["rules"] as $rule) {
401
-						$feed_id = null;
402
-						$cat_id = null;
400
+                    foreach ($filter["rules"] as $rule) {
401
+                        $feed_id = null;
402
+                        $cat_id = null;
403 403
 
404
-						if ($rule["match"]) {
404
+                        if ($rule["match"]) {
405 405
 
406 406
                             $match_on = [];
407 407
 
408
-						    foreach ($rule["match"] as $match) {
409
-						        list ($name, $is_cat, $is_id) = $match;
408
+                            foreach ($rule["match"] as $match) {
409
+                                list ($name, $is_cat, $is_id) = $match;
410 410
 
411
-						        if ($is_id) {
412
-						            array_push($match_on, ($is_cat ? "CAT:" : "") . $name);
411
+                                if ($is_id) {
412
+                                    array_push($match_on, ($is_cat ? "CAT:" : "") . $name);
413 413
                                 } else {
414 414
 
415 415
                                     if (!$is_cat) {
@@ -421,18 +421,18 @@  discard block
 block discarded – undo
421 421
                                         if ($row = $tsth->fetch()) {
422 422
                                             $match_id = $row['id'];
423 423
 
424
-											array_push($match_on, $match_id);
424
+                                            array_push($match_on, $match_id);
425 425
                                         }
426 426
                                     } else {
427 427
                                         $tsth = $this->pdo->prepare("SELECT id FROM ttrss_feed_categories
428 428
                                     		WHERE title = ? AND owner_uid = ?");
429
-										$tsth->execute([$name, $_SESSION['uid']]);
429
+                                        $tsth->execute([$name, $_SESSION['uid']]);
430 430
 
431
-										if ($row = $tsth->fetch()) {
432
-											$match_id = $row['id'];
431
+                                        if ($row = $tsth->fetch()) {
432
+                                            $match_id = $row['id'];
433 433
 
434
-											array_push($match_on, "CAT:$match_id");
435
-										}
434
+                                            array_push($match_on, "CAT:$match_id");
435
+                                        }
436 436
                                     }
437 437
                                 }
438 438
                             }
@@ -460,14 +460,14 @@  discard block
 block discarded – undo
460 460
                                     $feed_id = $row['id'];
461 461
                                 }
462 462
                             } else {
463
-								$tsth = $this->pdo->prepare("SELECT id FROM ttrss_feed_categories
463
+                                $tsth = $this->pdo->prepare("SELECT id FROM ttrss_feed_categories
464 464
                                     WHERE title = ? AND owner_uid = ?");
465 465
 
466
-								$tsth->execute([$rule['feed'], $_SESSION['uid']]);
466
+                                $tsth->execute([$rule['feed'], $_SESSION['uid']]);
467 467
 
468
-								if ($row = $tsth->fetch()) {
469
-									$feed_id = $row['id'];
470
-								}
468
+                                if ($row = $tsth->fetch()) {
469
+                                    $feed_id = $row['id'];
470
+                                }
471 471
                             }
472 472
 
473 473
                             $cat_filter = bool_to_sql_bool($rule["cat_filter"]);
@@ -481,174 +481,174 @@  discard block
 block discarded – undo
481 481
                                 (?, ?, ?, ?, ?, ?, ?)");
482 482
                             $usth->execute([$feed_id, $cat_id, $filter_id, $filter_type, $reg_exp, $cat_filter, $inverse]);
483 483
                         }
484
-					}
484
+                    }
485 485
 
486
-					foreach ($filter["actions"] as $action) {
486
+                    foreach ($filter["actions"] as $action) {
487 487
 
488
-						$action_id = (int)$action["action_id"];
489
-						$action_param = $action["action_param"];
488
+                        $action_id = (int)$action["action_id"];
489
+                        $action_param = $action["action_param"];
490 490
 
491
-						$usth = $this->pdo->prepare("INSERT INTO ttrss_filters2_actions
491
+                        $usth = $this->pdo->prepare("INSERT INTO ttrss_filters2_actions
492 492
 							(filter_id,action_id,action_param)
493 493
 							VALUES
494 494
 							(?, ?, ?)");
495
-						$usth->execute([$filter_id, $action_id, $action_param]);
496
-					}
497
-				}
498
-			}
499
-		}
500
-	}
501
-
502
-	private function opml_import_category($doc, $root_node, $owner_uid, $parent_id) {
503
-		$default_cat_id = (int) $this->get_feed_category('Imported feeds', false);
504
-
505
-		if ($root_node) {
506
-			$cat_title = mb_substr($root_node->attributes->getNamedItem('text')->nodeValue, 0, 250);
507
-
508
-			if (!$cat_title)
509
-				$cat_title = mb_substr($root_node->attributes->getNamedItem('title')->nodeValue, 0, 250);
510
-
511
-			if (!in_array($cat_title, array("tt-rss-filters", "tt-rss-labels", "tt-rss-prefs"))) {
512
-				$cat_id = $this->get_feed_category($cat_title, $parent_id);
513
-
514
-				if ($cat_id === false) {
515
-					$order_id = (int) $root_node->attributes->getNamedItem('ttrssSortOrder')->nodeValue;
516
-					if (!$order_id) $order_id = 0;
517
-
518
-					Feeds::add_feed_category($cat_title, $parent_id, $order_id);
519
-					$cat_id = $this->get_feed_category($cat_title, $parent_id);
520
-				}
521
-
522
-			} else {
523
-				$cat_id = 0;
524
-			}
525
-
526
-			$outlines = $root_node->childNodes;
527
-
528
-		} else {
529
-			$xpath = new DOMXpath($doc);
530
-			$outlines = $xpath->query("//opml/body/outline");
531
-
532
-			$cat_id = 0;
533
-		}
534
-
535
-		#$this->opml_notice("[CAT] $cat_title id: $cat_id P_id: $parent_id");
536
-		$this->opml_notice(T_sprintf("Processing category: %s", $cat_title ? $cat_title : __("Uncategorized")));
537
-
538
-		foreach ($outlines as $node) {
539
-			if ($node->hasAttributes() && strtolower($node->tagName) == "outline") {
540
-				$attrs = $node->attributes;
541
-				$node_cat_title = $attrs->getNamedItem('text')->nodeValue;
542
-
543
-				if (!$node_cat_title)
544
-					$node_cat_title = $attrs->getNamedItem('title')->nodeValue;
545
-
546
-				$node_feed_url = $attrs->getNamedItem('xmlUrl')->nodeValue;
547
-
548
-				if ($node_cat_title && !$node_feed_url) {
549
-					$this->opml_import_category($doc, $node, $owner_uid, $cat_id);
550
-				} else {
551
-
552
-					if (!$cat_id) {
553
-						$dst_cat_id = $default_cat_id;
554
-					} else {
555
-						$dst_cat_id = $cat_id;
556
-					}
557
-
558
-					switch ($cat_title) {
559
-					case "tt-rss-prefs":
560
-						$this->opml_import_preference($node);
561
-						break;
562
-					case "tt-rss-labels":
563
-						$this->opml_import_label($node, $owner_uid);
564
-						break;
565
-					case "tt-rss-filters":
566
-						$this->opml_import_filter($node);
567
-						break;
568
-					default:
569
-						$this->opml_import_feed($node, $dst_cat_id, $owner_uid);
570
-					}
571
-				}
572
-			}
573
-		}
574
-	}
575
-
576
-	public function opml_import($owner_uid) {
577
-		if (!$owner_uid) return;
578
-
579
-		$doc = false;
580
-
581
-		if ($_FILES['opml_file']['error'] != 0) {
582
-			print_error(T_sprintf("Upload failed with error code %d",
583
-				$_FILES['opml_file']['error']));
584
-			return;
585
-		}
586
-
587
-		if (is_uploaded_file($_FILES['opml_file']['tmp_name'])) {
588
-			$tmp_file = tempnam(CACHE_DIR . '/upload', 'opml');
589
-
590
-			$result = move_uploaded_file($_FILES['opml_file']['tmp_name'],
591
-				$tmp_file);
592
-
593
-			if (!$result) {
594
-				print_error(__("Unable to move uploaded file."));
595
-				return;
596
-			}
597
-		} else {
598
-			print_error(__('Error: please upload OPML file.'));
599
-			return;
600
-		}
601
-
602
-		if (is_file($tmp_file)) {
603
-			$doc = new DOMDocument();
604
-			libxml_disable_entity_loader(false);
605
-			$doc->load($tmp_file);
606
-			libxml_disable_entity_loader(true);
607
-			unlink($tmp_file);
608
-		} else if (!$doc) {
609
-			print_error(__('Error: unable to find moved OPML file.'));
610
-			return;
611
-		}
612
-
613
-		if ($doc) {
614
-			$this->pdo->beginTransaction();
615
-			$this->opml_import_category($doc, false, $owner_uid, false);
616
-			$this->pdo->commit();
617
-		} else {
618
-			print_error(__('Error while parsing document.'));
619
-		}
620
-	}
621
-
622
-	private function opml_notice($msg) {
623
-		print "$msg<br/>";
624
-	}
625
-
626
-	public static function opml_publish_url(){
627
-
628
-		$url_path = get_self_url_prefix();
629
-		$url_path .= "/opml.php?op=publish&key=" .
630
-			Feeds::get_feed_access_key('OPML:Publish', false, $_SESSION["uid"]);
631
-
632
-		return $url_path;
633
-	}
634
-
635
-	public function get_feed_category($feed_cat, $parent_cat_id = false) {
636
-
637
-		$parent_cat_id = (int) $parent_cat_id;
638
-
639
-		$sth = $this->pdo->prepare("SELECT id FROM ttrss_feed_categories
495
+                        $usth->execute([$filter_id, $action_id, $action_param]);
496
+                    }
497
+                }
498
+            }
499
+        }
500
+    }
501
+
502
+    private function opml_import_category($doc, $root_node, $owner_uid, $parent_id) {
503
+        $default_cat_id = (int) $this->get_feed_category('Imported feeds', false);
504
+
505
+        if ($root_node) {
506
+            $cat_title = mb_substr($root_node->attributes->getNamedItem('text')->nodeValue, 0, 250);
507
+
508
+            if (!$cat_title)
509
+                $cat_title = mb_substr($root_node->attributes->getNamedItem('title')->nodeValue, 0, 250);
510
+
511
+            if (!in_array($cat_title, array("tt-rss-filters", "tt-rss-labels", "tt-rss-prefs"))) {
512
+                $cat_id = $this->get_feed_category($cat_title, $parent_id);
513
+
514
+                if ($cat_id === false) {
515
+                    $order_id = (int) $root_node->attributes->getNamedItem('ttrssSortOrder')->nodeValue;
516
+                    if (!$order_id) $order_id = 0;
517
+
518
+                    Feeds::add_feed_category($cat_title, $parent_id, $order_id);
519
+                    $cat_id = $this->get_feed_category($cat_title, $parent_id);
520
+                }
521
+
522
+            } else {
523
+                $cat_id = 0;
524
+            }
525
+
526
+            $outlines = $root_node->childNodes;
527
+
528
+        } else {
529
+            $xpath = new DOMXpath($doc);
530
+            $outlines = $xpath->query("//opml/body/outline");
531
+
532
+            $cat_id = 0;
533
+        }
534
+
535
+        #$this->opml_notice("[CAT] $cat_title id: $cat_id P_id: $parent_id");
536
+        $this->opml_notice(T_sprintf("Processing category: %s", $cat_title ? $cat_title : __("Uncategorized")));
537
+
538
+        foreach ($outlines as $node) {
539
+            if ($node->hasAttributes() && strtolower($node->tagName) == "outline") {
540
+                $attrs = $node->attributes;
541
+                $node_cat_title = $attrs->getNamedItem('text')->nodeValue;
542
+
543
+                if (!$node_cat_title)
544
+                    $node_cat_title = $attrs->getNamedItem('title')->nodeValue;
545
+
546
+                $node_feed_url = $attrs->getNamedItem('xmlUrl')->nodeValue;
547
+
548
+                if ($node_cat_title && !$node_feed_url) {
549
+                    $this->opml_import_category($doc, $node, $owner_uid, $cat_id);
550
+                } else {
551
+
552
+                    if (!$cat_id) {
553
+                        $dst_cat_id = $default_cat_id;
554
+                    } else {
555
+                        $dst_cat_id = $cat_id;
556
+                    }
557
+
558
+                    switch ($cat_title) {
559
+                    case "tt-rss-prefs":
560
+                        $this->opml_import_preference($node);
561
+                        break;
562
+                    case "tt-rss-labels":
563
+                        $this->opml_import_label($node, $owner_uid);
564
+                        break;
565
+                    case "tt-rss-filters":
566
+                        $this->opml_import_filter($node);
567
+                        break;
568
+                    default:
569
+                        $this->opml_import_feed($node, $dst_cat_id, $owner_uid);
570
+                    }
571
+                }
572
+            }
573
+        }
574
+    }
575
+
576
+    public function opml_import($owner_uid) {
577
+        if (!$owner_uid) return;
578
+
579
+        $doc = false;
580
+
581
+        if ($_FILES['opml_file']['error'] != 0) {
582
+            print_error(T_sprintf("Upload failed with error code %d",
583
+                $_FILES['opml_file']['error']));
584
+            return;
585
+        }
586
+
587
+        if (is_uploaded_file($_FILES['opml_file']['tmp_name'])) {
588
+            $tmp_file = tempnam(CACHE_DIR . '/upload', 'opml');
589
+
590
+            $result = move_uploaded_file($_FILES['opml_file']['tmp_name'],
591
+                $tmp_file);
592
+
593
+            if (!$result) {
594
+                print_error(__("Unable to move uploaded file."));
595
+                return;
596
+            }
597
+        } else {
598
+            print_error(__('Error: please upload OPML file.'));
599
+            return;
600
+        }
601
+
602
+        if (is_file($tmp_file)) {
603
+            $doc = new DOMDocument();
604
+            libxml_disable_entity_loader(false);
605
+            $doc->load($tmp_file);
606
+            libxml_disable_entity_loader(true);
607
+            unlink($tmp_file);
608
+        } else if (!$doc) {
609
+            print_error(__('Error: unable to find moved OPML file.'));
610
+            return;
611
+        }
612
+
613
+        if ($doc) {
614
+            $this->pdo->beginTransaction();
615
+            $this->opml_import_category($doc, false, $owner_uid, false);
616
+            $this->pdo->commit();
617
+        } else {
618
+            print_error(__('Error while parsing document.'));
619
+        }
620
+    }
621
+
622
+    private function opml_notice($msg) {
623
+        print "$msg<br/>";
624
+    }
625
+
626
+    public static function opml_publish_url(){
627
+
628
+        $url_path = get_self_url_prefix();
629
+        $url_path .= "/opml.php?op=publish&key=" .
630
+            Feeds::get_feed_access_key('OPML:Publish', false, $_SESSION["uid"]);
631
+
632
+        return $url_path;
633
+    }
634
+
635
+    public function get_feed_category($feed_cat, $parent_cat_id = false) {
636
+
637
+        $parent_cat_id = (int) $parent_cat_id;
638
+
639
+        $sth = $this->pdo->prepare("SELECT id FROM ttrss_feed_categories
640 640
 			WHERE title = :title
641 641
 			AND (parent_cat = :parent OR (:parent = 0 AND parent_cat IS NULL))
642 642
 			AND owner_uid = :uid");
643 643
 
644
-		$sth->execute([':title' => $feed_cat, ':parent' => $parent_cat_id, ':uid' => $_SESSION['uid']]);
644
+        $sth->execute([':title' => $feed_cat, ':parent' => $parent_cat_id, ':uid' => $_SESSION['uid']]);
645 645
 
646
-		if ($row = $sth->fetch()) {
647
-			return $row['id'];
648
-		} else {
649
-			return false;
650
-		}
651
-	}
646
+        if ($row = $sth->fetch()) {
647
+            return $row['id'];
648
+        } else {
649
+            return false;
650
+        }
651
+    }
652 652
 
653 653
 
654 654
 }
Please login to merge, or discard this patch.
backend.php 1 patch
Indentation   +129 added lines, -129 removed lines patch added patch discarded remove patch
@@ -1,130 +1,130 @@
 block discarded – undo
1 1
 <?php
2
-	set_include_path(dirname(__FILE__) ."/include" . PATH_SEPARATOR .
3
-		get_include_path());
4
-
5
-	$op = $_REQUEST["op"];
6
-	@$method = $_REQUEST['subop'] ? $_REQUEST['subop'] : $_REQUEST["method"];
7
-
8
-	if (!$method)
9
-		$method = 'index';
10
-	else
11
-		$method = strtolower($method);
12
-
13
-	/* Public calls compatibility shim */
14
-
15
-	$public_calls = array("globalUpdateFeeds", "rss", "getUnread", "getProfiles", "share",
16
-		"fbexport", "logout", "pubsub");
17
-
18
-	if (array_search($op, $public_calls) !== false) {
19
-		header("Location: public.php?" . $_SERVER['QUERY_STRING']);
20
-		return;
21
-	}
22
-
23
-	@$csrf_token = $_REQUEST['csrf_token'];
24
-
25
-	require_once "autoload.php";
26
-	require_once "sessions.php";
27
-	require_once "functions.php";
28
-	require_once "config.php";
29
-	require_once "db.php";
30
-	require_once "db-prefs.php";
31
-
32
-	startup_gettext();
33
-
34
-	$script_started = microtime(true);
35
-
36
-	if (!init_plugins()) return;
37
-
38
-	header("Content-Type: text/json; charset=utf-8");
39
-
40
-	if (ENABLE_GZIP_OUTPUT && function_exists("ob_gzhandler")) {
41
-		ob_start("ob_gzhandler");
42
-	}
43
-
44
-	if (SINGLE_USER_MODE) {
45
-		authenticate_user( "admin", null);
46
-	}
47
-
48
-	if ($_SESSION["uid"]) {
49
-		if (!validate_session()) {
50
-			header("Content-Type: text/json");
51
-			print error_json(6);
52
-			return;
53
-		}
54
-		load_user_plugins( $_SESSION["uid"]);
55
-	}
56
-
57
-	$purge_intervals = array(
58
-		0  => __("Use default"),
59
-		-1 => __("Never purge"),
60
-		5  => __("1 week old"),
61
-		14 => __("2 weeks old"),
62
-		31 => __("1 month old"),
63
-		60 => __("2 months old"),
64
-		90 => __("3 months old"));
65
-
66
-	$update_intervals = array(
67
-		0   => __("Default interval"),
68
-		-1  => __("Disable updates"),
69
-		15  => __("15 minutes"),
70
-		30  => __("30 minutes"),
71
-		60  => __("Hourly"),
72
-		240 => __("4 hours"),
73
-		720 => __("12 hours"),
74
-		1440 => __("Daily"),
75
-		10080 => __("Weekly"));
76
-
77
-	$update_intervals_nodefault = array(
78
-		-1  => __("Disable updates"),
79
-		15  => __("15 minutes"),
80
-		30  => __("30 minutes"),
81
-		60  => __("Hourly"),
82
-		240 => __("4 hours"),
83
-		720 => __("12 hours"),
84
-		1440 => __("Daily"),
85
-		10080 => __("Weekly"));
86
-
87
-	$access_level_names = array(
88
-		0 => __("User"),
89
-		5 => __("Power User"),
90
-		10 => __("Administrator"));
91
-
92
-	$op = str_replace("-", "_", $op);
93
-
94
-	$override = PluginHost::getInstance()->lookup_handler($op, $method);
95
-
96
-	if (class_exists($op) || $override) {
97
-
98
-		if ($override) {
99
-			$handler = $override;
100
-		} else {
101
-			$handler = new $op($_REQUEST);
102
-		}
103
-
104
-		if ($handler && implements_interface($handler, 'IHandler')) {
105
-			if (validate_csrf($csrf_token) || $handler->csrf_ignore($method)) {
106
-				if ($handler->before($method)) {
107
-					if ($method && method_exists($handler, $method)) {
108
-						$handler->$method();
109
-					} else {
110
-						if (method_exists($handler, "catchall")) {
111
-							$handler->catchall($method);
112
-						}
113
-					}
114
-					$handler->after();
115
-					return;
116
-				} else {
117
-					header("Content-Type: text/json");
118
-					print error_json(6);
119
-					return;
120
-				}
121
-			} else {
122
-				header("Content-Type: text/json");
123
-				print error_json(6);
124
-				return;
125
-			}
126
-		}
127
-	}
128
-
129
-	header("Content-Type: text/json");
130
-	print error_json(13);
2
+    set_include_path(dirname(__FILE__) ."/include" . PATH_SEPARATOR .
3
+        get_include_path());
4
+
5
+    $op = $_REQUEST["op"];
6
+    @$method = $_REQUEST['subop'] ? $_REQUEST['subop'] : $_REQUEST["method"];
7
+
8
+    if (!$method)
9
+        $method = 'index';
10
+    else
11
+        $method = strtolower($method);
12
+
13
+    /* Public calls compatibility shim */
14
+
15
+    $public_calls = array("globalUpdateFeeds", "rss", "getUnread", "getProfiles", "share",
16
+        "fbexport", "logout", "pubsub");
17
+
18
+    if (array_search($op, $public_calls) !== false) {
19
+        header("Location: public.php?" . $_SERVER['QUERY_STRING']);
20
+        return;
21
+    }
22
+
23
+    @$csrf_token = $_REQUEST['csrf_token'];
24
+
25
+    require_once "autoload.php";
26
+    require_once "sessions.php";
27
+    require_once "functions.php";
28
+    require_once "config.php";
29
+    require_once "db.php";
30
+    require_once "db-prefs.php";
31
+
32
+    startup_gettext();
33
+
34
+    $script_started = microtime(true);
35
+
36
+    if (!init_plugins()) return;
37
+
38
+    header("Content-Type: text/json; charset=utf-8");
39
+
40
+    if (ENABLE_GZIP_OUTPUT && function_exists("ob_gzhandler")) {
41
+        ob_start("ob_gzhandler");
42
+    }
43
+
44
+    if (SINGLE_USER_MODE) {
45
+        authenticate_user( "admin", null);
46
+    }
47
+
48
+    if ($_SESSION["uid"]) {
49
+        if (!validate_session()) {
50
+            header("Content-Type: text/json");
51
+            print error_json(6);
52
+            return;
53
+        }
54
+        load_user_plugins( $_SESSION["uid"]);
55
+    }
56
+
57
+    $purge_intervals = array(
58
+        0  => __("Use default"),
59
+        -1 => __("Never purge"),
60
+        5  => __("1 week old"),
61
+        14 => __("2 weeks old"),
62
+        31 => __("1 month old"),
63
+        60 => __("2 months old"),
64
+        90 => __("3 months old"));
65
+
66
+    $update_intervals = array(
67
+        0   => __("Default interval"),
68
+        -1  => __("Disable updates"),
69
+        15  => __("15 minutes"),
70
+        30  => __("30 minutes"),
71
+        60  => __("Hourly"),
72
+        240 => __("4 hours"),
73
+        720 => __("12 hours"),
74
+        1440 => __("Daily"),
75
+        10080 => __("Weekly"));
76
+
77
+    $update_intervals_nodefault = array(
78
+        -1  => __("Disable updates"),
79
+        15  => __("15 minutes"),
80
+        30  => __("30 minutes"),
81
+        60  => __("Hourly"),
82
+        240 => __("4 hours"),
83
+        720 => __("12 hours"),
84
+        1440 => __("Daily"),
85
+        10080 => __("Weekly"));
86
+
87
+    $access_level_names = array(
88
+        0 => __("User"),
89
+        5 => __("Power User"),
90
+        10 => __("Administrator"));
91
+
92
+    $op = str_replace("-", "_", $op);
93
+
94
+    $override = PluginHost::getInstance()->lookup_handler($op, $method);
95
+
96
+    if (class_exists($op) || $override) {
97
+
98
+        if ($override) {
99
+            $handler = $override;
100
+        } else {
101
+            $handler = new $op($_REQUEST);
102
+        }
103
+
104
+        if ($handler && implements_interface($handler, 'IHandler')) {
105
+            if (validate_csrf($csrf_token) || $handler->csrf_ignore($method)) {
106
+                if ($handler->before($method)) {
107
+                    if ($method && method_exists($handler, $method)) {
108
+                        $handler->$method();
109
+                    } else {
110
+                        if (method_exists($handler, "catchall")) {
111
+                            $handler->catchall($method);
112
+                        }
113
+                    }
114
+                    $handler->after();
115
+                    return;
116
+                } else {
117
+                    header("Content-Type: text/json");
118
+                    print error_json(6);
119
+                    return;
120
+                }
121
+            } else {
122
+                header("Content-Type: text/json");
123
+                print error_json(6);
124
+                return;
125
+            }
126
+        }
127
+    }
128
+
129
+    header("Content-Type: text/json");
130
+    print error_json(13);
Please login to merge, or discard this patch.
include/autoload.php 1 patch
Indentation   +18 added lines, -18 removed lines patch added patch discarded remove patch
@@ -1,26 +1,26 @@
 block discarded – undo
1 1
 <?php
2
-	require_once "functions.php";
2
+    require_once "functions.php";
3 3
 
4
-	spl_autoload_register(function($class) {
5
-		$namespace = '';
6
-		$class_name = $class;
4
+    spl_autoload_register(function($class) {
5
+        $namespace = '';
6
+        $class_name = $class;
7 7
 
8
-		if (strpos($class, '\\') !== FALSE)
9
-			list ($namespace, $class_name) = explode('\\', $class, 2);
8
+        if (strpos($class, '\\') !== FALSE)
9
+            list ($namespace, $class_name) = explode('\\', $class, 2);
10 10
 
11
-		$root_dir = dirname(__DIR__); // we're in tt-rss/include
11
+        $root_dir = dirname(__DIR__); // we're in tt-rss/include
12 12
 
13
-		// 1. third party libraries with namespaces are loaded from vendor/
14
-		// 2. internal tt-rss classes are loaded from classes/ and use special naming logic instead of namespaces
15
-		// 3. plugin classes are loaded by PluginHandler from plugins.local/ and plugins/ (TODO: use generic autoloader?)
13
+        // 1. third party libraries with namespaces are loaded from vendor/
14
+        // 2. internal tt-rss classes are loaded from classes/ and use special naming logic instead of namespaces
15
+        // 3. plugin classes are loaded by PluginHandler from plugins.local/ and plugins/ (TODO: use generic autoloader?)
16 16
 
17
-		if ($namespace && $class_name) {
18
-			$class_file = "$root_dir/vendor/$namespace/" . str_replace('\\', '/', $class_name) . ".php";
19
-		} else {
20
-			$class_file = "$root_dir/classes/" . str_replace("_", "/", strtolower($class)) . ".php";
21
-		}
17
+        if ($namespace && $class_name) {
18
+            $class_file = "$root_dir/vendor/$namespace/" . str_replace('\\', '/', $class_name) . ".php";
19
+        } else {
20
+            $class_file = "$root_dir/classes/" . str_replace("_", "/", strtolower($class)) . ".php";
21
+        }
22 22
 
23
-		if (file_exists($class_file))
24
-			include $class_file;
23
+        if (file_exists($class_file))
24
+            include $class_file;
25 25
 
26
-	});
26
+    });
Please login to merge, or discard this patch.
include/sanity_check.php 1 patch
Indentation   +145 added lines, -145 removed lines patch added patch discarded remove patch
@@ -1,190 +1,190 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 
3
-	function make_self_url() {
4
-		$proto = is_server_https() ? 'https' : 'http';
3
+    function make_self_url() {
4
+        $proto = is_server_https() ? 'https' : 'http';
5 5
 
6
-		return $proto . '://' . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];
7
-	}
6
+        return $proto . '://' . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];
7
+    }
8 8
 
9
-	function make_self_url_path() {
10
-		$proto = is_server_https() ? 'https' : 'http';
11
-		$url_path = $proto . '://' . $_SERVER["HTTP_HOST"] . parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH);
9
+    function make_self_url_path() {
10
+        $proto = is_server_https() ? 'https' : 'http';
11
+        $url_path = $proto . '://' . $_SERVER["HTTP_HOST"] . parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH);
12 12
 
13
-		return $url_path;
14
-	}
13
+        return $url_path;
14
+    }
15 15
 
16
-	function check_mysql_tables() {
17
-		$pdo = Db::pdo();
16
+    function check_mysql_tables() {
17
+        $pdo = Db::pdo();
18 18
 
19
-		$sth = $pdo->prepare("SELECT engine, table_name FROM information_schema.tables WHERE
19
+        $sth = $pdo->prepare("SELECT engine, table_name FROM information_schema.tables WHERE
20 20
 				table_schema = ? AND table_name LIKE 'ttrss_%' AND engine != 'InnoDB'");
21
-		$sth->execute([DB_NAME]);
21
+        $sth->execute([DB_NAME]);
22 22
 
23
-		$bad_tables = [];
23
+        $bad_tables = [];
24 24
 
25
-		while ($line = $sth->fetch()) {
26
-			array_push($bad_tables, $line);
27
-		}
25
+        while ($line = $sth->fetch()) {
26
+            array_push($bad_tables, $line);
27
+        }
28 28
 
29
-		return $bad_tables;
30
-	}
29
+        return $bad_tables;
30
+    }
31 31
 
32
-	function initial_sanity_check() {
32
+    function initial_sanity_check() {
33 33
 
34
-		$errors = array();
34
+        $errors = array();
35 35
 
36
-		if (!file_exists("config.php")) {
37
-			array_push($errors, "Configuration file not found. Looks like you forgot to copy config.php-dist to config.php and edit it.");
38
-		} else {
36
+        if (!file_exists("config.php")) {
37
+            array_push($errors, "Configuration file not found. Looks like you forgot to copy config.php-dist to config.php and edit it.");
38
+        } else {
39 39
 
40
-			require_once "sanity_config.php";
40
+            require_once "sanity_config.php";
41 41
 
42
-			if (file_exists("install") && !file_exists("config.php")) {
43
-				array_push($errors, "Please copy config.php-dist to config.php or run the installer in install/");
44
-			}
42
+            if (file_exists("install") && !file_exists("config.php")) {
43
+                array_push($errors, "Please copy config.php-dist to config.php or run the installer in install/");
44
+            }
45 45
 
46
-			if (strpos(PLUGINS, "auth_") === FALSE) {
47
-				array_push($errors, "Please enable at least one authentication module via PLUGINS constant in config.php");
48
-			}
46
+            if (strpos(PLUGINS, "auth_") === FALSE) {
47
+                array_push($errors, "Please enable at least one authentication module via PLUGINS constant in config.php");
48
+            }
49 49
 
50
-			if (function_exists('posix_getuid') && posix_getuid() == 0) {
51
-				array_push($errors, "Please don't run this script as root.");
52
-			}
50
+            if (function_exists('posix_getuid') && posix_getuid() == 0) {
51
+                array_push($errors, "Please don't run this script as root.");
52
+            }
53 53
 
54
-			if (version_compare(PHP_VERSION, '5.6.0', '<')) {
55
-				array_push($errors, "PHP version 5.6.0 or newer required. You're using " . PHP_VERSION . ".");
56
-			}
54
+            if (version_compare(PHP_VERSION, '5.6.0', '<')) {
55
+                array_push($errors, "PHP version 5.6.0 or newer required. You're using " . PHP_VERSION . ".");
56
+            }
57 57
 
58
-			if (!class_exists("UConverter")) {
59
-				array_push($errors, "PHP UConverter class is missing, it's provided by the Internationalization (intl) module.");
60
-			}
58
+            if (!class_exists("UConverter")) {
59
+                array_push($errors, "PHP UConverter class is missing, it's provided by the Internationalization (intl) module.");
60
+            }
61 61
 
62
-			if (CONFIG_VERSION != EXPECTED_CONFIG_VERSION) {
63
-				array_push($errors, "Configuration file (config.php) has incorrect version. Update it with new options from config.php-dist and set CONFIG_VERSION to the correct value.");
64
-			}
62
+            if (CONFIG_VERSION != EXPECTED_CONFIG_VERSION) {
63
+                array_push($errors, "Configuration file (config.php) has incorrect version. Update it with new options from config.php-dist and set CONFIG_VERSION to the correct value.");
64
+            }
65 65
 
66
-			if (!is_writable(CACHE_DIR . "/images")) {
67
-				array_push($errors, "Image cache is not writable (chmod -R 777 ".CACHE_DIR."/images)");
68
-			}
66
+            if (!is_writable(CACHE_DIR . "/images")) {
67
+                array_push($errors, "Image cache is not writable (chmod -R 777 ".CACHE_DIR."/images)");
68
+            }
69 69
 
70
-			if (!is_writable(CACHE_DIR . "/upload")) {
71
-				array_push($errors, "Upload cache is not writable (chmod -R 777 ".CACHE_DIR."/upload)");
72
-			}
70
+            if (!is_writable(CACHE_DIR . "/upload")) {
71
+                array_push($errors, "Upload cache is not writable (chmod -R 777 ".CACHE_DIR."/upload)");
72
+            }
73 73
 
74
-			if (!is_writable(CACHE_DIR . "/export")) {
75
-				array_push($errors, "Data export cache is not writable (chmod -R 777 ".CACHE_DIR."/export)");
76
-			}
74
+            if (!is_writable(CACHE_DIR . "/export")) {
75
+                array_push($errors, "Data export cache is not writable (chmod -R 777 ".CACHE_DIR."/export)");
76
+            }
77 77
 
78
-			if (GENERATED_CONFIG_CHECK != EXPECTED_CONFIG_VERSION) {
79
-				array_push($errors,
80
-					"Configuration option checker sanity_config.php is outdated, please recreate it using ./utils/regen_config_checks.sh");
81
-			}
78
+            if (GENERATED_CONFIG_CHECK != EXPECTED_CONFIG_VERSION) {
79
+                array_push($errors,
80
+                    "Configuration option checker sanity_config.php is outdated, please recreate it using ./utils/regen_config_checks.sh");
81
+            }
82 82
 
83
-			foreach ($required_defines as $d) {
84
-				if (!defined($d)) {
85
-					array_push($errors,
86
-						"Required configuration file parameter $d is not defined in config.php. You might need to copy it from config.php-dist.");
87
-				}
88
-			}
83
+            foreach ($required_defines as $d) {
84
+                if (!defined($d)) {
85
+                    array_push($errors,
86
+                        "Required configuration file parameter $d is not defined in config.php. You might need to copy it from config.php-dist.");
87
+                }
88
+            }
89 89
 
90
-			if (SINGLE_USER_MODE && class_exists("PDO")) {
91
-			    $pdo = DB::pdo();
90
+            if (SINGLE_USER_MODE && class_exists("PDO")) {
91
+                $pdo = DB::pdo();
92 92
 
93
-				$res = $pdo->query("SELECT id FROM ttrss_users WHERE id = 1");
93
+                $res = $pdo->query("SELECT id FROM ttrss_users WHERE id = 1");
94 94
 
95
-				if (!$res->fetch()) {
96
-					array_push($errors, "SINGLE_USER_MODE is enabled in config.php but default admin account is not found.");
97
-				}
98
-			}
95
+                if (!$res->fetch()) {
96
+                    array_push($errors, "SINGLE_USER_MODE is enabled in config.php but default admin account is not found.");
97
+                }
98
+            }
99 99
 
100
-			$ref_self_url_path = make_self_url_path();
101
-			$ref_self_url_path = preg_replace("/\w+\.php$/", "", $ref_self_url_path);
100
+            $ref_self_url_path = make_self_url_path();
101
+            $ref_self_url_path = preg_replace("/\w+\.php$/", "", $ref_self_url_path);
102 102
 
103
-			if (SELF_URL_PATH == "http://example.org/tt-rss/") {
104
-				array_push($errors,
105
-						"Please set SELF_URL_PATH to the correct value for your server (possible value: <b>$ref_self_url_path</b>)");
106
-			}
103
+            if (SELF_URL_PATH == "http://example.org/tt-rss/") {
104
+                array_push($errors,
105
+                        "Please set SELF_URL_PATH to the correct value for your server (possible value: <b>$ref_self_url_path</b>)");
106
+            }
107 107
 
108
-			if (isset($_SERVER["HTTP_HOST"]) &&
109
-				(!defined('_SKIP_SELF_URL_PATH_CHECKS') || !_SKIP_SELF_URL_PATH_CHECKS) &&
110
-				SELF_URL_PATH != $ref_self_url_path && SELF_URL_PATH != mb_substr($ref_self_url_path, 0, mb_strlen($ref_self_url_path)-1)) {
111
-				array_push($errors,
112
-					"Please set SELF_URL_PATH to the correct value detected for your server: <b>$ref_self_url_path</b>");
113
-			}
108
+            if (isset($_SERVER["HTTP_HOST"]) &&
109
+                (!defined('_SKIP_SELF_URL_PATH_CHECKS') || !_SKIP_SELF_URL_PATH_CHECKS) &&
110
+                SELF_URL_PATH != $ref_self_url_path && SELF_URL_PATH != mb_substr($ref_self_url_path, 0, mb_strlen($ref_self_url_path)-1)) {
111
+                array_push($errors,
112
+                    "Please set SELF_URL_PATH to the correct value detected for your server: <b>$ref_self_url_path</b>");
113
+            }
114 114
 
115
-			if (!is_writable(ICONS_DIR)) {
116
-				array_push($errors, "ICONS_DIR defined in config.php is not writable (chmod -R 777 ".ICONS_DIR.").\n");
117
-			}
115
+            if (!is_writable(ICONS_DIR)) {
116
+                array_push($errors, "ICONS_DIR defined in config.php is not writable (chmod -R 777 ".ICONS_DIR.").\n");
117
+            }
118 118
 
119
-			if (!is_writable(LOCK_DIRECTORY)) {
120
-				array_push($errors, "LOCK_DIRECTORY defined in config.php is not writable (chmod -R 777 ".LOCK_DIRECTORY.").\n");
121
-			}
119
+            if (!is_writable(LOCK_DIRECTORY)) {
120
+                array_push($errors, "LOCK_DIRECTORY defined in config.php is not writable (chmod -R 777 ".LOCK_DIRECTORY.").\n");
121
+            }
122 122
 
123
-			if (!function_exists("curl_init") && !ini_get("allow_url_fopen")) {
124
-				array_push($errors, "PHP configuration option allow_url_fopen is disabled, and CURL functions are not present. Either enable allow_url_fopen or install PHP extension for CURL.");
125
-			}
123
+            if (!function_exists("curl_init") && !ini_get("allow_url_fopen")) {
124
+                array_push($errors, "PHP configuration option allow_url_fopen is disabled, and CURL functions are not present. Either enable allow_url_fopen or install PHP extension for CURL.");
125
+            }
126 126
 
127
-			if (!function_exists("json_encode")) {
128
-				array_push($errors, "PHP support for JSON is required, but was not found.");
129
-			}
127
+            if (!function_exists("json_encode")) {
128
+                array_push($errors, "PHP support for JSON is required, but was not found.");
129
+            }
130 130
 
131
-			if (DB_TYPE == "mysql" && !function_exists("mysqli_connect")) {
132
-				array_push($errors, "PHP support for MySQL is required for configured DB_TYPE in config.php.");
133
-			}
131
+            if (DB_TYPE == "mysql" && !function_exists("mysqli_connect")) {
132
+                array_push($errors, "PHP support for MySQL is required for configured DB_TYPE in config.php.");
133
+            }
134 134
 
135
-			if (DB_TYPE == "pgsql" && !function_exists("pg_connect")) {
136
-				array_push($errors, "PHP support for PostgreSQL is required for configured DB_TYPE in config.php");
137
-			}
135
+            if (DB_TYPE == "pgsql" && !function_exists("pg_connect")) {
136
+                array_push($errors, "PHP support for PostgreSQL is required for configured DB_TYPE in config.php");
137
+            }
138 138
 
139
-			if (!class_exists("PDO")) {
140
-				array_push($errors, "PHP support for PDO is required but was not found.");
141
-			}
139
+            if (!class_exists("PDO")) {
140
+                array_push($errors, "PHP support for PDO is required but was not found.");
141
+            }
142 142
 
143
-			if (!function_exists("mb_strlen")) {
144
-				array_push($errors, "PHP support for mbstring functions is required but was not found.");
145
-			}
143
+            if (!function_exists("mb_strlen")) {
144
+                array_push($errors, "PHP support for mbstring functions is required but was not found.");
145
+            }
146 146
 
147
-			if (!function_exists("hash")) {
148
-				array_push($errors, "PHP support for hash() function is required but was not found.");
149
-			}
147
+            if (!function_exists("hash")) {
148
+                array_push($errors, "PHP support for hash() function is required but was not found.");
149
+            }
150 150
 
151
-			if (ini_get("safe_mode")) {
152
-				array_push($errors, "PHP safe mode setting is obsolete and not supported by tt-rss.");
153
-			}
151
+            if (ini_get("safe_mode")) {
152
+                array_push($errors, "PHP safe mode setting is obsolete and not supported by tt-rss.");
153
+            }
154 154
 
155
-			if (!function_exists("mime_content_type")) {
156
-				array_push($errors, "PHP function mime_content_type() is missing, try enabling fileinfo module.");
157
-			}
155
+            if (!function_exists("mime_content_type")) {
156
+                array_push($errors, "PHP function mime_content_type() is missing, try enabling fileinfo module.");
157
+            }
158 158
 
159
-			if (!class_exists("DOMDocument")) {
160
-				array_push($errors, "PHP support for DOMDocument is required, but was not found.");
161
-			}
159
+            if (!class_exists("DOMDocument")) {
160
+                array_push($errors, "PHP support for DOMDocument is required, but was not found.");
161
+            }
162 162
 
163
-			if (DB_TYPE == "mysql") {
164
-				$bad_tables = check_mysql_tables();
163
+            if (DB_TYPE == "mysql") {
164
+                $bad_tables = check_mysql_tables();
165 165
 
166
-				if (count($bad_tables) > 0) {
167
-					$bad_tables_fmt = [];
166
+                if (count($bad_tables) > 0) {
167
+                    $bad_tables_fmt = [];
168 168
 
169
-					foreach ($bad_tables as $bt) {
170
-						array_push($bad_tables_fmt, sprintf("%s (%s)", $bt['table_name'], $bt['engine']));
171
-					}
169
+                    foreach ($bad_tables as $bt) {
170
+                        array_push($bad_tables_fmt, sprintf("%s (%s)", $bt['table_name'], $bt['engine']));
171
+                    }
172 172
 
173
-					$msg = "<p>The following tables use an unsupported MySQL engine: <b>" .
174
-						implode(", ", $bad_tables_fmt) . "</b>.</p>";
173
+                    $msg = "<p>The following tables use an unsupported MySQL engine: <b>" .
174
+                        implode(", ", $bad_tables_fmt) . "</b>.</p>";
175 175
 
176
-					$msg .= "<p>The only supported engine on MySQL is InnoDB. MyISAM lacks functionality to run
176
+                    $msg .= "<p>The only supported engine on MySQL is InnoDB. MyISAM lacks functionality to run
177 177
 						tt-rss.
178 178
 						Please backup your data (via OPML) and re-import the schema before continuing.</p>
179 179
 						<p><b>WARNING: importing the schema would mean LOSS OF ALL YOUR DATA.</b></p>";
180 180
 
181 181
 
182
-					array_push($errors, $msg);
183
-				}
184
-			}
185
-		}
182
+                    array_push($errors, $msg);
183
+                }
184
+            }
185
+        }
186 186
 
187
-		if (count($errors) > 0 && $_SERVER['REQUEST_URI']) { ?>
187
+        if (count($errors) > 0 && $_SERVER['REQUEST_URI']) { ?>
188 188
 			<!DOCTYPE html>
189 189
 			<html>
190 190
 			<head>
@@ -211,22 +211,22 @@  discard block
 block discarded – undo
211 211
 		</html>
212 212
 
213 213
 		<?php
214
-			die;
215
-		} else if (count($errors) > 0) {
216
-			echo "Tiny Tiny RSS was unable to start properly. This usually means a misconfiguration or an incomplete upgrade.\n";
217
-			echo "Please fix errors indicated by the following messages:\n\n";
214
+            die;
215
+        } else if (count($errors) > 0) {
216
+            echo "Tiny Tiny RSS was unable to start properly. This usually means a misconfiguration or an incomplete upgrade.\n";
217
+            echo "Please fix errors indicated by the following messages:\n\n";
218 218
 
219
-			foreach ($errors as $error) {
220
-				echo " * $error\n";
221
-			}
219
+            foreach ($errors as $error) {
220
+                echo " * $error\n";
221
+            }
222 222
 
223
-			echo "\nYou might want to check tt-rss wiki or the forums for more information.\n";
224
-			echo "Please search the forums before creating new topic for your question.\n";
223
+            echo "\nYou might want to check tt-rss wiki or the forums for more information.\n";
224
+            echo "Please search the forums before creating new topic for your question.\n";
225 225
 
226
-			exit(-1);
227
-		}
228
-	}
226
+            exit(-1);
227
+        }
228
+    }
229 229
 
230
-	initial_sanity_check();
230
+    initial_sanity_check();
231 231
 
232 232
 ?>
Please login to merge, or discard this patch.
include/db.php 1 patch
Indentation   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -1,38 +1,38 @@
 block discarded – undo
1 1
 <?php
2 2
 
3 3
 function db_escape_string($s, $strip_tags = true) {
4
-	return Db::get()->escape_string($s, $strip_tags);
4
+    return Db::get()->escape_string($s, $strip_tags);
5 5
 }
6 6
 
7 7
 function db_query($query, $die_on_error = true) {
8
-	return Db::get()->query($query, $die_on_error);
8
+    return Db::get()->query($query, $die_on_error);
9 9
 }
10 10
 
11 11
 function db_fetch_assoc($result) {
12
-	return Db::get()->fetch_assoc($result);
12
+    return Db::get()->fetch_assoc($result);
13 13
 }
14 14
 
15 15
 
16 16
 function db_num_rows($result) {
17
-	return Db::get()->num_rows($result);
17
+    return Db::get()->num_rows($result);
18 18
 }
19 19
 
20 20
 function db_fetch_result($result, $row, $param) {
21
-	return Db::get()->fetch_result($result, $row, $param);
21
+    return Db::get()->fetch_result($result, $row, $param);
22 22
 }
23 23
 
24 24
 function db_affected_rows($result) {
25
-	return Db::get()->affected_rows($result);
25
+    return Db::get()->affected_rows($result);
26 26
 }
27 27
 
28 28
 function db_last_error() {
29
-	return Db::get()->last_error();
29
+    return Db::get()->last_error();
30 30
 }
31 31
 
32 32
 function db_last_query_error() {
33
-	return Db::get()->last_query_error();
33
+    return Db::get()->last_query_error();
34 34
 }
35 35
 
36 36
 function db_quote($str){
37
-	return Db::get()->quote($str);
37
+    return Db::get()->quote($str);
38 38
 }
Please login to merge, or discard this patch.
include/controls.php 1 patch
Indentation   +189 added lines, -189 removed lines patch added patch discarded remove patch
@@ -1,339 +1,339 @@
 block discarded – undo
1 1
 <?php
2 2
 
3 3
 function print_select($id, $default, $values, $attributes = "", $name = "") {
4
-	if (!$name) $name = $id;
4
+    if (!$name) $name = $id;
5 5
 
6
-	print "<select name=\"$name\" id=\"$id\" $attributes>";
7
-	foreach ($values as $v) {
8
-		if ($v == $default)
9
-			$sel = "selected=\"1\"";
10
-		else
11
-			$sel = "";
6
+    print "<select name=\"$name\" id=\"$id\" $attributes>";
7
+    foreach ($values as $v) {
8
+        if ($v == $default)
9
+            $sel = "selected=\"1\"";
10
+        else
11
+            $sel = "";
12 12
 
13
-		$v = trim($v);
13
+        $v = trim($v);
14 14
 
15
-		print "<option value=\"$v\" $sel>$v</option>";
16
-	}
17
-	print "</select>";
15
+        print "<option value=\"$v\" $sel>$v</option>";
16
+    }
17
+    print "</select>";
18 18
 }
19 19
 
20 20
 function print_select_hash($id, $default, $values, $attributes = "", $name = "") {
21
-	if (!$name) $name = $id;
21
+    if (!$name) $name = $id;
22 22
 
23
-	print "<select name=\"$name\" id='$id' $attributes>";
24
-	foreach (array_keys($values) as $v) {
25
-		if ($v == $default)
26
-			$sel = 'selected="selected"';
27
-		else
28
-			$sel = "";
23
+    print "<select name=\"$name\" id='$id' $attributes>";
24
+    foreach (array_keys($values) as $v) {
25
+        if ($v == $default)
26
+            $sel = 'selected="selected"';
27
+        else
28
+            $sel = "";
29 29
 
30
-		$v = trim($v);
30
+        $v = trim($v);
31 31
 
32
-		print "<option $sel value=\"$v\">".$values[$v]."</option>";
33
-	}
32
+        print "<option $sel value=\"$v\">".$values[$v]."</option>";
33
+    }
34 34
 
35
-	print "</select>";
35
+    print "</select>";
36 36
 }
37 37
 
38 38
 function print_hidden($name, $value) {
39
-	print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"$name\" value=\"$value\">";
39
+    print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"$name\" value=\"$value\">";
40 40
 }
41 41
 
42 42
 function print_checkbox($id, $checked, $value = "", $attributes = "") {
43
-	$checked_str = $checked ? "checked" : "";
44
-	$value_str = $value ? "value=\"$value\"" : "";
43
+    $checked_str = $checked ? "checked" : "";
44
+    $value_str = $value ? "value=\"$value\"" : "";
45 45
 
46
-	print "<input dojoType=\"dijit.form.CheckBox\" id=\"$id\" $value_str $checked_str $attributes name=\"$id\">";
46
+    print "<input dojoType=\"dijit.form.CheckBox\" id=\"$id\" $value_str $checked_str $attributes name=\"$id\">";
47 47
 }
48 48
 
49 49
 function print_button($type, $value, $attributes = "") {
50
-	print "<p><button dojoType=\"dijit.form.Button\" $attributes type=\"$type\">$value</button>";
50
+    print "<p><button dojoType=\"dijit.form.Button\" $attributes type=\"$type\">$value</button>";
51 51
 }
52 52
 
53 53
 function print_radio($id, $default, $true_is, $values, $attributes = "") {
54
-	foreach ($values as $v) {
54
+    foreach ($values as $v) {
55 55
 
56
-		if ($v == $default)
57
-			$sel = "checked";
58
-		else
59
-			$sel = "";
56
+        if ($v == $default)
57
+            $sel = "checked";
58
+        else
59
+            $sel = "";
60 60
 
61
-		if ($v == $true_is) {
62
-			$sel .= " value=\"1\"";
63
-		} else {
64
-			$sel .= " value=\"0\"";
65
-		}
61
+        if ($v == $true_is) {
62
+            $sel .= " value=\"1\"";
63
+        } else {
64
+            $sel .= " value=\"0\"";
65
+        }
66 66
 
67
-		print "<input class=\"noborder\" dojoType=\"dijit.form.RadioButton\"
67
+        print "<input class=\"noborder\" dojoType=\"dijit.form.RadioButton\"
68 68
 				type=\"radio\" $sel $attributes name=\"$id\">&nbsp;$v&nbsp;";
69 69
 
70
-	}
70
+    }
71 71
 }
72 72
 
73 73
 function print_feed_multi_select($id, $default_ids = [],
74
-						   $attributes = "", $include_all_feeds = true,
75
-						   $root_id = null, $nest_level = 0) {
74
+                            $attributes = "", $include_all_feeds = true,
75
+                            $root_id = null, $nest_level = 0) {
76 76
 
77
-	$pdo = DB::pdo();
77
+    $pdo = DB::pdo();
78 78
 
79
-	print_r(in_array("CAT:6",$default_ids));
79
+    print_r(in_array("CAT:6",$default_ids));
80 80
 
81
-	if (!$root_id) {
82
-		print "<select multiple=\true\" id=\"$id\" name=\"$id\" $attributes>";
83
-		if ($include_all_feeds) {
84
-			$is_selected = (in_array("0", $default_ids)) ? "selected=\"1\"" : "";
85
-			print "<option $is_selected value=\"0\">".__('All feeds')."</option>";
86
-		}
87
-	}
81
+    if (!$root_id) {
82
+        print "<select multiple=\true\" id=\"$id\" name=\"$id\" $attributes>";
83
+        if ($include_all_feeds) {
84
+            $is_selected = (in_array("0", $default_ids)) ? "selected=\"1\"" : "";
85
+            print "<option $is_selected value=\"0\">".__('All feeds')."</option>";
86
+        }
87
+    }
88 88
 
89
-	if (get_pref('ENABLE_FEED_CATS')) {
89
+    if (get_pref('ENABLE_FEED_CATS')) {
90 90
 
91
-		if (!$root_id) $root_id = null;
91
+        if (!$root_id) $root_id = null;
92 92
 
93
-		$sth = $pdo->prepare("SELECT id,title,
93
+        $sth = $pdo->prepare("SELECT id,title,
94 94
 				(SELECT COUNT(id) FROM ttrss_feed_categories AS c2 WHERE
95 95
 					c2.parent_cat = ttrss_feed_categories.id) AS num_children
96 96
 				FROM ttrss_feed_categories
97 97
 				WHERE owner_uid = :uid AND
98 98
 				(parent_cat = :root_id OR (:root_id IS NULL AND parent_cat IS NULL)) ORDER BY title");
99 99
 
100
-		$sth->execute([":uid" => $_SESSION['uid'], ":root_id" => $root_id]);
100
+        $sth->execute([":uid" => $_SESSION['uid'], ":root_id" => $root_id]);
101 101
 
102
-		while ($line = $sth->fetch()) {
102
+        while ($line = $sth->fetch()) {
103 103
 
104
-			for ($i = 0; $i < $nest_level; $i++)
105
-				$line["title"] = " - " . $line["title"];
104
+            for ($i = 0; $i < $nest_level; $i++)
105
+                $line["title"] = " - " . $line["title"];
106 106
 
107
-			$is_selected = in_array("CAT:".$line["id"], $default_ids) ? "selected=\"1\"" : "";
107
+            $is_selected = in_array("CAT:".$line["id"], $default_ids) ? "selected=\"1\"" : "";
108 108
 
109
-			printf("<option $is_selected value='CAT:%d'>%s</option>",
110
-				$line["id"], htmlspecialchars($line["title"]));
109
+            printf("<option $is_selected value='CAT:%d'>%s</option>",
110
+                $line["id"], htmlspecialchars($line["title"]));
111 111
 
112
-			if ($line["num_children"] > 0)
113
-				print_feed_multi_select($id, $default_ids, $attributes,
114
-					$include_all_feeds, $line["id"], $nest_level+1);
112
+            if ($line["num_children"] > 0)
113
+                print_feed_multi_select($id, $default_ids, $attributes,
114
+                    $include_all_feeds, $line["id"], $nest_level+1);
115 115
 
116
-			$f_sth = $pdo->prepare("SELECT id,title FROM ttrss_feeds
116
+            $f_sth = $pdo->prepare("SELECT id,title FROM ttrss_feeds
117 117
 					WHERE cat_id = ? AND owner_uid = ? ORDER BY title");
118 118
 
119
-			$f_sth->execute([$line['id'], $_SESSION['uid']]);
119
+            $f_sth->execute([$line['id'], $_SESSION['uid']]);
120 120
 
121
-			while ($fline = $f_sth->fetch()) {
122
-				$is_selected = (in_array($fline["id"], $default_ids)) ? "selected=\"1\"" : "";
121
+            while ($fline = $f_sth->fetch()) {
122
+                $is_selected = (in_array($fline["id"], $default_ids)) ? "selected=\"1\"" : "";
123 123
 
124
-				$fline["title"] = " + " . $fline["title"];
124
+                $fline["title"] = " + " . $fline["title"];
125 125
 
126
-				for ($i = 0; $i < $nest_level; $i++)
127
-					$fline["title"] = " - " . $fline["title"];
126
+                for ($i = 0; $i < $nest_level; $i++)
127
+                    $fline["title"] = " - " . $fline["title"];
128 128
 
129
-				printf("<option $is_selected value='%d'>%s</option>",
130
-					$fline["id"], htmlspecialchars($fline["title"]));
131
-			}
132
-		}
129
+                printf("<option $is_selected value='%d'>%s</option>",
130
+                    $fline["id"], htmlspecialchars($fline["title"]));
131
+            }
132
+        }
133 133
 
134
-		if (!$root_id) {
135
-			$is_selected = in_array("CAT:0", $default_ids) ? "selected=\"1\"" : "";
134
+        if (!$root_id) {
135
+            $is_selected = in_array("CAT:0", $default_ids) ? "selected=\"1\"" : "";
136 136
 
137
-			printf("<option $is_selected value='CAT:0'>%s</option>",
138
-				__("Uncategorized"));
137
+            printf("<option $is_selected value='CAT:0'>%s</option>",
138
+                __("Uncategorized"));
139 139
 
140
-			$f_sth = $pdo->prepare("SELECT id,title FROM ttrss_feeds
140
+            $f_sth = $pdo->prepare("SELECT id,title FROM ttrss_feeds
141 141
 					WHERE cat_id IS NULL AND owner_uid = ? ORDER BY title");
142
-			$f_sth->execute([$_SESSION['uid']]);
142
+            $f_sth->execute([$_SESSION['uid']]);
143 143
 
144
-			while ($fline = $f_sth->fetch()) {
145
-				$is_selected = in_array($fline["id"], $default_ids) ? "selected=\"1\"" : "";
144
+            while ($fline = $f_sth->fetch()) {
145
+                $is_selected = in_array($fline["id"], $default_ids) ? "selected=\"1\"" : "";
146 146
 
147
-				$fline["title"] = " + " . $fline["title"];
147
+                $fline["title"] = " + " . $fline["title"];
148 148
 
149
-				for ($i = 0; $i < $nest_level; $i++)
150
-					$fline["title"] = " - " . $fline["title"];
149
+                for ($i = 0; $i < $nest_level; $i++)
150
+                    $fline["title"] = " - " . $fline["title"];
151 151
 
152
-				printf("<option $is_selected value='%d'>%s</option>",
153
-					$fline["id"], htmlspecialchars($fline["title"]));
154
-			}
155
-		}
152
+                printf("<option $is_selected value='%d'>%s</option>",
153
+                    $fline["id"], htmlspecialchars($fline["title"]));
154
+            }
155
+        }
156 156
 
157
-	} else {
158
-		$sth = $pdo->prepare("SELECT id,title FROM ttrss_feeds
157
+    } else {
158
+        $sth = $pdo->prepare("SELECT id,title FROM ttrss_feeds
159 159
 				WHERE owner_uid = ? ORDER BY title");
160
-		$sth->execute([$_SESSION['uid']]);
160
+        $sth->execute([$_SESSION['uid']]);
161 161
 
162
-		while ($line = $sth->fetch()) {
162
+        while ($line = $sth->fetch()) {
163 163
 
164
-			$is_selected = (in_array($line["id"], $default_ids)) ? "selected=\"1\"" : "";
164
+            $is_selected = (in_array($line["id"], $default_ids)) ? "selected=\"1\"" : "";
165 165
 
166
-			printf("<option $is_selected value='%d'>%s</option>",
167
-				$line["id"], htmlspecialchars($line["title"]));
168
-		}
169
-	}
166
+            printf("<option $is_selected value='%d'>%s</option>",
167
+                $line["id"], htmlspecialchars($line["title"]));
168
+        }
169
+    }
170 170
 
171
-	if (!$root_id) {
172
-		print "</select>";
173
-	}
171
+    if (!$root_id) {
172
+        print "</select>";
173
+    }
174 174
 }
175 175
 
176 176
 function print_feed_cat_select($id, $default_id,
177
-							   $attributes, $include_all_cats = true, $root_id = null, $nest_level = 0) {
177
+                                $attributes, $include_all_cats = true, $root_id = null, $nest_level = 0) {
178 178
 
179
-	if (!$root_id) {
180
-		print "<select id=\"$id\" name=\"$id\" default=\"$default_id\" $attributes>";
181
-	}
179
+    if (!$root_id) {
180
+        print "<select id=\"$id\" name=\"$id\" default=\"$default_id\" $attributes>";
181
+    }
182 182
 
183
-	$pdo = DB::pdo();
183
+    $pdo = DB::pdo();
184 184
 
185
-	if (!$root_id) $root_id = null;
185
+    if (!$root_id) $root_id = null;
186 186
 
187
-	$sth = $pdo->prepare("SELECT id,title,
187
+    $sth = $pdo->prepare("SELECT id,title,
188 188
 				(SELECT COUNT(id) FROM ttrss_feed_categories AS c2 WHERE
189 189
 					c2.parent_cat = ttrss_feed_categories.id) AS num_children
190 190
 				FROM ttrss_feed_categories
191 191
 				WHERE owner_uid = :uid AND
192 192
 				  (parent_cat = :root_id OR (:root_id IS NULL AND parent_cat IS NULL)) ORDER BY title");
193
-	$sth->execute([":uid" => $_SESSION['uid'], ":root_id" => $root_id]);
194
-
195
-	$found = 0;
196
-
197
-	while ($line = $sth->fetch()) {
198
-		++$found;
199
-
200
-		if ($line["id"] == $default_id) {
201
-			$is_selected = "selected=\"1\"";
202
-		} else {
203
-			$is_selected = "";
204
-		}
205
-
206
-		for ($i = 0; $i < $nest_level; $i++)
207
-			$line["title"] = " - " . $line["title"];
208
-
209
-		if ($line["title"])
210
-			printf("<option $is_selected value='%d'>%s</option>",
211
-				$line["id"], htmlspecialchars($line["title"]));
212
-
213
-		if ($line["num_children"] > 0)
214
-			print_feed_cat_select($id, $default_id, $attributes,
215
-				$include_all_cats, $line["id"], $nest_level+1);
216
-	}
217
-
218
-	if (!$root_id) {
219
-		if ($include_all_cats) {
220
-			if ($found > 0) {
221
-				print "<option disabled=\"1\">--------</option>";
222
-			}
223
-
224
-			if ($default_id == 0) {
225
-				$is_selected = "selected=\"1\"";
226
-			} else {
227
-				$is_selected = "";
228
-			}
229
-
230
-			print "<option $is_selected value=\"0\">".__('Uncategorized')."</option>";
231
-		}
232
-		print "</select>";
233
-	}
193
+    $sth->execute([":uid" => $_SESSION['uid'], ":root_id" => $root_id]);
194
+
195
+    $found = 0;
196
+
197
+    while ($line = $sth->fetch()) {
198
+        ++$found;
199
+
200
+        if ($line["id"] == $default_id) {
201
+            $is_selected = "selected=\"1\"";
202
+        } else {
203
+            $is_selected = "";
204
+        }
205
+
206
+        for ($i = 0; $i < $nest_level; $i++)
207
+            $line["title"] = " - " . $line["title"];
208
+
209
+        if ($line["title"])
210
+            printf("<option $is_selected value='%d'>%s</option>",
211
+                $line["id"], htmlspecialchars($line["title"]));
212
+
213
+        if ($line["num_children"] > 0)
214
+            print_feed_cat_select($id, $default_id, $attributes,
215
+                $include_all_cats, $line["id"], $nest_level+1);
216
+    }
217
+
218
+    if (!$root_id) {
219
+        if ($include_all_cats) {
220
+            if ($found > 0) {
221
+                print "<option disabled=\"1\">--------</option>";
222
+            }
223
+
224
+            if ($default_id == 0) {
225
+                $is_selected = "selected=\"1\"";
226
+            } else {
227
+                $is_selected = "";
228
+            }
229
+
230
+            print "<option $is_selected value=\"0\">".__('Uncategorized')."</option>";
231
+        }
232
+        print "</select>";
233
+    }
234 234
 }
235 235
 
236 236
 function stylesheet_tag($filename, $id = false) {
237
-	$timestamp = filemtime($filename);
237
+    $timestamp = filemtime($filename);
238 238
 
239
-	$id_part = $id ? "id=\"$id\"" : "";
239
+    $id_part = $id ? "id=\"$id\"" : "";
240 240
 
241
-	return "<link rel=\"stylesheet\" $id_part type=\"text/css\" data-orig-href=\"$filename\" href=\"$filename?$timestamp\"/>\n";
241
+    return "<link rel=\"stylesheet\" $id_part type=\"text/css\" data-orig-href=\"$filename\" href=\"$filename?$timestamp\"/>\n";
242 242
 }
243 243
 
244 244
 function javascript_tag($filename) {
245
-	$query = "";
245
+    $query = "";
246 246
 
247
-	if (!(strpos($filename, "?") === FALSE)) {
248
-		$query = substr($filename, strpos($filename, "?")+1);
249
-		$filename = substr($filename, 0, strpos($filename, "?"));
250
-	}
247
+    if (!(strpos($filename, "?") === FALSE)) {
248
+        $query = substr($filename, strpos($filename, "?")+1);
249
+        $filename = substr($filename, 0, strpos($filename, "?"));
250
+    }
251 251
 
252
-	$timestamp = filemtime($filename);
252
+    $timestamp = filemtime($filename);
253 253
 
254
-	if ($query) $timestamp .= "&$query";
254
+    if ($query) $timestamp .= "&$query";
255 255
 
256
-	return "<script type=\"text/javascript\" charset=\"utf-8\" src=\"$filename?$timestamp\"></script>\n";
256
+    return "<script type=\"text/javascript\" charset=\"utf-8\" src=\"$filename?$timestamp\"></script>\n";
257 257
 }
258 258
 
259 259
 function format_warning($msg, $id = "") {
260
-	return "<div class=\"alert\" id=\"$id\">$msg</div>";
260
+    return "<div class=\"alert\" id=\"$id\">$msg</div>";
261 261
 }
262 262
 
263 263
 function format_notice($msg, $id = "") {
264
-	return "<div class=\"alert alert-info\" id=\"$id\">$msg</div>";
264
+    return "<div class=\"alert alert-info\" id=\"$id\">$msg</div>";
265 265
 }
266 266
 
267 267
 function format_error($msg, $id = "") {
268
-	return "<div class=\"alert alert-danger\" id=\"$id\">$msg</div>";
268
+    return "<div class=\"alert alert-danger\" id=\"$id\">$msg</div>";
269 269
 }
270 270
 
271 271
 function print_notice($msg) {
272
-	return print format_notice($msg);
272
+    return print format_notice($msg);
273 273
 }
274 274
 
275 275
 function print_warning($msg) {
276
-	return print format_warning($msg);
276
+    return print format_warning($msg);
277 277
 }
278 278
 
279 279
 function print_error($msg) {
280
-	return print format_error($msg);
280
+    return print format_error($msg);
281 281
 }
282 282
 
283 283
 function format_inline_player($url, $ctype) {
284 284
 
285
-	$entry = "";
285
+    $entry = "";
286 286
 
287
-	$url = htmlspecialchars($url);
287
+    $url = htmlspecialchars($url);
288 288
 
289
-	if (strpos($ctype, "audio/") === 0) {
289
+    if (strpos($ctype, "audio/") === 0) {
290 290
 
291
-		$entry .= "<div class='inline-player'>";
291
+        $entry .= "<div class='inline-player'>";
292 292
 
293
-		if ($_SESSION["hasAudio"] && (strpos($ctype, "ogg") !== false ||
294
-				$_SESSION["hasMp3"])) {
293
+        if ($_SESSION["hasAudio"] && (strpos($ctype, "ogg") !== false ||
294
+                $_SESSION["hasMp3"])) {
295 295
 
296
-			$entry .= "<audio preload=\"none\" controls>
296
+            $entry .= "<audio preload=\"none\" controls>
297 297
 					<source type=\"$ctype\" src=\"$url\"/>
298 298
 					</audio> ";
299 299
 
300
-		}
300
+        }
301 301
 
302
-		if ($entry) $entry .= "<a target=\"_blank\" rel=\"noopener noreferrer\"
302
+        if ($entry) $entry .= "<a target=\"_blank\" rel=\"noopener noreferrer\"
303 303
 				href=\"$url\">" . basename($url) . "</a>";
304 304
 
305
-		$entry .= "</div>";
305
+        $entry .= "</div>";
306 306
 
307
-		return $entry;
307
+        return $entry;
308 308
 
309
-	}
309
+    }
310 310
 
311
-	return "";
311
+    return "";
312 312
 }
313 313
 
314 314
 function print_label_select($name, $value, $attributes = "") {
315 315
 
316
-	$pdo = Db::pdo();
316
+    $pdo = Db::pdo();
317 317
 
318
-	$sth = $pdo->prepare("SELECT caption FROM ttrss_labels2
318
+    $sth = $pdo->prepare("SELECT caption FROM ttrss_labels2
319 319
 			WHERE owner_uid = ? ORDER BY caption");
320
-	$sth->execute([$_SESSION['uid']]);
320
+    $sth->execute([$_SESSION['uid']]);
321 321
 
322
-	print "<select default=\"$value\" name=\"" . htmlspecialchars($name) .
323
-		"\" $attributes>";
322
+    print "<select default=\"$value\" name=\"" . htmlspecialchars($name) .
323
+        "\" $attributes>";
324 324
 
325
-	while ($line = $sth->fetch()) {
325
+    while ($line = $sth->fetch()) {
326 326
 
327
-		$issel = ($line["caption"] == $value) ? "selected=\"1\"" : "";
327
+        $issel = ($line["caption"] == $value) ? "selected=\"1\"" : "";
328 328
 
329
-		print "<option value=\"".htmlspecialchars($line["caption"])."\"
329
+        print "<option value=\"".htmlspecialchars($line["caption"])."\"
330 330
 				$issel>" . htmlspecialchars($line["caption"]) . "</option>";
331 331
 
332
-	}
332
+    }
333 333
 
334 334
 #		print "<option value=\"ADD_LABEL\">" .__("Add label...") . "</option>";
335 335
 
336
-	print "</select>";
336
+    print "</select>";
337 337
 
338 338
 
339 339
 }
Please login to merge, or discard this patch.