X-Git-Url: https://git.wh0rd.org/?a=blobdiff_plain;f=include%2Ffunctions.php;h=8ede14a0bfa7a188b036d8ac704aff70dd7c22a9;hb=a33558a61efc244ad8c809748e6ee64413e3a217;hp=8c8cf90132aa51303706cc3b7540dd66a6cd162a;hpb=74a8b2f6f1cd8d6c0556fbf11898ca8437e14816;p=tt-rss.git diff --git a/include/functions.php b/include/functions.php index 8c8cf901..8ede14a0 100644 --- a/include/functions.php +++ b/include/functions.php @@ -1,6 +1,6 @@ = 120) { $pref_lang = get_pref("USER_LANGUAGE", $_SESSION["uid"]); - if ($pref_lang) { + if ($pref_lang && $pref_lang != 'auto') { $lang = $pref_lang; } } @@ -138,6 +139,8 @@ * @return void */ function _debug($msg, $show = true) { + if (defined('SUPPRESS_DEBUGGING')) + return false; $ts = strftime("%H:%M:%S", time()); if (function_exists('posix_getpid')) { @@ -152,7 +155,29 @@ $fp = fopen(LOGFILE, 'a+'); if ($fp) { + $locked = false; + + if (function_exists("flock")) { + $tries = 0; + + // try to lock logfile for writing + while ($tries < 5 && !$locked = flock($fp, LOCK_EX | LOCK_NB)) { + sleep(1); + ++$tries; + } + + if (!$locked) { + fclose($fp); + return; + } + } + fputs($fp, "[$ts] $msg\n"); + + if (function_exists("flock")) { + flock($fp, LOCK_UN); + } + fclose($fp); } } @@ -317,7 +342,12 @@ $fetch_curl_used = true; if (ini_get("safe_mode") || ini_get("open_basedir")) { - $ch = curl_init(geturl($url)); + $new_url = geturl($url); + if (!$new_url) { + // geturl has already populated $fetch_last_error + return false; + } + $ch = curl_init($new_url); } else { $ch = curl_init($url); } @@ -344,6 +374,10 @@ curl_setopt($ch, CURLOPT_POSTFIELDS, $post_query); } + if ((OPENSSL_VERSION_NUMBER >= 0x0090808f) && (OPENSSL_VERSION_NUMBER < 0x10000000)) { + curl_setopt($ch, CURLOPT_SSLVERSION, 3); + } + if ($login && $pass) curl_setopt($ch, CURLOPT_USERPWD, "$login:$pass"); @@ -961,27 +995,43 @@ } function file_is_locked($filename) { - if (function_exists('flock')) { - $fp = @fopen(LOCK_DIRECTORY . "/$filename", "r"); - if ($fp) { - if (flock($fp, LOCK_EX | LOCK_NB)) { - flock($fp, LOCK_UN); + if (file_exists(LOCK_DIRECTORY . "/$filename")) { + if (function_exists('flock')) { + $fp = @fopen(LOCK_DIRECTORY . "/$filename", "r"); + if ($fp) { + if (flock($fp, LOCK_EX | LOCK_NB)) { + flock($fp, LOCK_UN); + fclose($fp); + return false; + } fclose($fp); + return true; + } else { return false; } - fclose($fp); - return true; - } else { - return false; } + return true; // consider the file always locked and skip the test + } else { + return false; } - return true; // consider the file always locked and skip the test } + function make_lockfile($filename) { $fp = fopen(LOCK_DIRECTORY . "/$filename", "w"); if ($fp && flock($fp, LOCK_EX | LOCK_NB)) { + $stat_h = fstat($fp); + $stat_f = stat(LOCK_DIRECTORY . "/$filename"); + + if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') { + if ($stat_h["ino"] != $stat_f["ino"] || + $stat_h["dev"] != $stat_f["dev"]) { + + return false; + } + } + if (function_exists('posix_getpid')) { fwrite($fp, posix_getpid() . "\n"); } @@ -1037,7 +1087,7 @@ $date_qpart = "date_entered < DATE_SUB(NOW(), INTERVAL 1 WEEK) "; } break; - case "2weeks": + case "2week": if (DB_TYPE == "pgsql") { $date_qpart = "date_entered < NOW() - INTERVAL '2 week' "; } else { @@ -1459,8 +1509,14 @@ $count = getFeedUnread($i); + if ($i == 0 || $i == -1 || $i == -2) + $auxctr = getFeedArticles($i, false); + else + $auxctr = 0; + $cv = array("id" => $i, - "counter" => (int) $count); + "counter" => (int) $count, + "auxcounter" => $auxctr); // if (get_pref('EXTENDED_FEEDLIST')) // $cv["xmsg"] = getFeedArticles($i)." ".__("total"); @@ -1474,7 +1530,11 @@ foreach ($feeds as $feed) { $cv = array("id" => PluginHost::pfeed_to_feed_id($feed['id']), "counter" => $feed['sender']->get_unread($feed['id'])); - array_push($ret_arr, $cv); + + if (method_exists($feed['sender'], 'get_total')) + $cv["auxcounter"] = $feed['sender']->get_total($feed['id']); + + array_push($ret_arr, $cv); } } @@ -1487,11 +1547,13 @@ $owner_uid = $_SESSION["uid"]; - $result = db_query("SELECT id,caption,COUNT(unread) AS unread + $result = db_query("SELECT id,caption,COUNT(u1.unread) AS unread,COUNT(u2.unread) AS total FROM ttrss_labels2 LEFT JOIN ttrss_user_labels2 ON (ttrss_labels2.id = label_id) - LEFT JOIN ttrss_user_entries ON (ref_id = article_id AND unread = true - AND ttrss_user_entries.owner_uid = $owner_uid) + LEFT JOIN ttrss_user_entries AS u1 ON (u1.ref_id = article_id AND u1.unread = true + AND u1.owner_uid = $owner_uid) + LEFT JOIN ttrss_user_entries AS u2 ON (u2.ref_id = article_id AND u2.unread = false + AND u2.owner_uid = $owner_uid) WHERE ttrss_labels2.owner_uid = $owner_uid GROUP BY ttrss_labels2.id, ttrss_labels2.caption"); @@ -1499,17 +1561,12 @@ $id = label_to_feed_id($line["id"]); - $label_name = $line["caption"]; - $count = $line["unread"]; - $cv = array("id" => $id, - "counter" => (int) $count); + "counter" => (int) $line["unread"], + "auxcounter" => (int) $line["total"]); if ($descriptions) - $cv["description"] = $label_name; - -// if (get_pref('EXTENDED_FEEDLIST')) -// $cv["xmsg"] = getFeedArticles($id)." ".__("total"); + $cv["description"] = $line["caption"]; array_push($ret_arr, $cv); } @@ -1661,7 +1718,7 @@ $feed_id = db_fetch_result($result, 0, "id"); if ($feed_id) { - update_rss_feed($feed_id, false, false, false, $contents); + update_rss_feed($feed_id, true); } return array("code" => 1); @@ -1851,19 +1908,19 @@ return "images/archive.png"; break; case -1: - return "images/mark_set.svg"; + return "images/star.png"; break; case -2: - return "images/pub_set.svg"; + return "images/feed.png"; break; case -3: return "images/fresh.png"; break; case -4: - return "images/tag.png"; + return "images/folder.png"; break; case -6: - return "images/recently_read.png"; + return "images/time.png"; break; default: if ($id < LABEL_BASE_INDEX) { @@ -1942,7 +1999,6 @@ $params["max_feed_id"] = (int) $max_feed_id; $params["num_feeds"] = (int) $num_feeds; - $params["collapsed_feedlist"] = (int) get_pref("_COLLAPSED_FEEDLIST"); $params["hotkeys"] = get_hotkeys_map(); $params["csrf_token"] = $_SESSION["csrf_token"]; @@ -2172,6 +2228,7 @@ $keywords = explode(" ", $search); $query_keywords = array(); + $search_words = array(); foreach ($keywords as $k) { if (strpos($k, "-") === 0) { @@ -2191,6 +2248,7 @@ } else { array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER('%$k%') OR UPPER(ttrss_entries.content) $not LIKE UPPER('%$k%'))"); + array_push($search_words, $k); } break; case "author": @@ -2200,6 +2258,7 @@ } else { array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER('%$k%') OR UPPER(ttrss_entries.content) $not LIKE UPPER('%$k%'))"); + array_push($search_words, $k); } break; case "note": @@ -2214,6 +2273,7 @@ } else { array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER('%$k%') OR UPPER(ttrss_entries.content) $not LIKE UPPER('%$k%'))"); + if (!$not) array_push($search_words, $k); } break; case "star": @@ -2226,6 +2286,7 @@ } else { array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER('%$k%') OR UPPER(ttrss_entries.content) $not LIKE UPPER('%$k%'))"); + if (!$not) array_push($search_words, $k); } break; case "pub": @@ -2238,6 +2299,7 @@ } else { array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER('%$k%') OR UPPER(ttrss_entries.content) $not LIKE UPPER('%$k%'))"); + if (!$not) array_push($search_words, $k); } break; default: @@ -2253,13 +2315,15 @@ } else { array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER('%$k%') OR UPPER(ttrss_entries.content) $not LIKE UPPER('%$k%'))"); + + if (!$not) array_push($search_words, $k); } } } $search_query_part = implode("AND", $query_keywords); - return $search_query_part; + return array($search_query_part, $search_words); } function getParentCategories($cat, $owner_uid) { @@ -2290,11 +2354,12 @@ return $rv; } - function queryFeedHeadlines($feed, $limit, $view_mode, $cat_view, $search, $search_mode, $override_order = false, $offset = 0, $owner_uid = 0, $filter = false, $since_id = 0, $include_children = false, $ignore_vfeed_group = false) { + function queryFeedHeadlines($feed, $limit, $view_mode, $cat_view, $search, $search_mode, $override_order = false, $offset = 0, $owner_uid = 0, $filter = false, $since_id = 0, $include_children = false, $ignore_vfeed_group = false, $override_strategy = false, $override_vfeed = false) { if (!$owner_uid) $owner_uid = $_SESSION["uid"]; $ext_tables_part = ""; + $search_words = array(); if ($search) { @@ -2307,7 +2372,7 @@ $search_query_part = "ref_id = -1 AND "; } else { - $search_query_part = search_to_sql($search); + list($search_query_part, $search_words) = search_to_sql($search); $search_query_part .= " AND "; } @@ -2328,8 +2393,10 @@ $filter_query_part = filter_to_sql($filter, $owner_uid); // Try to check if SQL regexp implementation chokes on a valid regexp + + $result = db_query("SELECT true AS true_val FROM ttrss_entries, - ttrss_user_entries, ttrss_feeds, ttrss_feed_categories + ttrss_user_entries, ttrss_feeds WHERE $filter_query_part LIMIT 1", false); if ($result) { @@ -2490,6 +2557,11 @@ $allow_archived = true; if (!$override_order) $override_order = "last_read DESC"; + +/* } else if ($feed == -7) { // shared + $query_strategy_part = "uuid != ''"; + $vfeed_query_part = "ttrss_feeds.title AS feed_title,"; + $allow_archived = true; */ } else if ($feed == -3) { // fresh virtual feed $query_strategy_part = "unread = true AND score >= 0"; @@ -2531,6 +2603,14 @@ $order_by = $override_order; } + if ($override_strategy) { + $query_strategy_part = $override_strategy; + } + + if ($override_vfeed) { + $vfeed_query_part = $override_vfeed; + } + $feed_title = ""; if ($search) { @@ -2553,7 +2633,9 @@ } } - $content_query_part = "content as content_preview, cached_content, "; + + $content_query_part = "content, content AS content_preview, "; + if (is_numeric($feed)) { @@ -2601,6 +2683,8 @@ num_comments, comments, int_id, + uuid, + lang, hide_images, unread,feed_id,marked,published,link,last_read,orig_feed_id, last_marked, last_published, @@ -2643,6 +2727,8 @@ "tag_cache," . "label_cache," . "link," . + "lang," . + "uuid," . "last_read," . "(SELECT hide_images FROM ttrss_feeds WHERE id = feed_id) AS hide_images," . "last_marked, last_published, " . @@ -2694,18 +2780,15 @@ $result = db_query($select_qpart . $from_qpart . $where_qpart); } - return array($result, $feed_title, $feed_site_url, $last_error, $last_updated); + return array($result, $feed_title, $feed_site_url, $last_error, $last_updated, $search_words); } - function sanitize($str, $force_remove_images = false, $owner = false, $site_url = false) { + function sanitize($str, $force_remove_images = false, $owner = false, $site_url = false, $highlight_words = false, $article_id = false) { if (!$owner) $owner = $_SESSION["uid"]; $res = trim($str); if (!$res) return ''; - if (strpos($res, "href=") === false) - $res = rewrite_urls($res); - $charset_hack = ' '; @@ -2787,7 +2870,7 @@ $disallowed_attributes = array('id', 'style', 'class'); foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_SANITIZE) as $plugin) { - $retval = $plugin->hook_sanitize($doc, $site_url, $allowed_elements, $disallowed_attributes); + $retval = $plugin->hook_sanitize($doc, $site_url, $allowed_elements, $disallowed_attributes, $article_id); if (is_array($retval)) { $doc = $retval[0]; $allowed_elements = $retval[1]; @@ -2799,7 +2882,39 @@ $doc->removeChild($doc->firstChild); //remove doctype $doc = strip_harmful_tags($doc, $allowed_elements, $disallowed_attributes); + + if ($highlight_words) { + foreach ($highlight_words as $word) { + + // http://stackoverflow.com/questions/4081372/highlight-keywords-in-a-paragraph + + $elements = $xpath->query("//*/text()"); + + foreach ($elements as $child) { + + $fragment = $doc->createDocumentFragment(); + $text = $child->textContent; + $stubs = array(); + + while (($pos = mb_stripos($text, $word)) !== false) { + $fragment->appendChild(new DomText(mb_substr($text, 0, $pos))); + $word = mb_substr($text, $pos, mb_strlen($word)); + $highlight = $doc->createElement('span'); + $highlight->appendChild(new DomText($word)); + $highlight->setAttribute('class', 'highlight'); + $fragment->appendChild($highlight); + $text = mb_substr($text, $pos + mb_strlen($word)); + } + + if (!empty($text)) $fragment->appendChild(new DomText($text)); + + $child->parentNode->replaceChild($fragment, $child); + } + } + } + $res = $doc->saveHTML(); + return $res; } @@ -2948,10 +3063,6 @@ if (preg_match("/^[0-9]*$/", $tag)) return false; if (mb_strlen($tag) > 250) return false; - if (function_exists('iconv')) { - $tag = iconv("utf-8", "utf-8", $tag); - } - if (!$tag) return false; return true; @@ -2967,19 +3078,19 @@ function format_warning($msg, $id = "") { global $link; return "
- $msg
"; + $msg"; } function format_notice($msg, $id = "") { global $link; return "
- $msg
"; + $msg"; } function format_error($msg, $id = "") { global $link; return "
- $msg
"; + $msg"; } function print_notice($msg) { @@ -3011,7 +3122,7 @@ if ($_SESSION["hasAudio"] && (strpos($ctype, "ogg") !== false || $_SESSION["hasMp3"])) { - $entry .= "