]> git.wh0rd.org - tt-rss.git/blobdiff - include/functions.php
Merge branch 'hookhead' of git://github.com/justauserx/Tiny-Tiny-RSS into justauserx...
[tt-rss.git] / include / functions.php
index 4272c649d8a131f4a2b15d39e41febc870f653a9..8c25d9008be8df86243d08abc09617bea668091d 100644 (file)
@@ -1,10 +1,12 @@
 <?php
        define('EXPECTED_CONFIG_VERSION', 26);
-       define('SCHEMA_VERSION', 118);
+       define('SCHEMA_VERSION', 121);
 
        define('LABEL_BASE_INDEX', -1024);
        define('PLUGIN_FEED_BASE_INDEX', -128);
 
+       define('COOKIE_LIFETIME_LONG', 86400*365);
+
        $fetch_last_error = false;
        $fetch_last_error_code = false;
        $fetch_last_content_type = false;
                        $lang = _TRANSLATION_OVERRIDE_DEFAULT;
                }
 
-               if ($_SESSION["language"] && $_SESSION["language"] != "auto") {
-                       $lang = $_SESSION["language"];
+               if ($_SESSION["uid"] && get_schema_version() >= 120) {
+                       $pref_lang = get_pref("USER_LANGUAGE", $_SESSION["uid"]);
+
+                       if ($pref_lang && $pref_lang != 'auto') {
+                               $lang = $pref_lang;
+                       }
                }
 
                if ($lang) {
                }
        }
 
-       startup_gettext();
-
        require_once 'db-prefs.php';
        require_once 'version.php';
        require_once 'ccache.php';
                        $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);
                        }
                                $_SESSION["last_login_update"] = time();
                        }
 
-                       if ($_SESSION["uid"] && $_SESSION["language"] && SESSION_COOKIE_LIFETIME > 0) {
-                               setcookie("ttrss_lang", $_SESSION["language"],
-                                       time() + SESSION_COOKIE_LIFETIME);
-                       }
-
                        if ($_SESSION["uid"]) {
+                               startup_gettext();
                                load_user_plugins($_SESSION["uid"]);
 
                                /* cleanup ccache */
 
                        $tz_offset = $user_tz->getOffset($dt);
                } else {
-                       $tz_offset = (int) $_SESSION["clientTzOffset"];
+                       $tz_offset = (int) -$_SESSION["clientTzOffset"];
                }
 
                $user_timestamp = $dt->format('U') + $tz_offset;
        }
 
        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");
                        }
 
                $data = array_merge($data, getVirtCounters());
                $data = array_merge($data, getLabelCounters());
-               $data = array_merge($data, getFeedCounters($active_feed));
+               $data = array_merge($data, getFeedCounters());
                $data = array_merge($data, getCategoryCounters());
 
                return $data;
 
                        return $unread;
                } else if ($cat == -1) {
-                       return getFeedUnread(-1) + getFeedUnread($link, -2) + getFeedUnread($link, -3) + getFeedUnread($link, 0);
+                       return getFeedUnread(-1) + getFeedUnread(-2) + getFeedUnread(-3) + getFeedUnread(0);
                } else if ($cat == -2) {
 
                        $result = db_query("
 
                        $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");
 
                $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");
 
 
                        $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);
                }
                        }
 
                        if (!$root_id) {
-                               $is_selected = ($default_id == "CAT:0") ? "selected=\"1\"" : "";
+                               $default_is_cat = ($default_id == "CAT:0");
+                               $is_selected = $default_is_cat ? "selected=\"1\"" : "";
 
                                printf("<option $is_selected value='CAT:0'>%s</option>",
                                        __("Uncategorized"));
                        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) {
                $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"];
                                $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) {
                                }
                        }
 
-                       $content_query_part = "content as content_preview, cached_content, ";
+
+                       $content_query_part = "content, content AS content_preview, cached_content, ";
+
 
                        if (is_numeric($feed)) {
 
                        if ($version_data) {
                                $version_data = json_decode($version_data, true);
                                if ($version_data && $version_data['version']) {
-
-                                       if (version_compare(VERSION, $version_data['version']) == -1) {
+                                       if (version_compare(VERSION_STATIC, $version_data['version']) == -1) {
                                                return $version_data;
                                        }
                                }
                        ttrss_tags WHERE post_int_id = (SELECT int_id FROM ttrss_user_entries WHERE
                        ref_id = '$a_id' AND owner_uid = '$owner_uid' LIMIT 1) ORDER BY tag_name";
 
-               $obj_id = md5("TAGS:$owner_uid:$id");
                $tags = array();
 
                /* check cache first */
        function format_warning($msg, $id = "") {
                global $link;
                return "<div class=\"warning\" id=\"$id\">
-                       <span><img src=\"images/sign_excl.svg\"></span><span>$msg</span></div>";
+                       <span><img src=\"images/alert.png\"></span><span>$msg</span></div>";
        }
 
        function format_notice($msg, $id = "") {
                global $link;
                return "<div class=\"notice\" id=\"$id\">
-                       <span><img src=\"images/sign_info.svg\"></span><span>$msg</span></div>";
+                       <span><img src=\"images/information.png\"></span><span>$msg</span></div>";
        }
 
        function format_error($msg, $id = "") {
                global $link;
                return "<div class=\"error\" id=\"$id\">
-                       <span><img src=\"images/sign_excl.svg\"></span><span>$msg</span></div>";
+                       <span><img src=\"images/alert.png\"></span><span>$msg</span></div>";
        }
 
        function print_notice($msg) {
                        if ($_SESSION["hasAudio"] && (strpos($ctype, "ogg") !== false ||
                                $_SESSION["hasMp3"])) {
 
-                               $entry .= "<audio controls>
+                               $entry .= "<audio preload=\"none\" controls>
                                        <source type=\"$ctype\" src=\"$url\"></source>
                                        </audio>";
 
                        $line["tags"] = get_article_tags($id, $owner_uid, $line["tag_cache"]);
                        unset($line["tag_cache"]);
 
-                       $line["content"] = sanitize($line["content"], false, $owner_uid,        $line["site_url"]);
+                       $line["content"] = sanitize($line["content"],
+                               sql_bool_to_bool($line['hide_images']),
+                               $owner_uid, $line["site_url"]);
 
                        foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_RENDER_ARTICLE) as $p) {
                                $line = $p->hook_render_article($line);
                                $rv['content'] .= "<html><head>
                                                <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>
                                                <title>Tiny Tiny RSS - ".$line["title"]."</title>
-                                               <link rel=\"stylesheet\" type=\"text/css\" href=\"tt-rss.css\">
+                                               <link rel=\"stylesheet\" type=\"text/css\" href=\"css/tt-rss.css\">
                                        </head><body id=\"ttrssZoom\">";
                        }
 
 
        function print_checkpoint($n, $s) {
                $ts = microtime(true);
-               echo sprintf("<!-- CP[$n] %.4f seconds -->", $ts - $s);
+               echo sprintf("<!-- CP[$n] %.4f seconds -->\n", $ts - $s);
                return $ts;
        }
 
        }
 
        function format_tags_string($tags, $id) {
+               if (!is_array($tags) || count($tags) == 0) {
+                       return __("no tags");
+               } else {
+                       $maxtags = min(5, count($tags));
 
-               $tags_str = "";
-               $tags_nolinks_str = "";
-
-               $num_tags = 0;
-
-               $tag_limit = 6;
-
-               $formatted_tags = array();
-
-               foreach ($tags as $tag) {
-                       $num_tags++;
-                       $tag_escaped = str_replace("'", "\\'", $tag);
-
-                       if (mb_strlen($tag) > 30) {
-                               $tag = truncate_string($tag, 30);
-                       }
-
-                       $tag_str = "<a href=\"javascript:viewfeed('$tag_escaped')\">$tag</a>";
-
-                       array_push($formatted_tags, $tag_str);
-
-                       $tmp_tags_str = implode(", ", $formatted_tags);
-
-                       if ($num_tags == $tag_limit || mb_strlen($tmp_tags_str) > 150) {
-                               break;
+                       for ($i = 0; $i < $maxtags; $i++) {
+                               $tags_str .= "<a class=\"tag\" href=\"#\" onclick=\"viewfeed('".$tags[$i]."')\">" . $tags[$i] . "</a>, ";
                        }
-               }
 
-               $tags_str = implode(", ", $formatted_tags);
+                       $tags_str = mb_substr($tags_str, 0, mb_strlen($tags_str)-2);
 
-               if ($num_tags < count($tags)) {
-                       $tags_str .= ", &hellip;";
-               }
+                       if (count($tags) > $maxtags)
+                               $tags_str .= ", &hellip;";
 
-               if ($num_tags == 0) {
-                       $tags_str = __("no tags");
+                       return $tags_str;
                }
-
-               return $tags_str;
-
        }
 
        function format_article_labels($labels, $id) {
 
-               if (is_array($labels)) return '';
+               if (!is_array($labels)) return '';
 
                $labels_str = "";
 
         * @return string Absolute URL
         */
        function rewrite_relative_url($url, $rel_url) {
-               if (strpos($rel_url, "magnet:") === 0) {
+               if (strpos($rel_url, ":") !== false) {
                        return $rel_url;
                } else if (strpos($rel_url, "://") !== false) {
                        return $rel_url;
 
                $sphinxpair = explode(":", SPHINX_SERVER, 2);
 
-               $sphinxClient->SetServer($sphinxpair[0], $sphinxpair[1]);
+               $sphinxClient->SetServer($sphinxpair[0], (int)$sphinxpair[1]);
                $sphinxClient->SetConnectTimeout(1);
 
                $sphinxClient->SetFieldWeights(array('title' => 70, 'content' => 30,
                        $reg_qpart = "REGEXP";
 
                foreach ($filter["rules"] AS $rule) {
+                       $rule['reg_exp'] = str_replace('/', '\/', $rule["reg_exp"]);
                        $regexp_valid = preg_match('/' . $rule['reg_exp'] . '/',
                                $rule['reg_exp']) !== FALSE;
 
                curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
                //curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); //CURLOPT_FOLLOWLOCATION Disabled...
                curl_setopt($curl, CURLOPT_TIMEOUT, 60);
+               curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
 
                $html = curl_exec($curl);
 
                $status = curl_getinfo($curl);
-               curl_close($curl);
 
                if($status['http_code']!=200){
                        if($status['http_code'] == 301 || $status['http_code'] == 302) {
+                               curl_close($curl);
                                list($header) = explode("\r\n\r\n", $html, 2);
                                $matches = array();
                                preg_match("/(Location:|URI:)[^(\n)]*/", $header, $matches);
                                $url = trim(str_replace($matches[1],"",$matches[0]));
                                $url_parsed = parse_url($url);
-                               return (isset($url_parsed))? geturl($url, $referer):'';
+                               return (isset($url_parsed))? geturl($url):'';
                        }
+
+                       global $fetch_last_error;
+
+                       $fetch_last_error = curl_errno($curl) . " " . curl_error($curl);
+                       curl_close($curl);
+
                        $oline='';
                        foreach($status as $key=>$eline){$oline.='['.$key.']'.$eline.' ';}
                        $line =$oline." \r\n ".$url."\r\n-----------------\r\n";
 #                      fwrite($handle, $line);
                        return FALSE;
                }
+               curl_close($curl);
                return $url;
        }
 
 
                foreach ($files as $js) {
                        if (!isset($_GET['debug'])) {
-                               $cached_file = CACHE_DIR . "/js/$js.js";
+                               $cached_file = CACHE_DIR . "/js/".basename($js).".js";
 
                                if (file_exists($cached_file) &&
                                                is_readable($cached_file) &&
        }
 
        function calculate_dep_timestamp() {
-               $files = array_merge(glob("js/*.js"), glob("*.css"));
+               $files = array_merge(glob("js/*.js"), glob("css/*.css"));
 
                $max_ts = -1;