Browse Source

move more globals to more appropriate places
set libxml to always use internal errors

Andrew Dolgov 2 months ago
parent
commit
088fcf8131
7 changed files with 386 additions and 390 deletions
  1. 251 3
      classes/feeds.php
  2. 10 2
      classes/pref/users.php
  3. 60 19
      classes/rssutils.php
  4. 3 363
      include/functions.php
  5. 17 1
      include/sanity_check.php
  6. 0 2
      plugins/cache_starred_images/init.php
  7. 45 0
      update.php

+ 251 - 3
classes/feeds.php

@@ -860,7 +860,7 @@ class Feeds extends Handler_Protected {
 
 			// fall back in case of no plugins
 			if (!$search_qpart) {
-				list($search_qpart, $search_words) = search_to_sql($search[0], $search[1]);
+				list($search_qpart, $search_words) = Feeds::search_to_sql($search[0], $search[1]);
 			}
 		} else {
 			$search_qpart = "true";
@@ -1456,7 +1456,7 @@ class Feeds extends Handler_Protected {
 
 			// fall back in case of no plugins
 			if (!$search_query_part) {
-				list($search_query_part, $search_words) = search_to_sql($search, $search_language);
+				list($search_query_part, $search_words) = Feeds::search_to_sql($search, $search_language);
 			}
 
 			if (DB_TYPE == "pgsql") {
@@ -1927,7 +1927,6 @@ class Feeds extends Handler_Protected {
 		$url     = Feeds::fix_url($url);
 		$baseUrl = substr($url, 0, strrpos($url, '/') + 1);
 
-		libxml_use_internal_errors(true);
 		$feedUrls = [];
 
 		$doc = new DOMDocument();
@@ -2070,5 +2069,254 @@ class Feeds extends Handler_Protected {
 			return $key;
 		}
 	}
+
+	/**
+	 * Purge a feed old posts.
+	 *
+	 * @param mixed $link A database connection.
+	 * @param mixed $feed_id The id of the purged feed.
+	 * @param mixed $purge_interval Olderness of purged posts.
+	 * @param boolean $debug Set to True to enable the debug. False by default.
+	 * @access public
+	 * @return void
+	 */
+	static function purge_feed($feed_id, $purge_interval) {
+
+		if (!$purge_interval) $purge_interval = Feeds::feed_purge_interval($feed_id);
+
+		$pdo = Db::pdo();
+
+		$sth = $pdo->prepare("SELECT owner_uid FROM ttrss_feeds WHERE id = ?");
+		$sth->execute([$feed_id]);
+
+		$owner_uid = false;
+
+		if ($row = $sth->fetch()) {
+			$owner_uid = $row["owner_uid"];
+		}
+
+		if ($purge_interval == -1 || !$purge_interval) {
+			if ($owner_uid) {
+				CCache::update($feed_id, $owner_uid);
+			}
+			return;
+		}
+
+		if (!$owner_uid) return;
+
+		if (FORCE_ARTICLE_PURGE == 0) {
+			$purge_unread = get_pref("PURGE_UNREAD_ARTICLES",
+				$owner_uid, false);
+		} else {
+			$purge_unread = true;
+			$purge_interval = FORCE_ARTICLE_PURGE;
+		}
+
+		if (!$purge_unread)
+			$query_limit = " unread = false AND ";
+		else
+			$query_limit = "";
+
+		$purge_interval = (int) $purge_interval;
+
+		if (DB_TYPE == "pgsql") {
+			$sth = $pdo->prepare("DELETE FROM ttrss_user_entries
+				USING ttrss_entries
+				WHERE ttrss_entries.id = ref_id AND
+				marked = false AND
+				feed_id = ? AND
+				$query_limit
+				ttrss_entries.date_updated < NOW() - INTERVAL '$purge_interval days'");
+			$sth->execute([$feed_id]);
+
+		} else {
+			$sth  = $pdo->prepare("DELETE FROM ttrss_user_entries
+				USING ttrss_user_entries, ttrss_entries
+				WHERE ttrss_entries.id = ref_id AND
+				marked = false AND
+				feed_id = ? AND
+				$query_limit
+				ttrss_entries.date_updated < DATE_SUB(NOW(), INTERVAL $purge_interval DAY)");
+			$sth->execute([$feed_id]);
+
+		}
+
+		$rows = $sth->rowCount();
+
+		CCache::update($feed_id, $owner_uid);
+
+		Debug::log("Purged feed $feed_id ($purge_interval): deleted $rows articles");
+
+		return $rows;
+	}
+
+	static function feed_purge_interval($feed_id) {
+
+		$pdo = DB::pdo();
+
+		$sth = $pdo->prepare("SELECT purge_interval, owner_uid FROM ttrss_feeds
+			WHERE id = ?");
+		$sth->execute([$feed_id]);
+
+		if ($row = $sth->fetch()) {
+			$purge_interval = $row["purge_interval"];
+			$owner_uid = $row["owner_uid"];
+
+			if ($purge_interval == 0) $purge_interval = get_pref(
+				'PURGE_OLD_DAYS', $owner_uid);
+
+			return $purge_interval;
+
+		} else {
+			return -1;
+		}
+	}
+
+	static function search_to_sql($search, $search_language) {
+
+		$keywords = str_getcsv(trim($search), " ");
+		$query_keywords = array();
+		$search_words = array();
+		$search_query_leftover = array();
+
+		$pdo = Db::pdo();
+
+		if ($search_language)
+			$search_language = $pdo->quote(mb_strtolower($search_language));
+		else
+			$search_language = $pdo->quote("english");
+
+		foreach ($keywords as $k) {
+			if (strpos($k, "-") === 0) {
+				$k = substr($k, 1);
+				$not = "NOT";
+			} else {
+				$not = "";
+			}
+
+			$commandpair = explode(":", mb_strtolower($k), 2);
+
+			switch ($commandpair[0]) {
+				case "title":
+					if ($commandpair[1]) {
+						array_push($query_keywords, "($not (LOWER(ttrss_entries.title) LIKE ".
+							$pdo->quote('%' . mb_strtolower($commandpair[1]) . '%') ."))");
+					} else {
+						array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER('%$k%')
+								OR UPPER(ttrss_entries.content) $not LIKE UPPER(".$pdo->quote("%$k%")."))");
+						array_push($search_words, $k);
+					}
+					break;
+				case "author":
+					if ($commandpair[1]) {
+						array_push($query_keywords, "($not (LOWER(author) LIKE ".
+							$pdo->quote('%' . mb_strtolower($commandpair[1]) . '%')."))");
+					} else {
+						array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER('%$k%')
+								OR UPPER(ttrss_entries.content) $not LIKE UPPER(".$pdo->quote("%$k%")."))");
+						array_push($search_words, $k);
+					}
+					break;
+				case "note":
+					if ($commandpair[1]) {
+						if ($commandpair[1] == "true")
+							array_push($query_keywords, "($not (note IS NOT NULL AND note != ''))");
+						else if ($commandpair[1] == "false")
+							array_push($query_keywords, "($not (note IS NULL OR note = ''))");
+						else
+							array_push($query_keywords, "($not (LOWER(note) LIKE ".
+								$pdo->quote('%' . mb_strtolower($commandpair[1]) . '%')."))");
+					} else {
+						array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER(".$pdo->quote("%$k%").")
+								OR UPPER(ttrss_entries.content) $not LIKE UPPER(".$pdo->quote("%$k%")."))");
+						if (!$not) array_push($search_words, $k);
+					}
+					break;
+				case "star":
+
+					if ($commandpair[1]) {
+						if ($commandpair[1] == "true")
+							array_push($query_keywords, "($not (marked = true))");
+						else
+							array_push($query_keywords, "($not (marked = false))");
+					} else {
+						array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER(".$pdo->quote("%$k%").")
+								OR UPPER(ttrss_entries.content) $not LIKE UPPER(".$pdo->quote("%$k%")."))");
+						if (!$not) array_push($search_words, $k);
+					}
+					break;
+				case "pub":
+					if ($commandpair[1]) {
+						if ($commandpair[1] == "true")
+							array_push($query_keywords, "($not (published = true))");
+						else
+							array_push($query_keywords, "($not (published = false))");
+
+					} else {
+						array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER('%$k%')
+								OR UPPER(ttrss_entries.content) $not LIKE UPPER(".$pdo->quote("%$k%")."))");
+						if (!$not) array_push($search_words, $k);
+					}
+					break;
+				case "unread":
+					if ($commandpair[1]) {
+						if ($commandpair[1] == "true")
+							array_push($query_keywords, "($not (unread = true))");
+						else
+							array_push($query_keywords, "($not (unread = false))");
+
+					} else {
+						array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER(".$pdo->quote("%$k%").")
+								OR UPPER(ttrss_entries.content) $not LIKE UPPER(".$pdo->quote("%$k%")."))");
+						if (!$not) array_push($search_words, $k);
+					}
+					break;
+				default:
+					if (strpos($k, "@") === 0) {
+
+						$user_tz_string = get_pref('USER_TIMEZONE', $_SESSION['uid']);
+						$orig_ts = strtotime(substr($k, 1));
+						$k = date("Y-m-d", convert_timestamp($orig_ts, $user_tz_string, 'UTC'));
+
+						//$k = date("Y-m-d", strtotime(substr($k, 1)));
+
+						array_push($query_keywords, "(".SUBSTRING_FOR_DATE."(updated,1,LENGTH('$k')) $not = '$k')");
+					} else {
+
+						if (DB_TYPE == "pgsql") {
+							$k = mb_strtolower($k);
+							array_push($search_query_leftover, $not ? "!$k" : $k);
+						} else {
+							array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER(".$pdo->quote("%$k%").")
+								OR UPPER(ttrss_entries.content) $not LIKE UPPER(".$pdo->quote("%$k%")."))");
+						}
+
+						if (!$not) array_push($search_words, $k);
+					}
+			}
+		}
+
+		if (count($search_query_leftover) > 0) {
+
+			if (DB_TYPE == "pgsql") {
+
+				// if there's no joiners consider this a "simple" search and
+				// concatenate everything with &, otherwise don't try to mess with tsquery syntax
+				if (preg_match("/[&|]/", implode(" " , $search_query_leftover))) {
+					$tsquery = $pdo->quote(implode(" ", $search_query_leftover));
+				} else {
+					$tsquery = $pdo->quote(implode(" & ", $search_query_leftover));
+				}
+
+				array_push($query_keywords,
+					"(tsvector_combined @@ to_tsquery($search_language, $tsquery))");
+			}
+
+		}
+
+		$search_query_part = implode("AND", $query_keywords);
+
+		return array($search_query_part, $search_words);
+	}
 }
 

+ 10 - 2
classes/pref/users.php

@@ -362,7 +362,7 @@ class Pref_Users extends Handler_Protected {
 			print "</div>"; #pane
 			print "<div style='padding : 0px' dojoType='dijit.layout.ContentPane' region='center'>";
 
-			$sort = validate_field($sort,
+			$sort = $this->validate_field($sort,
 				["login", "access_level", "created", "num_feeds", "created", "last_login"], "login");
 
 			if ($sort != "login") $sort = "$sort DESC";
@@ -435,4 +435,12 @@ class Pref_Users extends Handler_Protected {
 			print "</div>"; #container
 
 		}
-	}
+
+		function validate_field($string, $allowed, $default = "") {
+			if (in_array($string, $allowed))
+				return $string;
+			else
+				return $default;
+		}
+
+}

+ 60 - 19
classes/rssutils.php

@@ -1147,7 +1147,7 @@ class RSSUtils {
 
 			Debug::log("purging feed...", Debug::$LOG_VERBOSE);
 
-			purge_feed($feed, 0);
+			Feeds::purge_feed($feed, 0);
 
 			$sth = $pdo->prepare("UPDATE ttrss_feeds
 				SET last_updated = NOW(), last_unconditional = NOW(), last_error = '' WHERE id = ?");
@@ -1205,32 +1205,31 @@ class RSSUtils {
 	}
 
 	static function cache_media($html, $site_url) {
-		libxml_use_internal_errors(true);
-
 		$doc = new DOMDocument();
-		$doc->loadHTML('<?xml encoding="UTF-8">' . $html);
-		$xpath = new DOMXPath($doc);
+		if ($doc->loadHTML($html)) {
+			$xpath = new DOMXPath($doc);
 
-		$entries = $xpath->query('(//img[@src])|(//video/source[@src])|(//audio/source[@src])');
+			$entries = $xpath->query('(//img[@src])|(//video/source[@src])|(//audio/source[@src])');
 
-		foreach ($entries as $entry) {
-			if ($entry->hasAttribute('src') && strpos($entry->getAttribute('src'), "data:") !== 0) {
-				$src = rewrite_relative_url($site_url, $entry->getAttribute('src'));
+			foreach ($entries as $entry) {
+				if ($entry->hasAttribute('src') && strpos($entry->getAttribute('src'), "data:") !== 0) {
+					$src = rewrite_relative_url($site_url, $entry->getAttribute('src'));
 
-				$local_filename = CACHE_DIR . "/images/" . sha1($src);
+					$local_filename = CACHE_DIR . "/images/" . sha1($src);
 
-				Debug::log("cache_media: checking $src", Debug::$LOG_VERBOSE);
+					Debug::log("cache_media: checking $src", Debug::$LOG_VERBOSE);
 
-				if (!file_exists($local_filename)) {
-					Debug::log("cache_media: downloading: $src to $local_filename", Debug::$LOG_VERBOSE);
+					if (!file_exists($local_filename)) {
+						Debug::log("cache_media: downloading: $src to $local_filename", Debug::$LOG_VERBOSE);
 
-					$file_content = fetch_file_contents($src);
+						$file_content = fetch_file_contents($src);
 
-					if ($file_content && strlen($file_content) > MIN_CACHE_FILE_SIZE) {
-						file_put_contents($local_filename, $file_content);
+						if ($file_content && strlen($file_content) > MIN_CACHE_FILE_SIZE) {
+							file_put_contents($local_filename, $file_content);
+						}
+					} else if (is_writable($local_filename)) {
+						touch($local_filename);
 					}
-				} else if (is_writable($local_filename)) {
-					touch($local_filename);
 				}
 			}
 		}
@@ -1517,7 +1516,7 @@ class RSSUtils {
 		$icon_file = ICONS_DIR . "/$feed.ico";
 
 		if (!file_exists($icon_file)) {
-			$favicon_url = get_favicon_url($site_url);
+			$favicon_url = RSSUtils::get_favicon_url($site_url);
 
 			if ($favicon_url) {
 				// Limiting to "image" type misses those served with text/plain
@@ -1679,4 +1678,46 @@ class RSSUtils {
 
 		return $filters;
 	}
+
+	/**
+	 * Try to determine the favicon URL for a feed.
+	 * adapted from wordpress favicon plugin by Jeff Minard (http://thecodepro.com/)
+	 * http://dev.wp-plugins.org/file/favatars/trunk/favatars.php
+	 *
+	 * @param string $url A feed or page URL
+	 * @access public
+	 * @return mixed The favicon URL, or false if none was found.
+	 */
+	static function get_favicon_url($url) {
+
+		$favicon_url = false;
+
+		if ($html = @fetch_file_contents($url)) {
+
+			$doc = new DOMDocument();
+			if ($doc->loadHTML($html)) {
+				$xpath = new DOMXPath($doc);
+
+				$base = $xpath->query('/html/head/base[@href]');
+				foreach ($base as $b) {
+					$url = rewrite_relative_url($url, $b->getAttribute("href"));
+					break;
+				}
+
+				$entries = $xpath->query('/html/head/link[@rel="shortcut icon" or @rel="icon"]');
+				if (count($entries) > 0) {
+					foreach ($entries as $entry) {
+						$favicon_url = rewrite_relative_url($url, $entry->getAttribute("href"));
+						break;
+					}
+				}
+			}
+		}
+
+		if (!$favicon_url)
+			$favicon_url = rewrite_relative_url($url, "/favicon.ico");
+
+		return $favicon_url;
+	}
+
 }

+ 3 - 363
include/functions.php

@@ -15,6 +15,7 @@
 	$fetch_curl_used = false;
 
 	libxml_disable_entity_loader(true);
+	libxml_use_internal_errors(true);
 
 	// separate test because this is included before sanity checks
 	if (function_exists("mb_internal_encoding")) mb_internal_encoding("UTF-8");
@@ -160,108 +161,6 @@
 	    Debug::log($msg);
 	}
 
-	/**
-	 * Purge a feed old posts.
-	 *
-	 * @param mixed $link A database connection.
-	 * @param mixed $feed_id The id of the purged feed.
-	 * @param mixed $purge_interval Olderness of purged posts.
-	 * @param boolean $debug Set to True to enable the debug. False by default.
-	 * @access public
-	 * @return void
-	 */
-	function purge_feed($feed_id, $purge_interval) {
-
-		if (!$purge_interval) $purge_interval = feed_purge_interval($feed_id);
-
-		$pdo = Db::pdo();
-
-		$sth = $pdo->prepare("SELECT owner_uid FROM ttrss_feeds WHERE id = ?");
-		$sth->execute([$feed_id]);
-
-		$owner_uid = false;
-
-		if ($row = $sth->fetch()) {
-			$owner_uid = $row["owner_uid"];
-		}
-
-		if ($purge_interval == -1 || !$purge_interval) {
-			if ($owner_uid) {
-				CCache::update($feed_id, $owner_uid);
-			}
-			return;
-		}
-
-		if (!$owner_uid) return;
-
-		if (FORCE_ARTICLE_PURGE == 0) {
-			$purge_unread = get_pref("PURGE_UNREAD_ARTICLES",
-				$owner_uid, false);
-		} else {
-			$purge_unread = true;
-			$purge_interval = FORCE_ARTICLE_PURGE;
-		}
-
-		if (!$purge_unread)
-			$query_limit = " unread = false AND ";
-		else
-			$query_limit = "";
-
-		$purge_interval = (int) $purge_interval;
-
-		if (DB_TYPE == "pgsql") {
-			$sth = $pdo->prepare("DELETE FROM ttrss_user_entries
-				USING ttrss_entries
-				WHERE ttrss_entries.id = ref_id AND
-				marked = false AND
-				feed_id = ? AND
-				$query_limit
-				ttrss_entries.date_updated < NOW() - INTERVAL '$purge_interval days'");
-			$sth->execute([$feed_id]);
-
-		} else {
-			$sth  = $pdo->prepare("DELETE FROM ttrss_user_entries
-				USING ttrss_user_entries, ttrss_entries
-				WHERE ttrss_entries.id = ref_id AND
-				marked = false AND
-				feed_id = ? AND
-				$query_limit
-				ttrss_entries.date_updated < DATE_SUB(NOW(), INTERVAL $purge_interval DAY)");
-			$sth->execute([$feed_id]);
-
-		}
-
-		$rows = $sth->rowCount();
-
-		CCache::update($feed_id, $owner_uid);
-
-        Debug::log("Purged feed $feed_id ($purge_interval): deleted $rows articles");
-
-		return $rows;
-	} // function purge_feed
-
-	function feed_purge_interval($feed_id) {
-
-		$pdo = DB::pdo();
-
-		$sth = $pdo->prepare("SELECT purge_interval, owner_uid FROM ttrss_feeds
-			WHERE id = ?");
-		$sth->execute([$feed_id]);
-
-		if ($row = $sth->fetch()) {
-			$purge_interval = $row["purge_interval"];
-			$owner_uid = $row["owner_uid"];
-
-			if ($purge_interval == 0) $purge_interval = get_pref(
-				'PURGE_OLD_DAYS', $owner_uid);
-
-			return $purge_interval;
-
-		} else {
-			return -1;
-		}
-	}
-
 	// TODO: max_size currently only works for CURL transfers
 	// TODO: multiple-argument way is deprecated, first parameter is a hash now
 	function fetch_file_contents($options /* previously: 0: $url , 1: $type = false, 2: $login = false, 3: $pass = false,
@@ -544,48 +443,6 @@
 
 	}
 
-	/**
-	 * Try to determine the favicon URL for a feed.
-	 * adapted from wordpress favicon plugin by Jeff Minard (http://thecodepro.com/)
-	 * http://dev.wp-plugins.org/file/favatars/trunk/favatars.php
-	 *
-	 * @param string $url A feed or page URL
-	 * @access public
-	 * @return mixed The favicon URL, or false if none was found.
-	 */
-	function get_favicon_url($url) {
-
-		$favicon_url = false;
-
-		if ($html = @fetch_file_contents($url)) {
-
-			libxml_use_internal_errors(true);
-
-			$doc = new DOMDocument();
-			$doc->loadHTML('<?xml encoding="UTF-8">' . $html);
-			$xpath = new DOMXPath($doc);
-
-			$base = $xpath->query('/html/head/base[@href]');
-			foreach ($base as $b) {
-				$url = rewrite_relative_url($url, $b->getAttribute("href"));
-				break;
-			}
-
-			$entries = $xpath->query('/html/head/link[@rel="shortcut icon" or @rel="icon"]');
-			if (count($entries) > 0) {
-				foreach ($entries as $entry) {
-					$favicon_url = rewrite_relative_url($url, $entry->getAttribute("href"));
-					break;
-				}
-			}
-		}
-
-		if (!$favicon_url)
-			$favicon_url = rewrite_relative_url($url, "/favicon.ico");
-
-		return $favicon_url;
-	} // function get_favicon_url
-
 	function initialize_user_prefs($uid, $profile = false) {
 
 		if (get_schema_version() < 63) $profile_qpart = "";
@@ -1361,153 +1218,6 @@
 		return $data;
 	}
 
-	function search_to_sql($search, $search_language) {
-
-		$keywords = str_getcsv(trim($search), " ");
-		$query_keywords = array();
-		$search_words = array();
-		$search_query_leftover = array();
-
-		$pdo = Db::pdo();
-
-		if ($search_language)
-			$search_language = $pdo->quote(mb_strtolower($search_language));
-		else
-			$search_language = $pdo->quote("english");
-
-		foreach ($keywords as $k) {
-			if (strpos($k, "-") === 0) {
-				$k = substr($k, 1);
-				$not = "NOT";
-			} else {
-				$not = "";
-			}
-
-			$commandpair = explode(":", mb_strtolower($k), 2);
-
-			switch ($commandpair[0]) {
-				case "title":
-					if ($commandpair[1]) {
-						array_push($query_keywords, "($not (LOWER(ttrss_entries.title) LIKE ".
-							$pdo->quote('%' . mb_strtolower($commandpair[1]) . '%') ."))");
-					} else {
-						array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER('%$k%')
-								OR UPPER(ttrss_entries.content) $not LIKE UPPER(".$pdo->quote("%$k%")."))");
-						array_push($search_words, $k);
-					}
-					break;
-				case "author":
-					if ($commandpair[1]) {
-						array_push($query_keywords, "($not (LOWER(author) LIKE ".
-							$pdo->quote('%' . mb_strtolower($commandpair[1]) . '%')."))");
-					} else {
-						array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER('%$k%')
-								OR UPPER(ttrss_entries.content) $not LIKE UPPER(".$pdo->quote("%$k%")."))");
-						array_push($search_words, $k);
-					}
-					break;
-				case "note":
-					if ($commandpair[1]) {
-						if ($commandpair[1] == "true")
-							array_push($query_keywords, "($not (note IS NOT NULL AND note != ''))");
-						else if ($commandpair[1] == "false")
-							array_push($query_keywords, "($not (note IS NULL OR note = ''))");
-						else
-							array_push($query_keywords, "($not (LOWER(note) LIKE ".
-								$pdo->quote('%' . mb_strtolower($commandpair[1]) . '%')."))");
-					} else {
-						array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER(".$pdo->quote("%$k%").")
-								OR UPPER(ttrss_entries.content) $not LIKE UPPER(".$pdo->quote("%$k%")."))");
-						if (!$not) array_push($search_words, $k);
-					}
-					break;
-				case "star":
-
-					if ($commandpair[1]) {
-						if ($commandpair[1] == "true")
-							array_push($query_keywords, "($not (marked = true))");
-						else
-							array_push($query_keywords, "($not (marked = false))");
-					} else {
-						array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER(".$pdo->quote("%$k%").")
-								OR UPPER(ttrss_entries.content) $not LIKE UPPER(".$pdo->quote("%$k%")."))");
-						if (!$not) array_push($search_words, $k);
-					}
-					break;
-				case "pub":
-					if ($commandpair[1]) {
-						if ($commandpair[1] == "true")
-							array_push($query_keywords, "($not (published = true))");
-						else
-							array_push($query_keywords, "($not (published = false))");
-
-					} else {
-						array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER('%$k%')
-								OR UPPER(ttrss_entries.content) $not LIKE UPPER(".$pdo->quote("%$k%")."))");
-						if (!$not) array_push($search_words, $k);
-					}
-					break;
-				case "unread":
-					if ($commandpair[1]) {
-						if ($commandpair[1] == "true")
-							array_push($query_keywords, "($not (unread = true))");
-						else
-							array_push($query_keywords, "($not (unread = false))");
-
-					} else {
-						array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER(".$pdo->quote("%$k%").")
-								OR UPPER(ttrss_entries.content) $not LIKE UPPER(".$pdo->quote("%$k%")."))");
-						if (!$not) array_push($search_words, $k);
-					}
-					break;
-				default:
-					if (strpos($k, "@") === 0) {
-
-						$user_tz_string = get_pref('USER_TIMEZONE', $_SESSION['uid']);
-						$orig_ts = strtotime(substr($k, 1));
-						$k = date("Y-m-d", convert_timestamp($orig_ts, $user_tz_string, 'UTC'));
-
-						//$k = date("Y-m-d", strtotime(substr($k, 1)));
-
-						array_push($query_keywords, "(".SUBSTRING_FOR_DATE."(updated,1,LENGTH('$k')) $not = '$k')");
-					} else {
-
-						if (DB_TYPE == "pgsql") {
-							$k = mb_strtolower($k);
-							array_push($search_query_leftover, $not ? "!$k" : $k);
-						} else {
-							array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER(".$pdo->quote("%$k%").")
-								OR UPPER(ttrss_entries.content) $not LIKE UPPER(".$pdo->quote("%$k%")."))");
-						}
-
-						if (!$not) array_push($search_words, $k);
-					}
-			}
-		}
-
-		if (count($search_query_leftover) > 0) {
-
-			if (DB_TYPE == "pgsql") {
-
-				// if there's no joiners consider this a "simple" search and
-				// concatenate everything with &, otherwise don't try to mess with tsquery syntax
-				if (preg_match("/[&|]/", implode(" " , $search_query_leftover))) {
-					$tsquery = $pdo->quote(implode(" ", $search_query_leftover));
-				} else {
-					$tsquery = $pdo->quote(implode(" & ", $search_query_leftover));
-				}
-
-				array_push($query_keywords,
-					"(tsvector_combined @@ to_tsquery($search_language, $tsquery))");
-			}
-
-		}
-
-		$search_query_part = implode("AND", $query_keywords);
-
-		return array($search_query_part, $search_words);
-	}
-
 	function iframe_whitelisted($entry) {
 		$whitelist = array("youtube.com", "youtu.be", "vimeo.com", "player.vimeo.com");
 
@@ -1586,8 +1296,6 @@
 
 		$res = trim($str); if (!$res) return '';
 
-		libxml_use_internal_errors(true);
-
 		$doc = new DOMDocument();
 		$doc->loadHTML('<?xml encoding="UTF-8">' . $res);
 		$xpath = new DOMXPath($doc);
@@ -1901,51 +1609,6 @@
 		}
 	}
 
-	function cleanup_tags($days = 14, $limit = 1000) {
-
-		$days = (int) $days;
-
-		if (DB_TYPE == "pgsql") {
-			$interval_query = "date_updated < NOW() - INTERVAL '$days days'";
-		} else if (DB_TYPE == "mysql") {
-			$interval_query = "date_updated < DATE_SUB(NOW(), INTERVAL $days DAY)";
-		}
-
-		$tags_deleted = 0;
-
-		$pdo = Db::pdo();
-
-		while ($limit > 0) {
-			$limit_part = 500;
-
-			$sth = $pdo->prepare("SELECT ttrss_tags.id AS id
-					FROM ttrss_tags, ttrss_user_entries, ttrss_entries
-					WHERE post_int_id = int_id AND $interval_query AND
-					ref_id = ttrss_entries.id AND tag_cache != '' LIMIT ?");
-            $sth->bindValue(1, $limit_part, PDO::PARAM_INT);
-            $sth->execute();
-
-			$ids = array();
-
-			while ($line = $sth->fetch()) {
-				array_push($ids, $line['id']);
-			}
-
-			if (count($ids) > 0) {
-				$ids = join(",", $ids);
-
-				$usth = $pdo->query("DELETE FROM ttrss_tags WHERE id IN ($ids)");
-				$tags_deleted = $usth->rowCount();
-			} else {
-				break;
-			}
-
-			$limit -= $limit_part;
-		}
-
-		return $tags_deleted;
-	}
-
 	function print_user_stylesheet() {
 		$value = get_pref('USER_STYLESHEET');
 
@@ -1957,7 +1620,7 @@
 
 	}
 
-	function filter_to_sql($filter, $owner_uid) {
+	/* function filter_to_sql($filter, $owner_uid) {
 		$query = array();
 
 		$pdo = Db::pdo();
@@ -2043,7 +1706,7 @@
 		if ($filter['inverse']) $fullquery = "(NOT $fullquery)";
 
 		return $fullquery;
-	}
+	} */
 
 	if (!function_exists('gzdecode')) {
 		function gzdecode($string) { // no support for 2nd argument
@@ -2231,29 +1894,6 @@
 		}
 	}
 
-	function check_mysql_tables() {
-		$pdo = Db::pdo();
-
-		$sth = $pdo->prepare("SELECT engine, table_name FROM information_schema.tables WHERE
-			table_schema = ? AND table_name LIKE 'ttrss_%' AND engine != 'InnoDB'");
-		$sth->execute([DB_NAME]);
-
-		$bad_tables = [];
-
-		while ($line = $sth->fetch()) {
-			array_push($bad_tables, $line);
-		}
-
-		return $bad_tables;
-	}
-
-	function validate_field($string, $allowed, $default = "") {
-		if (in_array($string, $allowed))
-			return $string;
-		else
-			return $default;
-	}
-
 	function arr_qmarks($arr) {
 		return str_repeat('?,', count($arr) - 1) . '?';
 	}

+ 17 - 1
include/sanity_check.php

@@ -27,7 +27,23 @@
 		return $url_path;
 	}
 
-	/**
+	function check_mysql_tables() {
+		$pdo = Db::pdo();
+
+		$sth = $pdo->prepare("SELECT engine, table_name FROM information_schema.tables WHERE
+				table_schema = ? AND table_name LIKE 'ttrss_%' AND engine != 'InnoDB'");
+		$sth->execute([DB_NAME]);
+
+		$bad_tables = [];
+
+		while ($line = $sth->fetch()) {
+			array_push($bad_tables, $line);
+		}
+
+		return $bad_tables;
+	}
+
+/**
 	 * @SuppressWarnings(PHPMD.UnusedLocalVariable)
 	 */
 	function initial_sanity_check() {

+ 0 - 2
plugins/cache_starred_images/init.php

@@ -166,8 +166,6 @@ class Cache_Starred_Images extends Plugin implements IHandler {
 	 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
 	 */
 	function cache_article_images($content, $site_url, $owner_uid, $article_id) {
-		libxml_use_internal_errors(true);
-
 		$status_filename = $this->cache_dir . $article_id . "-" . sha1($site_url) . ".status";
 
 		Debug::log("status: $status_filename", Debug::$LOG_EXTENDED);

+ 45 - 0
update.php

@@ -14,6 +14,51 @@
 	require_once "db.php";
 	require_once "db-prefs.php";
 
+	function cleanup_tags($days = 14, $limit = 1000) {
+
+		$days = (int) $days;
+
+		if (DB_TYPE == "pgsql") {
+			$interval_query = "date_updated < NOW() - INTERVAL '$days days'";
+		} else if (DB_TYPE == "mysql") {
+			$interval_query = "date_updated < DATE_SUB(NOW(), INTERVAL $days DAY)";
+		}
+
+		$tags_deleted = 0;
+
+		$pdo = Db::pdo();
+
+		while ($limit > 0) {
+			$limit_part = 500;
+
+			$sth = $pdo->prepare("SELECT ttrss_tags.id AS id
+						FROM ttrss_tags, ttrss_user_entries, ttrss_entries
+						WHERE post_int_id = int_id AND $interval_query AND
+						ref_id = ttrss_entries.id AND tag_cache != '' LIMIT ?");
+			$sth->bindValue(1, $limit_part, PDO::PARAM_INT);
+			$sth->execute();
+
+			$ids = array();
+
+			while ($line = $sth->fetch()) {
+				array_push($ids, $line['id']);
+			}
+
+			if (count($ids) > 0) {
+				$ids = join(",", $ids);
+
+				$usth = $pdo->query("DELETE FROM ttrss_tags WHERE id IN ($ids)");
+				$tags_deleted = $usth->rowCount();
+			} else {
+				break;
+			}
+
+			$limit -= $limit_part;
+		}
+
+		return $tags_deleted;
+	}
+
 	if (!defined('PHP_EXECUTABLE'))
 		define('PHP_EXECUTABLE', '/usr/bin/php');