X-Git-Url: https://git.wh0rd.org/?a=blobdiff_plain;f=include%2Ffunctions.php;h=b338bde5bc5eb468c43d99db34a61c51a68268c7;hb=8dcb2b47628346226b18940b5cde7849f7a24687;hp=0156ddf9a1394e0dc3fc957b6481f56f27758f02;hpb=f99759dae4ce97b44da9da1edf03e4ac64085ae0;p=tt-rss.git diff --git a/include/functions.php b/include/functions.php index 0156ddf9..b338bde5 100644 --- a/include/functions.php +++ b/include/functions.php @@ -1,6 +1,6 @@ "Italiano", "ja_JP" => "日本語 (Japanese)", "nb_NO" => "Norwegian bokmÃ¥l", + "pl_PL" => "Polski", "ru_RU" => "Русский", "pt_BR" => "Portuguese/Brazil", "zh_CN" => "Simplified Chinese"); @@ -69,14 +71,11 @@ $lang = _TRANSLATION_OVERRIDE_DEFAULT; } - if ($_COOKIE["ttrss_lang"] && $_COOKIE["ttrss_lang"] != "auto") { - $lang = $_COOKIE["ttrss_lang"]; - } - /* In login action of mobile version */ if ($_POST["language"] && defined('MOBILE_VERSION')) { $lang = $_POST["language"]; - $_COOKIE["ttrss_lang"] = $lang; + } else { + $lang = $_SESSION["language"]; } if ($lang) { @@ -110,8 +109,7 @@ ini_set('user_agent', SELF_USER_AGENT); require_once 'lib/pubsubhubbub/publisher.php'; - - $purifier = false; + require_once 'lib/htmLawed.php'; $tz_offset = -1; $utc_tz = new DateTimeZone('UTC'); @@ -465,104 +463,6 @@ print ""; } - function get_article_filters($filters, $title, $content, $link, $timestamp, $author, $tags) { - $matches = array(); - - foreach ($filters as $filter) { - $match_any_rule = $filter["match_any_rule"]; - $filter_match = false; - - foreach ($filter["rules"] as $rule) { - $match = false; - $reg_exp = $rule["reg_exp"]; - - if (!$reg_exp) - continue; - - switch ($rule["type"]) { - case "title": - $match = @preg_match("/$reg_exp/i", $title); - break; - case "content": - $match = @preg_match("/$reg_exp/i", $content); - break; - case "both": - $match = (@preg_match("/$reg_exp/i", $title) || @preg_match("/$reg_exp/i", $title)); - break; - case "link": - $match = @preg_match("/$reg_exp/i", $link); - break; - case "author": - $match = @preg_match("/$reg_exp/i", $author); - break; - case "tag": - $tag_string = join(",", $tags); - $match = @preg_match("/$reg_exp/i", $tag_string); - break; - } - - if ($match_any_rule) { - if ($match) { - $filter_match = true; - break; - } - } else { - $filter_match = $match; - if (!$match) { - break; - } - } - } - - if ($filter_match) { - foreach ($filter["actions"] AS $action) { - array_push($matches, $action); - } - } - } - - return $matches; - } - - function find_article_filter($filters, $filter_name) { - foreach ($filters as $f) { - if ($f["type"] == $filter_name) { - return $f; - }; - } - return false; - } - - function find_article_filters($filters, $filter_name) { - $results = array(); - - foreach ($filters as $f) { - if ($f["type"] == $filter_name) { - array_push($results, $f); - }; - } - return $results; - } - - function calculate_article_score($filters) { - $score = 0; - - foreach ($filters as $f) { - if ($f["type"] == "score") { - $score += $f["param"]; - }; - } - return $score; - } - - function assign_article_to_labels($link, $id, $filters, $owner_uid) { - foreach ($filters as $f) { - if ($f["type"] == "label") { - label_add_article($link, $id, $f["param"], $owner_uid); - }; - } - } - function getmicrotime() { list($usec, $sec) = explode(" ",microtime()); return ((float)$usec + (float)$sec); @@ -833,90 +733,14 @@ /* bump login timestamp */ db_query($link, "UPDATE ttrss_users SET last_login = NOW() WHERE id = " . $_SESSION["uid"]); - - if ($_SESSION["language"] && SESSION_COOKIE_LIFETIME > 0) { - setcookie("ttrss_lang", $_SESSION["language"], - time() + SESSION_COOKIE_LIFETIME); - } } - } - } - - - /* function login_sequence($link, $mobile = false) { - $_SESSION["prefs_cache"] = array(); - - if (!SINGLE_USER_MODE) { - - $login_action = $_POST["login_action"]; - - # try to authenticate user if called from login form - if ($login_action == "do_login") { - $login = db_escape_string($_POST["login"]); - $password = $_POST["password"]; - $remember_me = $_POST["remember_me"]; - - if (authenticate_user($link, $login, $password)) { - $_POST["password"] = ""; - - $_SESSION["language"] = $_POST["language"]; - $_SESSION["ref_schema_version"] = get_schema_version($link, true); - $_SESSION["bw_limit"] = !!$_POST["bw_limit"]; - - if ($_POST["profile"]) { - $profile = db_escape_string($_POST["profile"]); - - $result = db_query($link, "SELECT id FROM ttrss_settings_profiles - WHERE id = '$profile' AND owner_uid = " . $_SESSION["uid"]); - - if (db_num_rows($result) != 0) { - $_SESSION["profile"] = $profile; - $_SESSION["prefs_cache"] = array(); - } - } - - if ($_REQUEST['return']) { - header("Location: " . $_REQUEST['return']); - } else { - header("Location: " . $_SERVER["REQUEST_URI"]); - } - - exit; - - return; - } else { - $_SESSION["login_error_msg"] = __("Incorrect username or password"); - } + if ($_SESSION["uid"] && $_SESSION["language"] && SESSION_COOKIE_LIFETIME > 0) { + setcookie("ttrss_lang", $_SESSION["language"], + time() + SESSION_COOKIE_LIFETIME); } - - if (!$_SESSION["uid"] || !validate_session($link)) { - - if (AUTH_AUTO_LOGIN && authenticate_user($link, null, null)) { - $_SESSION["ref_schema_version"] = get_schema_version($link, true); - } else { - authenticate_user($link, null, null, true); - render_login_form($link, $mobile); - exit; - } - } else { - // bump login timestamp - db_query($link, "UPDATE ttrss_users SET last_login = NOW() WHERE id = " . - $_SESSION["uid"]); - - if ($_SESSION["language"] && SESSION_COOKIE_LIFETIME > 0) { - setcookie("ttrss_lang", $_SESSION["language"], - time() + SESSION_COOKIE_LIFETIME); - } - - // try to remove possible duplicates from feed counter cache -// ccache_cleanup($link, $_SESSION["uid"]); - } - - } else { - return authenticate_user($link, "admin", null); } - } */ + } function truncate_string($str, $max_len, $suffix = '…') { if (mb_strlen($str, "utf-8") > $max_len - 3) { @@ -1232,24 +1056,22 @@ if ($feed >= 0) { if ($feed > 0) { - $cat_qpart = "cat_id = '$feed'"; + $children = getChildCategories($link, $feed, $owner_uid); + array_push($children, $feed); + + $children = join(",", $children); + + $cat_qpart = "cat_id IN ($children)"; } else { $cat_qpart = "cat_id IS NULL"; } - $tmp_result = db_query($link, "SELECT id - FROM ttrss_feeds WHERE $cat_qpart AND owner_uid = $owner_uid"); - - while ($tmp_line = db_fetch_assoc($tmp_result)) { - - $tmp_feed = $tmp_line["id"]; + db_query($link, "UPDATE ttrss_user_entries + SET unread = false,last_read = NOW() + WHERE feed_id IN (SELECT id FROM ttrss_feeds WHERE $cat_qpart) + AND $ref_check_qpart + AND owner_uid = $owner_uid"); - db_query($link, "UPDATE ttrss_user_entries - SET unread = false,last_read = NOW() - WHERE feed_id = '$tmp_feed' - AND $ref_check_qpart - AND owner_uid = $owner_uid"); - } } else if ($feed == -2) { db_query($link, "UPDATE ttrss_user_entries @@ -1412,8 +1234,7 @@ } $cv = array("id" => $line["cat_id"], "kind" => "cat", - "child_counter" => $child_counter, - "counter" => $line["unread"]); + "counter" => $line["unread"] + $child_counter); array_push($ret_arr, $cv); } @@ -1421,7 +1242,7 @@ /* Special case: NULL category doesn't actually exist in the DB */ $cv = array("id" => 0, "kind" => "cat", - "counter" => ccache_find($link, 0, $_SESSION["uid"], true)); + "counter" => (int) ccache_find($link, 0, $_SESSION["uid"], true)); array_push($ret_arr, $cv); @@ -1631,7 +1452,7 @@ } $cv = array("id" => "global-unread", - "counter" => $global_unread); + "counter" => (int) $global_unread); array_push($ret_arr, $cv); @@ -1641,7 +1462,7 @@ $subscribed_feeds = db_fetch_result($result, 0, "fn"); $cv = array("id" => "subscribed-feeds", - "counter" => $subscribed_feeds); + "counter" => (int) $subscribed_feeds); array_push($ret_arr, $cv); @@ -1687,7 +1508,7 @@ $count = getFeedUnread($link, $i); $cv = array("id" => $i, - "counter" => $count); + "counter" => (int) $count); // if (get_pref($link, 'EXTENDED_FEEDLIST')) // $cv["xmsg"] = getFeedArticles($link, $i)." ".__("total"); @@ -1715,7 +1536,7 @@ $count = getFeedUnread($link, $id); $cv = array("id" => $id, - "counter" => $count); + "counter" => (int) $count); if ($descriptions) $cv["description"] = $label_name; @@ -1760,7 +1581,7 @@ $cv = array("id" => $id, "updated" => $last_updated, - "counter" => $count, + "counter" => (int) $count, "has_img" => (int) $has_img); if ($last_error) @@ -2123,7 +1944,6 @@ $params["icons_url"] = ICONS_URL; $params["cookie_lifetime"] = SESSION_COOKIE_LIFETIME; - $params["default_include_children"] = get_pref($link, "_DEFAULT_INCLUDE_CHILDREN"); $params["default_view_mode"] = get_pref($link, "_DEFAULT_VIEW_MODE"); $params["default_view_limit"] = (int) get_pref($link, "_DEFAULT_VIEW_LIMIT"); $params["default_view_order_by"] = get_pref($link, "_DEFAULT_VIEW_ORDER_BY"); @@ -2261,6 +2081,20 @@ return $search_query_part; } + function getParentCategories($link, $cat, $owner_uid) { + $rv = array(); + + $result = db_query($link, "SELECT parent_cat FROM ttrss_feed_categories + WHERE id = '$cat' AND parent_cat IS NOT NULL AND owner_uid = $owner_uid"); + + while ($line = db_fetch_assoc($result)) { + array_push($rv, $line["parent_cat"]); + $rv = array_merge($rv, getParentCategories($link, $line["parent_cat"], $owner_uid)); + } + + return $rv; + } + function getChildCategories($link, $cat, $owner_uid) { $rv = array(); @@ -2310,7 +2144,21 @@ $override_order = "updated DESC"; - $filter_query_part = filter_to_sql($filter) . " AND"; + $filter_query_part = filter_to_sql($link, $filter, $owner_uid); + + // Try to check if SQL regexp implementation chokes on a valid regexp + $result = db_query($link, "SELECT true AS true FROM ttrss_entries, + ttrss_user_entries, ttrss_feeds, ttrss_feed_categories + WHERE $filter_query_part LIMIT 1", false); + + $test = db_fetch_result($result, 0, "true"); + + if (!$test) { + $filter_query_part = "false AND"; + } else { + $filter_query_part .= " AND"; + } + } else { $filter_query_part = ""; } @@ -2424,6 +2272,8 @@ } else if ($feed == -1) { // starred virtual feed $query_strategy_part = "marked = true"; $vfeed_query_part = "ttrss_feeds.title AS feed_title,"; + $allow_archived = true; + } else if ($feed == -2) { // published virtual feed OR labels category if (!$cat_view) { @@ -2444,6 +2294,7 @@ } else if ($feed == -6) { // recently read $query_strategy_part = "unread = false AND last_read IS NOT NULL"; $vfeed_query_part = "ttrss_feeds.title AS feed_title,"; + $allow_archived = true; if (!$override_order) $override_order = "last_read DESC"; } else if ($feed == -3) { // fresh virtual feed @@ -2470,9 +2321,10 @@ $vfeed_query_part = "ttrss_feeds.title AS feed_title,"; $ext_tables_part = ",ttrss_labels2,ttrss_user_labels2"; + $allow_archived = true; } else { - $query_strategy_part = "id > 0"; // dumb + $query_strategy_part = "true"; } if (get_pref($link, "SORT_HEADLINES_BY_FEED_DATE", $owner_uid)) { @@ -2516,7 +2368,7 @@ } } - $content_query_part = "content as content_preview,"; + $content_query_part = "content as content_preview, cached_content, "; if (is_numeric($feed)) { @@ -2530,9 +2382,12 @@ $offset_query_part = "OFFSET $offset"; } + // proper override_order applied above if ($vfeed_query_part && get_pref($link, 'VFEED_GROUP_BY_FEED', $owner_uid)) { if (!$override_order) { $order_by = "ttrss_feeds.title, $order_by"; + } else { + $order_by = "ttrss_feeds.title, $override_order"; } } @@ -2541,7 +2396,7 @@ $feed_check_qpart = "ttrss_user_entries.feed_id = ttrss_feeds.id AND"; } else { - $from_qpart = "ttrss_entries,ttrss_user_entries$ext_tables_part + $from_qpart = "ttrss_entries$ext_tables_part,ttrss_user_entries LEFT JOIN ttrss_feeds ON (feed_id = ttrss_feeds.id)"; } @@ -2656,36 +2511,12 @@ } function sanitize($link, $str, $force_strip_tags = false, $owner = false, $site_url = false) { - global $purifier; - if (!$owner) $owner = $_SESSION["uid"]; $res = trim($str); if (!$res) return ''; - // create global Purifier object if needed - if (!$purifier) { - require_once 'lib/htmlpurifier/library/HTMLPurifier.auto.php'; - - $config = HTMLPurifier_Config::createDefault(); - - $allowed = "p,a[href],i,em,b,strong,code,pre,blockquote,br,img[src|alt|title|align|hspace],ul,ol,li,h1,h2,h3,h4,s,object[classid|type|id|name|width|height|codebase],param[name|value],table,tr,td,span[class]"; - - $config->set('HTML.SafeObject', true); - @$config->set('HTML', 'Allowed', $allowed); - $config->set('Output.FlashCompat', true); - $config->set('Attr.EnableID', true); - if (!defined('MOBILE_VERSION')) { - @$config->set('Cache', 'SerializerPath', CACHE_DIR . "/htmlpurifier"); - } else { - @$config->set('Cache', 'SerializerPath', "../" . CACHE_DIR . "/htmlpurifier"); - } - - $config->set('Filter.YouTube', true); - - $purifier = new HTMLPurifier($config); - } - - $res = $purifier->purify($res); + $config = array('safe' => 1, 'deny_attribute' => 'style, width, height, class, id', 'comment' => 1, 'cdata' => 1); + $res = htmLawed($res, $config); if (get_pref($link, "STRIP_IMAGES", $owner)) { $res = preg_replace('/]+>/is', '', $res); @@ -3281,15 +3112,17 @@ //if (!$zoom_mode) { print "
0) { if ($line["comments"]) { - $comments_url = $line["comments"]; + $comments_url = htmlspecialchars($line["comments"]); } else { - $comments_url = $line["link"]; + $comments_url = htmlspecialchars($line["link"]); } $entry_comments = "$num_comments comments"; } else { if ($line["comments"] && $line["link"] != $line["comments"]) { - $entry_comments = "comments"; + $entry_comments = "comments"; } } @@ -3357,7 +3191,7 @@ "; } - $title_escaped = db_escape_string($line['title']); + $title_escaped = htmlspecialchars($line['title']); $rv['content'] .= "
" . truncate_string(strip_tags($line['title']), 15) . "
"; @@ -3385,7 +3219,7 @@ $rv['content'] .= ""; } else { @@ -3424,15 +3258,10 @@ onclick=\"postOpenInNewTab(event, $id)\" alt='Zoom' title='".__('Open article in new tab')."'>"; - $button_plugins = explode(",", ARTICLE_BUTTON_PLUGINS); - - foreach ($button_plugins as $p) { - $pclass = trim("button_${p}"); + global $pluginhost; - if (class_exists($pclass)) { - $plugin = new $pclass($link); - $rv['content'] .= $plugin->render($id, $line); - } + foreach ($pluginhost->get_hooks($pluginhost::HOOK_ARTICLE_BUTTON) as $p) { + $rv['content'] .= $p->hook_article_button($line); } $rv['content'] .= "/", "", $text); - return $text; - } - function load_filters($link, $feed_id, $owner_uid, $action_id = false) { $filters = array(); @@ -3634,6 +3464,10 @@ $result = db_query($link, "SELECT * FROM ttrss_filters2 WHERE owner_uid = $owner_uid AND enabled = true"); + $check_cats = join(",", array_merge( + getParentCategories($link, $cat_id, $owner_uid), + array($cat_id))); + while ($line = db_fetch_assoc($result)) { $filter_id = $line["id"]; @@ -3642,7 +3476,7 @@ FROM ttrss_filters2_rules AS r, ttrss_filter_types AS t WHERE - (cat_id IS NULL OR cat_id = '$cat_id') AND + (cat_id IS NULL OR cat_id IN ($check_cats)) AND (feed_id IS NULL OR feed_id = '$feed_id') AND filter_type = t.id AND filter_id = '$filter_id'"); @@ -3722,6 +3556,12 @@ db_query($link, "SET NAMES " . MYSQL_CHARSET); } } + + global $pluginhost; + + $pluginhost = new PluginHost($link); + $pluginhost->load(PLUGINS); + return true; } else { print "Unable to connect to database:" . db_last_error(); @@ -3962,24 +3802,26 @@ } } - function get_article_labels($link, $id) { + function get_article_labels($link, $id, $owner_uid = false) { $rv = array(); + if (!$owner_uid) $owner_uid = $_SESSION["uid"]; $result = db_query($link, "SELECT label_cache FROM ttrss_user_entries WHERE ref_id = '$id' AND owner_uid = " . - $_SESSION["uid"]); - - $label_cache = db_fetch_result($result, 0, "label_cache"); + $owner_uid); - if ($label_cache) { + if (db_num_rows($result) > 0) { + $label_cache = db_fetch_result($result, 0, "label_cache"); - $label_cache = json_decode($label_cache, true); + if ($label_cache) { + $label_cache = json_decode($label_cache, true); - if ($label_cache["no-labels"] == 1) - return $rv; - else - return $label_cache; + if ($label_cache["no-labels"] == 1) + return $rv; + else + return $label_cache; + } } $result = db_query($link, @@ -3987,7 +3829,7 @@ FROM ttrss_labels2, ttrss_user_labels2 WHERE id = label_id AND article_id = '$id' - AND owner_uid = ".$_SESSION["uid"] . " + AND owner_uid = ". $owner_uid . " ORDER BY caption"); while ($line = db_fetch_assoc($result)) { @@ -3997,9 +3839,9 @@ } if (count($rv) > 0) - label_update_cache($link, $id, $rv); + label_update_cache($link, $owner_uid, $id, $rv); else - label_update_cache($link, $id, array("no-labels" => 1)); + label_update_cache($link, $owner_uid, $id, array("no-labels" => 1)); return $rv; } @@ -4017,7 +3859,19 @@ } } - function label_update_cache($link, $id, $labels = false, $force = false) { + function get_all_labels($link, $owner_uid) { + $rv = array(); + + $result = db_query($link, "SELECT fg_color, bg_color, caption FROM ttrss_labels2 WHERE owner_uid = " . $owner_uid); + + while ($line = db_fetch_assoc($result)) { + array_push($rv, $line); + } + + return $rv; + } + + function label_update_cache($link, $owner_uid, $id, $labels = false, $force = false) { if ($force) label_clear_cache($link, $id); @@ -4028,7 +3882,7 @@ $labels = db_escape_string(json_encode($labels)); db_query($link, "UPDATE ttrss_user_entries SET - label_cache = '$labels' WHERE ref_id = '$id'"); + label_cache = '$labels' WHERE ref_id = '$id' AND owner_uid = '$owner_uid'"); } @@ -4574,7 +4428,8 @@ function api_get_headlines($link, $feed_id, $limit, $offset, $filter, $is_cat, $show_excerpt, $show_content, $view_mode, $order, $include_attachments, $since_id, - $search = "", $search_mode = "", $match_on = "", $include_nested = false) { + $search = "", $search_mode = "", $match_on = "", + $include_nested = false, $sanitize_content = true) { $qfh_ret = queryFeedHeadlines($link, $feed_id, $limit, $view_mode, $is_cat, $search, $search_mode, $match_on, @@ -4618,7 +4473,17 @@ } if ($show_content) { - $headline_row["content"] = $line["content_preview"]; + + if ($line["cached_content"] != "") { + $line["content_preview"] =& $line["cached_content"]; + } + + if ($sanitize_content) { + $headline_row["content"] = sanitize($link, + $line["content_preview"], false, false, $line["site_url"]); + } else { + $headline_row["content"] = $line["content_preview"]; + } } // unify label output to ease parsing @@ -4628,6 +4493,11 @@ $headline_row["feed_title"] = $line["feed_title"]; + $headline_row["comments_count"] = (int)$line["num_comments"]; + $headline_row["comments_link"] = $line["comments"]; + + $headline_row["always_display_attachments"] = sql_bool_to_bool($line["always_display_enclosures"]); + array_push($headlines, $headline_row); } @@ -4776,7 +4646,7 @@ } function is_html($content) { - return preg_match("/ 0) { + $children = getChildCategories($link, $rule["cat_id"], $owner_uid); + array_push($children, $rule["cat_id"]); + + $children = join(",", $children); + + $cat_qpart = "cat_id IN ($children)"; + } else { + $cat_qpart = "cat_id IS NULL"; + } + + $qpart .= " AND $cat_qpart"; } array_push($query, "($qpart)"); @@ -5181,6 +5063,12 @@ if ($feeds) { if ($feeds['error']) { $status = $feeds['error']['code'] + 10; + + // access denied + if ($status == 16) { + db_query($link, "DELETE FROM ttrss_linked_feeds + WHERE instance_id = '$id'"); + } } else { $status = 1; @@ -5602,10 +5490,18 @@ } - function create_published_article($link, $title, $url, $content, $owner_uid) { - $guid = sha1($url); + function create_published_article($link, $title, $url, $content, $labels_str, + $owner_uid) { + + $guid = sha1($url . $owner_uid); // include owner_uid to prevent global GUID clash $content_hash = sha1($content); + if ($labels_str != "") { + $labels = explode(",", $labels_str); + } else { + $labels = array(); + } + $rc = false; if (!$title) $title = $url; @@ -5641,6 +5537,12 @@ ('$ref_id', '', NULL, NULL, $owner_uid, true, '', '', NOW(), '', false)"); } + if (count($labels) != 0) { + foreach ($labels as $label) { + label_add_article($link, $ref_id, trim($label), $owner_uid); + } + } + $rc = true; } else { @@ -5659,6 +5561,12 @@ VALUES ('$ref_id', '', NULL, NULL, $owner_uid, true, '', '', NOW(), '', false)"); + if (count($labels) != 0) { + foreach ($labels as $label) { + label_add_article($link, $ref_id, trim($label), $owner_uid); + } + } + $rc = true; } } @@ -5668,4 +5576,8 @@ return $rc; } + function implements_interface($class, $interface) { + return in_array($interface, class_implements($class)); + } + ?>