]> git.wh0rd.org - tt-rss.git/blobdiff - functions.php
remove modalbox; use dijit.Dialog; further dojo-related updates
[tt-rss.git] / functions.php
index 126ad27c611e4a87330d6cf8333240da219adf19..67e3087ec5b2d102f6a805fe4f1501d00d938d5c 100644 (file)
        require_once 'version.php';
 
        require_once 'lib/phpmailer/class.phpmailer.php';
+       require_once 'lib/sphinxapi.php';
 
-       define('MAGPIE_USER_AGENT_EXT', ' (Tiny Tiny RSS/' . VERSION . ')');
+       //define('MAGPIE_USER_AGENT_EXT', ' (Tiny Tiny RSS/' . VERSION . ')');
        define('MAGPIE_OUTPUT_ENCODING', 'UTF-8');
        define('MAGPIE_CACHE_AGE', 60*15); // 15 minutes
 
+       define('SELF_USER_AGENT', 'Tiny Tiny RSS/' . VERSION . ' (http://tt-rss.org/)');
+       define('MAGPIE_USER_AGENT', SELF_USER_AGENT);
+
        require_once "lib/simplepie/simplepie.inc";
        require_once "lib/magpierss/rss_fetch.inc";
        require_once 'lib/magpierss/rss_utils.inc';
        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],ul,ol,li,h1,h2,h3,h4";
+
+       $config->set('HTML', 'Allowed', $allowed);
+       $purifier = new HTMLPurifier($config);
+
        /**
         * Print a timestamped debug message.
         * 
         */
        function get_favicon_url($url) {
 
+               $favicon_url = false;
+
                if ($html = @fetch_file_contents($url)) {
 
-                       if ( preg_match('/<link[^>]+rel="(?:shortcut )?icon"[^>]+?href="([^"]+?)"/si', $html, $matches)) {
-                               // Attempt to grab a favicon link from their webpage url
-                               $linkUrl = html_entity_decode($matches[1]);
+                       libxml_use_internal_errors(true);
 
-                               if (substr($linkUrl, 0, 1) == '/') {
-                                       $urlParts = parse_url($url);
-                                       $faviconURL = $urlParts['scheme'].'://'.$urlParts['host'].$linkUrl;
-                               } else if (substr($linkUrl, 0, 7) == 'http://') {
-                                       $faviconURL = $linkUrl;
-                               } else {
-                                       $pos = strrpos($url, "/");
-                                       // no "/" in url or "/" is part of "://"
-                                       if ($pos === false || $pos == (strpos($url, "://")+2)) {
-                                               $faviconURL = $url.'/'.$linkUrl;
-                                       } else {
-                                               $faviconURL = substr($url, 0, $pos+1).$linkUrl;
-                                       }
-                               }
+                       $doc = new DOMDocument();
+                       $doc->loadHTML($html);
+                       $xpath = new DOMXPath($doc);
+                       $entries = $xpath->query('/html/head/link[@rel="shortcut icon"]');
 
-                       } else {
-                               // If unsuccessful, attempt to "guess" the favicon location
-                               $urlParts = parse_url($url);
-                               $faviconURL = $urlParts['scheme'].'://'.$urlParts['host'].'/favicon.ico';
-                       }
+                       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");
+
                // Run a test to see if what we have attempted to get actually exists.
-               if(USE_CURL_FOR_ICONS || url_validate($faviconURL)) {
-                       return $faviconURL;
+               if(USE_CURL_FOR_ICONS || url_validate($favicon_url)) {
+                       return $favicon_url;
                } else {
                        return false;
                }
                                }
        
                                $rss = new SimplePie();
-                               $rss->set_useragent(SIMPLEPIE_USERAGENT . MAGPIE_USER_AGENT_EXT);
+                               $rss->set_useragent(SELF_USER_AGENT);
        #                       $rss->set_timeout(10);
                                $rss->set_feed_url($fetch_url);
                                $rss->set_output_encoding('UTF-8');
                                $icon_url = db_escape_string($rss->get_image_url());
                        }
 
+                       $icon_url = substr($icon_url, 0, 250);
+
                        if ($icon_url && $orig_icon_url != $icon_url) { 
-                               db_query($link, "UPDATE ttrss_feeds SET icon_url = '$icon_url' WHERE id = '$feed'");
+                               if (USE_CURL_FOR_ICONS || url_validate($icon_url)) {
+                                       db_query($link, "UPDATE ttrss_feeds SET icon_url = '$icon_url' WHERE id = '$feed'");
+                               }
                        }
 
                        if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
                                $entry_tags = $entry_tags[1];
 
                                $entry_tags = array_merge($entry_tags, $additional_tags);
+                               $entry_tags = array_unique($entry_tags);
+
+                               for ($i = 0; $i < count($entry_tags); $i++)
+                                       $entry_tags[$i] = mb_strtolower($entry_tags[$i], 'utf-8');
 
                                if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
                                        _debug("update_rss_feed: unfiltered tags found:");
                                        /* Collect article tags here so we could filter by them: */
 
                                        $article_filters = get_article_filters($filters, $entry_title, 
-                                                       $entry_content, $entry_link, $entry_timestamp, $entry_author, $entry_tags);
+                                               $entry_content, $entry_link, $entry_timestamp, $entry_author, 
+                                               $entry_tags);
 
                                        if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
                                                _debug("update_rss_feed: article filters: ");
                if (!$feed_title) $feed_title = getFeedTitle($link, $feed_id, false);
                if (!$unread) $unread = getFeedUnread($link, $feed_id); 
 
-               if ($unread > 0) $class .= "Unread";
+               if ($unread > 0) $class .= " Unread";
 
                if (!$icon_file) $icon_file = getFeedIcon($feed_id);
 
                        $link_title = "Updated: $last_updated";
                }
 
+               $feed_title = truncate_string($feed_title, 30);
+
                $feed = "<span class='feedlink' title=\"$link_title\" id=\"FEEDL-$feed_id\" href=\"#\"
                        onclick=\"viewfeed('$feed_id');\">$feed_title</span>";
 
                print "<span $rtl_tag id=\"FEEDN-$feed_id\">$feed</span>";
 
                if ($unread != 0) {
-                       $fctr_class = "class=\"feedCtrHasUnread\"";
+                       $fctr_class = "class=\"feedCtr Unread\"";
                } else {
-                       $fctr_class = "class=\"feedCtrNoUnread\"";
+                       $fctr_class = "class=\"feedCtr\"";
                }
 
                print " <span $rtl_tag $fctr_class id=\"FEEDCTR-$feed_id\">
 
                        $has_img = feed_has_icon($id);
 
+                       if (date('Y') - date('Y', strtotime($line['last_updated'])) > 2)
+                               $last_updated = '';
+
                        $cv = array("id" => $id,
                                "updated" => $last_updated,
                                "counter" => $count,
                                $cv["xmsg"] = getFeedArticles($link, $id)." ".__("total");
 
                        if ($active_feed && $id == $active_feed)
-                               $cv["title"] = $line["title"];
+                               $cv["title"] = truncate_string($line["title"], 30);
 
                        array_push($ret_arr, $cv);
 
                return ((!defined('TTRSS_SESSION_NAME')) ? "ttrss_sid" : TTRSS_SESSION_NAME);
        }
 
-       function make_init_param($param, $value) {
-               return array("param" => $param, "value" => $value);
-       }
-
        function make_init_params($link) {
                $params = array();
 
 
                foreach (array("ON_CATCHUP_SHOW_NEXT_FEED", "HIDE_READ_FEEDS",
                        "ENABLE_FEED_CATS", "FEEDS_SORT_BY_UNREAD", "CONFIRM_FEED_CATCHUP",
-                       "CDM_AUTO_CATCHUP", "FRESH_ARTICLE_MAX_AGE", 
-                       "HIDE_READ_SHOWS_SPECIAL", "HIDE_FEEDLIST") as $param) {
+                       "CDM_AUTO_CATCHUP", "FRESH_ARTICLE_MAX_AGE", "DEFAULT_ARTICLE_LIMIT",
+                       "HIDE_READ_SHOWS_SPECIAL", "HIDE_FEEDLIST", "COMBINED_DISPLAY_MODE") as $param) {
 
                                 $params[strtolower($param)] = (int) get_pref($link, $param);
                 }
                        if ($_SESSION["last_version_check"] + 86400 + rand(-1000, 1000) < time()) {
                                $new_version_details = @check_for_update($link);
 
-                               print "<param key=\"new_version_available\" value=\"".
-                                       sprintf("%d", $new_version_details != ""). "\"/>";
+                               $data['new_version_available'] = (int) $new_version_details != "";
 
                                $_SESSION["last_version_check"] = time();
                        }
                }
 
-//             print "<param key=\"new_version_available\" value=\"1\"/>";
-
                return $data;
        }
 
                $ext_tables_part = "";
 
                        if ($search) {
-                       
-                               $search_query_part = getSearchSql($search, $match_on);
-                               $search_query_part .= " AND ";
+
+                               if (SPHINX_ENABLED) {
+                                       $ids = join(",", @sphinx_search($search, 0, 500));
+
+                                       if ($ids) 
+                                               $search_query_part = "ref_id IN ($ids) AND ";
+                                       else
+                                               $search_query_part = "ref_id = -1 AND ";
+
+                               } else {
+                                       $search_query_part = getSearchSql($search, $match_on);
+                                       $search_query_part .= " AND ";
+                               }                               
 
                        } else {
                                $search_query_part = "";
                }
        }
 
-       function strip_tags_long($string, $allowed) {
-
-               $config = HTMLPurifier_Config::createDefault();
-
-               $config->set('HTML', 'Allowed', $allowed);
-               $purifier = new HTMLPurifier($config);
-
-               return $purifier->purify($string);              
-
-       }
-
-       // http://ru2.php.net/strip-tags
-
-/*     function strip_tags_long($textstring, $allowed){
-       while($textstring != strip_tags($textstring, $allowed))
-    {
-    while (strlen($textstring) != 0)
-         {
-         if (strlen($textstring) > 1024) {
-              $otherlen = 1024;
-         } else {
-              $otherlen = strlen($textstring);
-         }
-         $temptext = strip_tags(substr($textstring,0,$otherlen), $allowed);
-         $safetext .= $temptext;
-         $textstring = substr_replace($textstring,'',0,$otherlen);
-         }  
-    $textstring = $safetext;
-    }
-       return $textstring;
-} */
-
-
        function sanitize_rss($link, $str, $force_strip_tags = false, $owner = false, $site_url = false) {
+               global $purifier;
 
                if (!$owner) $owner = $_SESSION["uid"];
 
                $res = trim($str); if (!$res) return '';
 
                if (get_pref($link, "STRIP_UNSAFE_TAGS", $owner) || $force_strip_tags) {
-
-//                     $res = strip_tags_long($res, 
-//                             "<p><a><i><em><b><strong><code><pre><blockquote><br><img><ul><ol><li>");
-
-                       $res = strip_tags_long($res, 
-                               "p,a[href],i,em,b,strong,code,pre,blockquote,br,img[src|alt|title],ul,ol,li,h1,h2,h3,h4");
-
+                       $res = $purifier->purify($res);
                }
 
                if (get_pref($link, "STRIP_IMAGES", $owner)) {
                $xpath = new DOMXPath($doc);
        
                $entries = $xpath->query('(//a[@href]|//img[@src])');
+               $br_inserted = 0;
 
                foreach ($entries as $entry) {
 
                                                rewrite_relative_url($site_url, $entry->getAttribute('src')));
                        }
 
-                       if (get_pref($link, 'OPEN_LINKS_IN_NEW_WINDOW', $owner)) {
-                               $entry->setAttribute("target", "_blank");
+                       if (strtolower($entry->nodeName) == "a") {
+                               if (get_pref($link, 'OPEN_LINKS_IN_NEW_WINDOW', $owner)) {
+                                       $entry->setAttribute("target", "_blank");
+                               }
+                       }
+
+                       if (strtolower($entry->nodeName) == "img" && !$br_inserted) {
+                               $br = $doc->createElement("br");
+
+                               if ($entry->parentNode->nextSibling) {
+                                       $entry->parentNode->insertBefore($br, $entry->nextSibling);
+                                       $br_inserted = 1;
+                               }
+
                        }
                }
        
 
                if (DEFAULT_UPDATE_METHOD == "1") {
                        $rss = new SimplePie();
-                       $rss->set_useragent(SIMPLEPIE_USERAGENT . MAGPIE_USER_AGENT_EXT);
+                       $rss->set_useragent(SELF_USER_AGENT);
                        $rss->set_feed_url($fetch_url);
                        $rss->set_output_encoding('UTF-8');
                        $rss->init();
                        $feed_id, $is_cat, $search, $match_on,
                        $search_mode, $view_mode) {
 
-                       print "<div class=\"headlinesSubToolbar\">";
+#                      print "<div class=\"headlinesSubToolbar\">";
 
                        $page_prev_link = "javascript:viewFeedGoPage(-1)";
                        $page_next_link = "javascript:viewFeedGoPage(1)";
                        $archive_sel_link = "javascript:archiveSelection()";
                        $delete_sel_link = "javascript:deleteSelection()";
 
-                       if (!get_pref($link, 'COMBINED_DISPLAY_MODE')) {
-
-                               $sel_all_link = "javascript:selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', true, '', true)";
-                               $sel_unread_link = "javascript:selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', true, 'Unread', true)";
-                               $sel_none_link = "javascript:selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', false)";
-                               $sel_inv_link = "javascript:invertHeadlineSelection()";
-
-                               $tog_unread_link = "javascript:selectionToggleUnread()";
-                               $tog_marked_link = "javascript:selectionToggleMarked()";
-                               $tog_published_link = "javascript:selectionTogglePublished()";
-
-                       } else {
-
-                               $sel_all_link = "javascript:cdmSelectArticles('all')";
-                               $sel_unread_link = "javascript:cdmSelectArticles('unread')";
-                               $sel_none_link = "javascript:cdmSelectArticles('none')";
-
-                               $sel_inv_link = "javascript:invertHeadlineSelection()";
-
-                               $tog_unread_link = "javascript:selectionToggleUnread()";
-                               $tog_marked_link = "javascript:selectionToggleMarked()";
-                               $tog_published_link = "javascript:selectionTogglePublished()";
+                       $sel_all_link = "javascript:selectArticles('all')";
+                       $sel_unread_link = "javascript:selectArticles('unread')";
+                       $sel_none_link = "javascript:selectArticles('none')";
+                       $sel_inv_link = "javascript:selectArticles('invert')";
 
-                       }
+                       $tog_unread_link = "javascript:selectionToggleUnread()";
+                       $tog_marked_link = "javascript:selectionToggleMarked()";
+                       $tog_published_link = "javascript:selectionTogglePublished()";
 
                        print "<div id=\"subtoolbar_ftitle\">";
 
                        print "</div>";
 
                        print __('Select:')."
-                               <a href=\"$sel_all_link\">".__('All')."</a>,
-                               <a href=\"$sel_unread_link\">".__('Unread')."</a>,
-                               <a href=\"$sel_inv_link\">".__('Invert')."</a>,
-                               <a href=\"$sel_none_link\">".__('None')."</a></li>";
+                               <a href=\"#\" onclick=\"$sel_all_link\">".__('All')."</a>,
+                               <a href=\"#\" onclick=\"$sel_unread_link\">".__('Unread')."</a>,
+                               <a href=\"#\" onclick=\"$sel_inv_link\">".__('Invert')."</a>,
+                               <a href=\"#\" onclick=\"$sel_none_link\">".__('None')."</a></li>";
 
                        print "&nbsp;&nbsp;";
 
 
                        print "</ul>";
 
-                       print "</div>";
+#                      print "</div>";
                }
 
        function printCategoryHeader($link, $cat_id, $hidden = false, $can_browse = true, 
                        if ($hidden) {
                                $holder_style = "display:none;";
                                $ellipsis = "…";
+                               $collapse_pic = "cat-uncollapse.png";
                        } else {
                                $holder_style = "";
                                $ellipsis = "";
+                               $collapse_pic = "cat-collapse.png";
                        }
 
-                       $catctr_class = ($cat_unread > 0) ? "catCtrHasUnread" : "catCtrNoUnread";
+                       $catctr_class = ($cat_unread > 0) ? "catCtr Unread" : "catCtr";
 
                        if ($can_browse) {
                                $browse_cat_link = "onclick=\"javascript:viewCategory($cat_id)\"";
                        print "<li class=\"$cat_class\" id=\"FCAT-$cat_id\">
                                <img onclick=\"toggleCollapseCat($cat_id)\" class=\"catCollapse\"
                                        title=\"".__('Click to collapse category')."\"
-                                       src=\"images/cat-collapse.png\"><span class=\"$inner_title_class\" 
+                                       src=\"images/$collapse_pic?\"><span class=\"$inner_title_class\" 
                                        id=\"FCATN-$cat_id\" $browse_cat_link/>$tmp_category</span>";
 
                        print "<span id=\"FCAP-$cat_id\">";
                                }
        
                                if ($actid == $feed_id) {
-                                       $class .= "Selected";
+                                       $class .= " Selected";
                                }
        
                                $total_unread += $unread;
 
                /// STOP //////////////////////////////////////////////////////////////////////////////////
 
+               print "<toolbar><![CDATA[";
+
                if (!$offset) {
-                       print "<div id=\"headlinesContainer\" $rtl_tag>";
+//                     print "<div id=\"headlinesContainer\" $rtl_tag>";
 
                        if (!$result) {
                                print "<div align='center'>".__("Could not display feed (query failed). Please check label match syntax or local configuration.")."</div>";
                                return;
                        }
 
-                       print_headline_subtoolbar($link, $feed_site_url, $feed_title,
-                               $feed, $cat_view, $search, $match_on, $search_mode, $view_mode);
+                       if (db_num_rows($result) > 0) {
+                               print_headline_subtoolbar($link, $feed_site_url, $feed_title,
+                                       $feed, $cat_view, $search, $match_on, $search_mode, $view_mode);
+
+//                             print "<div id=\"headlinesInnerContainer\" onscroll=\"headlines_scroll_handler()\">";
 
-                       print "<div id=\"headlinesInnerContainer\" onscroll=\"headlines_scroll_handler()\">";
+                       }
                }
 
+               print "]]></toolbar><content><![CDATA[";
+
                $headlines_count = db_num_rows($result);
 
                if (db_num_rows($result) > 0) {
 
-#                      print "\{$offset}";
-
-                       if (!get_pref($link, 'COMBINED_DISPLAY_MODE') && !$offset) {
-                               print "<table class=\"headlinesList\" id=\"headlinesList\" 
-                                       cellspacing=\"0\">";
-                       }
-
                        $lnum = $limit*$offset;
 
                        $num_unread = 0;
                                }
        
                                if ($line["unread"] == "t" || $line["unread"] == "1") {
-                                       $class .= "Unread";
+                                       $class .= " Unread";
                                        ++$num_unread;
                                        $is_unread = true;
                                } else {
 
                                                        $vf_catchup_link = "(<a onclick='javascript:catchupFeedInGroup($feed_id);' href='#'>".__('mark as read')."</a>)";
 
-                                                       print "<tr class='feedTitle'><td colspan='7'>".
+                                                       print "<div class='cdmFeedTitle'>".
                                                                "<div style=\"float : right\">$feed_icon_img</div>".
-                                                               "<a href=\"javascript:viewfeed($feed_id, '', false)\">".
-                                                               $line["feed_title"]."</a> $vf_catchup_link</td></tr>";
+                                                               "<a href=\"#\" onclick=\"viewfeed($feed_id)\">".
+                                                               $line["feed_title"]."</a> $vf_catchup_link</div>";
+
                                                }
                                        }
 
                                        $mouseover_attrs = "onmouseover='postMouseIn($id)' 
                                                onmouseout='postMouseOut($id)'";
 
-                                       print "<tr class='$class' id='RROW-$id' $mouseover_attrs>";
-               
-                                       print "<td class='hlUpdPic'>$update_pic</td>";
-               
-                                       print "<td class='hlSelectRow'>
-                                               <input type=\"checkbox\" onclick=\"tSR(this)\"
-                                                       id=\"RCHK-$id\">
-                                               </td>";
+                                       print "<div class='$class' id='RROW-$id' $mouseover_attrs>";
+
+                                       print "<div class='hlUpdPic'>$update_pic</div>";
+
+                                       print "<div class='hlLeft'>";
+
+                                       print "<input type=\"checkbox\" onclick=\"tSR(this)\"
+                                                       id=\"RCHK-$id\">";
                
-                                       print "<td class='hlMarkedPic'>$marked_pic</td>";
-                                       print "<td class='hlMarkedPic'>$published_pic</td>";
+                                       print "$marked_pic";
+                                       print "$published_pic";
 
-                                       print "<td onclick='return hlClicked(event,$id)' 
-                                               title=\"".__("Click to select, ctrl-click selects multiple")."\"
-                                               class='hlContent$hlc_suffix' valign='middle' id='HLC-$id'>";
+                                       print "</div>";
 
+                                       print "<div onclick='return hlClicked(event, $id)' 
+                                               class=\"hlTitle\"><span class='hlContent$hlc_suffix'>";
                                        print "<a id=\"RTITLE-$id\" 
                                                href=\"" . htmlspecialchars($line["link"]) . "\"
-                                               onclick=\"return false\">" .
+                                               onclick=\"return false;\">" .
                                                $line["title"];
 
                                        if (get_pref($link, 'SHOW_CONTENT_PREVIEW')) {
                                                }
                                        }
 
-                                       print "</a>";
+                                       print "</a></span>";
 
                                        print $labels_str;
 
-                                       if (!get_pref($link, 'VFEED_GROUP_BY_FEED')) {
+                                       /* if (!get_pref($link, 'VFEED_GROUP_BY_FEED')) {
                                                if (@$line["feed_title"]) {                     
                                                        print "<span class=\"hlFeed\">
-                                                               (<a href=\"javascript:viewfeed($feed_id, '', false)\">".
+                                                               (<a href=\"#\" onclick=\"viewfeed($feed_id)\">".
                                                                $line["feed_title"]."</a>)
                                                        </span>";
                                                }
-                                       }
+                                       } */
 
-                                       print "</td>";
+                                       print "</div>";
 
-               
-                                       print "<td class=\"hlUpdated\" 
-                                               onclick='return hlClicked(event,$id)'><nobr>$updated_fmt&nbsp;
-                                       </nobr></td>";
+                                       print "<div class=\"hlRight\">";                                        
+                                       print "<span class=\"hlUpdated\">$updated_fmt</span>";
+                                       print $score_pic;
 
-                                       print "<td class='hlMarkedPic'>$score_pic</td>";
+                                       if ($line["feed_title"] && !get_pref($link, 'VFEED_GROUP_BY_FEED')) {
 
-                                       if (@$line["feed_title"] && !get_pref($link, 'VFEED_GROUP_BY_FEED')) {
-                                               print "<td onclick=\"viewfeed($feed_id)\" class=\"hlFeedIcon\">$feed_icon_img</td>";
+                                               print "<span onclick=\"viewfeed($feed_id)\" 
+                                                       title=\"".htmlspecialchars($line['feed_title'])."\">
+                                                       $feed_icon_img<span>";
                                        }
 
-                                       print "</tr>";
+                                       print "</div>";
+                                       print "</div>";
 
                                } else {
 
 
                                                        print "<div class='cdmFeedTitle'>".
                                                                "<div style=\"float : right\">$feed_icon_img</div>".
-                                                               "<a href=\"javascript:viewfeed($feed_id, '', false)\">".
+                                                               "<a href=\"#\" onclick=\"viewfeed($feed_id)\">".
                                                                $line["feed_title"]."</a> $vf_catchup_link</div>";
                                                }
                                        }
 
-                                       if ($is_unread) {
-                                               $add_class = "Unread";
-                                       } else {
-                                               $add_class = "";
-                                       }       
-
                                        $expand_cdm = get_pref($link, 'CDM_EXPANDED');
 
                                        $mouseover_attrs = "onmouseover='postMouseIn($id)' 
 
                                        print "<div style='float : right'>";
                                        print "<span class='updated'>$updated_fmt</span>";
-                                       print "$marked_pic";
-                                       print "$published_pic";
                                        print "$score_pic";
 
                                        if (!get_pref($link, "VFEED_GROUP_BY_FEED") && $line["feed_title"]) {
                                                        title=\"".htmlspecialchars($line["feed_title"])."\"
                                                        onclick=\"viewfeed($feed_id)\">$feed_icon_img</span>";
                                        }
+                                       print "<div class=\"updPic\">$update_pic</div>";
+
                                        print "</div>";
-       
+                               
                                        print "<input type=\"checkbox\" onclick=\"toggleSelectRowById(this, 
-                                                       'RROW-$id')\" class=\"feedCheckBox\" id=\"RCHK-$id\"/>";
+                                                       'RROW-$id')\" id=\"RCHK-$id\"/>";
+
+                                       print "$marked_pic";
+                                       print "$published_pic";
 
                                        print "<span id=\"RTITLE-$id\" 
                                                onclick=\"return cdmExpandArticle($id)\"
                                                class=\"titleWrap$hlc_suffix\">
                                                <a class=\"title\"
                                                target=\"_blank\" href=\"".$line["link"]."\">".$line["title"]."</a>
+                                               $entry_author
                                                </span>";
 
                                        print $labels_str;
                                        print "</div>";
 
                                        print "<div class=\"cdmContent\" $content_hidden
-                                               title=\"".__("Click to select, ctrl-click selects multiple")."\"
                                                onclick=\"return cdmClicked(event, $id);\"
                                                id=\"CICD-$id\">";
 
                                                }
                                        }
 
-                                       $article_content = sanitize_rss($link, $line["content_preview"], 
-                                               false, false, $feed_site_url);
+                                       if ($expand_cdm) {
+                                               $article_content = sanitize_rss($link, $line["content_preview"], 
+                                                       false, false, $feed_site_url);
 
-                                       if (!$article_content) $article_content = "&nbsp;";
+                                               if (!$article_content) $article_content = "&nbsp;";
+                                       } else {
+                                               $article_content = '';
+                                       }
 
                                        print "<div id=\"POSTNOTE-$id\">";
                                        if ($line['note']) {
                                        }
                                        print "</div>";
 
-                                       print $article_content;
+                                       print "<span id=\"CWRAP-$id\">$article_content</span>";
 
                                        $tmp_result = db_query($link, "SELECT always_display_enclosures FROM
                                                ttrss_feeds WHERE id = ".
                                                        'images/tag.png')."' alt='Tags' title='Tags'>
                                                <span id=\"ATSTR-$id\">$tags_str</span>
                                                <a title=\"".__('Edit tags for this article')."\" 
-                                               href=\"javascript:editArticleTags($id, $feed_id, true)\">(+)</a>";
+                                               href=\"#\" onclick=\"editArticleTags($id, $feed_id, true)\">(+)</a>";
 
                                        print "<div style=\"float : right\">";
 
                                ++$lnum;
                        } 
 
-                       if (!get_pref($link, 'COMBINED_DISPLAY_MODE') && !$offset) {                    
-                               print "</table>";
-                       }
-
                } else {
                        $message = "";
 
                                        }
                        }
 
-                       if (!$offset) print "<div class='whiteBox'>$message</div>";
-               }
+                       if (!$offset && $message) {
+                               print "<div class='whiteBox'>$message";
 
-               if (!$offset) {
-                       print "</div>";
-                       print "</div>";
+                               print "<p class=\"small\"><span class=\"insensitive\">";
+
+                               $result = db_query($link, "SELECT ".SUBSTRING_FOR_DATE."(MAX(last_updated), 1, 19) AS last_updated FROM ttrss_feeds
+                                       WHERE owner_uid = " . $_SESSION['uid']);
+               
+                               $last_updated = db_fetch_result($result, 0, "last_updated");
+                               $last_updated = make_local_datetime($link, $last_updated, false);
+               
+                               printf(__("Feeds last updated at %s"), $last_updated);
+               
+                               $result = db_query($link, "SELECT COUNT(id) AS num_errors
+                                       FROM ttrss_feeds WHERE last_error != '' AND owner_uid = ".$_SESSION["uid"]);
+               
+                               $num_errors = db_fetch_result($result, 0, "num_errors");
+               
+                               if ($num_errors > 0) {
+                                       print "<br/>";
+                                       print "<a class=\"insensitive\" href=\"#\" onclick=\"showFeedsWithErrors()\">".
+                                               __('Some feeds have update errors (click for details)')."</a>";
+                               }
+                               print "</span></p></div>";
+                       }
                }
 
+#              if (!$offset) {
+#                      if ($headlines_count > 0) print "</div>";
+#                      print "</div>";
+#              }
+
+               print "]]></content>";
+
                return array($topmost_article_ids, $headlines_count, $feed, $disable_cache, $vgroup_last_feed);
        }
 
                // Send feed digests by email if needed.
                if (DAEMON_SENDS_DIGESTS) send_headlines_digests($link);
 
-               purge_orphans($link);
-
        } // function update_daemon_common
 
        function sanitize_article_content($text) {
                }
        }
 
+       function sphinx_search($query, $offset = 0, $limit = 30) {
+               $sphinxClient = new SphinxClient();
+
+               $sphinxClient->SetServer('localhost', 9312);
+               $sphinxClient->SetConnectTimeout(1);
+
+               $sphinxClient->SetFieldWeights(array('title' => 70, 'content' => 30, 
+                       'feed_title' => 20));
+
+               $sphinxClient->SetMatchMode(SPH_MATCH_EXTENDED2);
+               $sphinxClient->SetRankingMode(SPH_RANK_PROXIMITY_BM25);
+               $sphinxClient->SetLimits($offset, $limit, 1000);
+               $sphinxClient->SetArrayResult(false);
+               $sphinxClient->SetFilter('owner_uid', array($_SESSION['uid']));
+               
+               $result = $sphinxClient->Query($query, SPHINX_INDEX);
+
+               $ids = array();
+
+               if (is_array($result['matches'])) {
+                       foreach (array_keys($result['matches']) as $int_id) {
+                               $ref_id = $result['matches'][$int_id]['attrs']['ref_id'];
+                               array_push($ids, $ref_id);
+                       }
+               }
+
+               return $ids;
+       }
+
+       function cleanup_tags($link, $days = 14, $limit = 1000) {
+
+               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;
+
+               while ($limit > 0) {
+                       $limit_part = 500;
+
+                       $query = "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 $limit_part";
+       
+                       $result = db_query($link, $query);
+
+                       $ids = array();
+
+                       while ($line = db_fetch_assoc($result)) {
+                               array_push($ids, $line['id']);
+                       }
+
+                       if (count($ids) > 0) {
+                               $ids = join(",", $ids);
+                               print ".";
+
+                               $tmp_result = db_query($link, "DELETE FROM ttrss_tags WHERE id IN ($ids)");
+                               $tags_deleted += db_affected_rows($link, $tmp_result);
+                       } else {
+                               break;
+                       }
+
+                       $limit -= $limit_part;
+               }
+
+               print "\n";
+
+               return $tags_deleted;
+       }
+
 ?>