2013-02-21 15:58:06 +01:00
< ? php
require_once " colors.php " ;
class Feeds extends Handler_Protected {
2015-06-07 17:41:18 +02:00
private $params ;
function csrf_ignore ( $method ) {
2013-04-01 09:14:27 +02:00
$csrf_ignored = array ( " index " , " feedbrowser " , " quickaddfeed " , " search " );
2013-02-21 15:58:06 +01:00
return array_search ( $method , $csrf_ignored ) !== false ;
}
private function format_headline_subtoolbar ( $feed_site_url , $feed_title ,
2013-03-21 00:36:30 +01:00
$feed_id , $is_cat , $search ,
2015-07-07 14:59:32 +02:00
$view_mode , $error , $feed_last_updated ) {
2013-02-21 15:58:06 +01:00
$catchup_sel_link = " catchupSelection() " ;
$archive_sel_link = " archiveSelection() " ;
$delete_sel_link = " deleteSelection() " ;
$sel_all_link = " selectArticles('all') " ;
$sel_unread_link = " selectArticles('unread') " ;
$sel_none_link = " selectArticles('none') " ;
$sel_inv_link = " selectArticles('invert') " ;
$tog_unread_link = " selectionToggleUnread() " ;
$tog_marked_link = " selectionToggleMarked() " ;
$tog_published_link = " selectionTogglePublished() " ;
$set_score_link = " setSelectionScore() " ;
if ( $is_cat ) $cat_q = " &is_cat= $is_cat " ;
if ( $search ) {
2015-07-07 14:59:32 +02:00
$search_q = " &q= $search " ;
2013-02-21 15:58:06 +01:00
} else {
$search_q = " " ;
}
2014-01-27 19:03:42 +01:00
$reply .= " <span class= \" holder \" > " ;
2013-02-21 15:58:06 +01:00
$rss_link = htmlspecialchars ( get_self_url_prefix () .
" /public.php?op=rss&id= $feed_id $cat_q $search_q " );
// right part
2013-07-12 10:38:50 +02:00
$error_class = $error ? " error " : " " ;
2014-01-27 19:03:42 +01:00
$reply .= " <span class='r'>
< a href = \ " # \"
title = \ " " . __ ( " View as RSS feed " ) . " \"
onclick = \ " displayDlg(' " . __ ( " View as RSS " ) . " ','generatedFeed', ' $feed_id : $is_cat : $rss_link ') \" >
< img class = \ " noborder \" src= \" images/pub_set.png \" ></a> " ;
# $reply .= "<span>";
2013-07-12 10:38:50 +02:00
$reply .= " <span id='feed_title' class=' $error_class '> " ;
2013-02-21 15:58:06 +01:00
if ( $feed_site_url ) {
2013-04-25 14:27:33 +02:00
$last_updated = T_sprintf ( " Last updated: %s " ,
$feed_last_updated );
2013-02-21 15:58:06 +01:00
$target = " target= \" _blank \" " ;
2013-04-25 14:27:33 +02:00
$reply .= " <a title= \" $last_updated\ " $target href = \ " $feed_site_url\ " > " .
2014-02-02 20:17:13 +01:00
truncate_string ( $feed_title , 30 ) . " </a> " ;
2013-02-21 15:58:06 +01:00
if ( $error ) {
2013-07-13 20:14:18 +02:00
$error = htmlspecialchars ( $error );
2014-03-26 11:30:54 +01:00
$reply .= " <img title= \" $error\ " src = 'images/error.png' alt = 'error' class = \ " noborder \" > " ;
2013-02-21 15:58:06 +01:00
}
} else {
$reply .= $feed_title ;
}
$reply .= " </span> " ;
2014-02-02 16:56:51 +01:00
$reply .= " </span> " ;
2014-01-27 19:03:42 +01:00
# $reply .= "</span>";
2013-02-21 15:58:06 +01:00
// left part
2014-01-27 19:03:42 +01:00
$reply .= " <span class= \" main \" > " ;
2014-01-27 19:27:31 +01:00
$reply .= " <span id='selected_prompt'></span> " ;
2014-01-27 19:03:42 +01:00
2017-01-07 15:03:58 +01:00
/* $reply .= " <span class= \" sel_links \" >
2013-02-21 15:58:06 +01:00
< 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 > " ;
2017-01-07 15:03:58 +01:00
$reply .= " </span> " ; */
2013-02-21 15:58:06 +01:00
$reply .= " <select dojoType= \" dijit.form.Select \"
onchange = \ " headlineActionsChange(this) \" > " ;
2017-01-07 15:03:58 +01:00
$reply .= " <option value= \" 0 \" disabled='1'> " . __ ( 'Select...' ) . " </option> " ;
$reply .= " <option value= \" $sel_all_link\ " > " .__('All'). " </ option > " ;
$reply .= " <option value= \" $sel_unread_link\ " > " .__('Unread'). " </ option > " ;
$reply .= " <option value= \" $sel_inv_link\ " > " .__('Invert'). " </ option > " ;
$reply .= " <option value= \" $sel_none_link\ " > " .__('None'). " </ option > " ;
2013-02-21 15:58:06 +01:00
$reply .= " <option value= \" 0 \" disabled= \" 1 \" > " . __ ( 'Selection toggle:' ) . " </option> " ;
$reply .= " <option value= \" $tog_unread_link\ " > " .__('Unread'). " </ option >
< option value = \ " $tog_marked_link\ " > " .__('Starred'). " </ option >
< option value = \ " $tog_published_link\ " > " .__('Published'). " </ option > " ;
$reply .= " <option value= \" 0 \" disabled= \" 1 \" > " . __ ( 'Selection:' ) . " </option> " ;
$reply .= " <option value= \" $catchup_sel_link\ " > " .__('Mark as read'). " </ option > " ;
$reply .= " <option value= \" $set_score_link\ " > " .__('Set score'). " </ option > " ;
if ( $feed_id != " 0 " ) {
$reply .= " <option value= \" $archive_sel_link\ " > " .__('Archive'). " </ option > " ;
} else {
$reply .= " <option value= \" $archive_sel_link\ " > " .__('Move back'). " </ option > " ;
$reply .= " <option value= \" $delete_sel_link\ " > " .__('Delete'). " </ option > " ;
}
2013-04-18 10:27:34 +02:00
if ( PluginHost :: getInstance () -> get_plugin ( " mail " )) {
2013-02-21 15:58:06 +01:00
$reply .= " <option value= \" emailArticle(false) \" > " . __ ( 'Forward by email' ) .
" </option> " ;
}
2013-04-18 10:27:34 +02:00
if ( PluginHost :: getInstance () -> get_plugin ( " mailto " )) {
2013-03-19 15:32:49 +01:00
$reply .= " <option value= \" mailtoArticle(false) \" > " . __ ( 'Forward by email' ) .
" </option> " ;
}
2013-02-21 15:58:06 +01:00
$reply .= " <option value= \" 0 \" disabled= \" 1 \" > " . __ ( 'Feed:' ) . " </option> " ;
2013-03-31 13:39:10 +02:00
//$reply .= "<option value=\"catchupPage()\">".__('Mark as read')."</option>";
2013-02-21 15:58:06 +01:00
2013-04-01 08:47:41 +02:00
$reply .= " <option value= \" displayDlg(' " . __ ( " View as RSS " ) . " ','generatedFeed', ' $feed_id : $is_cat : $rss_link ') \" > " . __ ( 'View as RSS' ) . " </option> " ;
2013-02-21 15:58:06 +01:00
$reply .= " </select> " ;
//$reply .= "</h2";
2013-04-18 10:27:34 +02:00
foreach ( PluginHost :: getInstance () -> get_hooks ( PluginHost :: HOOK_HEADLINE_TOOLBAR_BUTTON ) as $p ) {
2014-08-18 13:22:02 +02:00
$reply .= $p -> hook_headline_toolbar_button ( $feed_id , $is_cat );
2013-04-01 16:06:09 +02:00
}
2014-01-27 19:03:42 +01:00
$reply .= " </span></span> " ;
2013-02-21 15:58:06 +01:00
return $reply ;
}
private function format_headlines_list ( $feed , $method , $view_mode , $limit , $cat_view ,
$next_unread_feed , $offset , $vgr_last_feed = false ,
2015-11-21 20:20:00 +01:00
$override_order = false , $include_children = false , $check_first_id = false ,
$skip_first_id_check = false ) {
2013-02-21 15:58:06 +01:00
$disable_cache = false ;
$reply = array ();
2013-04-15 13:27:35 +02:00
$rgba_cache = array ();
2013-02-27 19:16:58 +01:00
$timing_info = microtime ( true );
2013-02-21 15:58:06 +01:00
$topmost_article_ids = array ();
if ( ! $offset ) $offset = 0 ;
if ( $method == " undefined " ) $method = " " ;
$method_split = explode ( " : " , $method );
2016-01-26 09:45:47 +01:00
if ( $method == " ForceUpdate " && $feed > 0 && is_numeric ( $feed )) {
2013-02-21 15:58:06 +01:00
// Update the feed if required with some basic flood control
2016-01-26 09:45:47 +01:00
$any_needs_curl = false ;
if ( ini_get ( " open_basedir " )) {
$pluginhost = PluginHost :: getInstance ();
foreach ( $pluginhost -> get_plugins () as $plugin ) {
$flags = $plugin -> flags ();
if ( isset ( $flags [ " needs_curl " ]) && $flags [ " needs_curl " ]) {
$any_needs_curl = true ;
break ;
}
}
}
//if ($_REQUEST["debug"]) print "<!-- any_needs_curl: $any_needs_curl -->";
if ( ! $any_needs_curl ) {
$result = $this -> dbh -> query (
" SELECT cache_images, " . SUBSTRING_FOR_DATE . " (last_updated,1,19) AS last_updated
FROM ttrss_feeds WHERE id = '$feed' " );
2013-02-21 15:58:06 +01:00
2013-04-17 18:12:14 +02:00
if ( $this -> dbh -> num_rows ( $result ) != 0 ) {
$last_updated = strtotime ( $this -> dbh -> fetch_result ( $result , 0 , " last_updated " ));
$cache_images = sql_bool_to_bool ( $this -> dbh -> fetch_result ( $result , 0 , " cache_images " ));
2013-02-21 15:58:06 +01:00
2015-06-12 12:06:36 +02:00
if ( ! $cache_images && time () - $last_updated > 120 ) {
2013-02-21 15:58:06 +01:00
include " rssfuncs.php " ;
2013-04-17 16:34:18 +02:00
update_rss_feed ( $feed , true , true );
2013-02-21 15:58:06 +01:00
} else {
2013-04-17 18:12:14 +02:00
$this -> dbh -> query ( " UPDATE ttrss_feeds SET last_updated = '1970-01-01', last_update_started = '1970-01-01'
2016-01-26 09:45:47 +01:00
WHERE id = '$feed' " );
2013-02-21 15:58:06 +01:00
}
}
2016-01-30 11:40:56 +01:00
} else {
$this -> dbh -> query ( " UPDATE ttrss_feeds SET last_updated = '1970-01-01', last_update_started = '1970-01-01'
WHERE id = '$feed' " );
2016-01-26 09:45:47 +01:00
}
2013-02-21 15:58:06 +01:00
}
if ( $method_split [ 0 ] == " MarkAllReadGR " ) {
2013-04-17 16:34:18 +02:00
catchup_feed ( $method_split [ 1 ], false );
2013-02-21 15:58:06 +01:00
}
// FIXME: might break tag display?
if ( is_numeric ( $feed ) && $feed > 0 && ! $cat_view ) {
2013-04-17 18:12:14 +02:00
$result = $this -> dbh -> query (
2013-02-21 15:58:06 +01:00
" SELECT id FROM ttrss_feeds WHERE id = ' $feed ' LIMIT 1 " );
2013-04-17 18:12:14 +02:00
if ( $this -> dbh -> num_rows ( $result ) == 0 ) {
2013-02-21 15:58:06 +01:00
$reply [ 'content' ] = " <div align='center'> " . __ ( 'Feed not found.' ) . " </div> " ;
}
}
2013-04-17 18:12:14 +02:00
@ $search = $this -> dbh -> escape_string ( $_REQUEST [ " query " ]);
2015-08-04 12:53:48 +02:00
@ $search_language = $this -> dbh -> escape_string ( $_REQUEST [ " search_language " ]); // PGSQL only
2013-02-21 15:58:06 +01:00
if ( $search ) {
$disable_cache = true ;
}
if ( $_REQUEST [ " debug " ]) $timing_info = print_checkpoint ( " H0 " , $timing_info );
2013-03-27 13:14:27 +01:00
2013-03-28 20:34:35 +01:00
if ( ! $cat_view && is_numeric ( $feed ) && $feed < PLUGIN_FEED_BASE_INDEX && $feed > LABEL_BASE_INDEX ) {
2013-04-18 10:27:34 +02:00
$handler = PluginHost :: getInstance () -> get_feed_handler (
2013-03-27 13:14:27 +01:00
PluginHost :: feed_to_pfeed_id ( $feed ));
if ( $handler ) {
$options = array (
" limit " => $limit ,
" view_mode " => $view_mode ,
" cat_view " => $cat_view ,
" search " => $search ,
" override_order " => $override_order ,
" offset " => $offset ,
" owner_uid " => $_SESSION [ " uid " ],
" filter " => false ,
" since_id " => 0 ,
" include_children " => $include_children );
$qfh_ret = $handler -> get_headlines ( PluginHost :: feed_to_pfeed_id ( $feed ),
$options );
}
} else {
2015-07-12 00:29:36 +02:00
/* $qfh_ret = queryFeedHeadlines ( $feed , $limit , $view_mode , $cat_view ,
2015-07-07 14:59:32 +02:00
$search , false , $override_order , $offset , 0 ,
2015-07-12 00:29:36 +02:00
false , 0 , $include_children , $topid ); */
//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, $start_ts = false, $check_top_id = false) {
$params = array (
" feed " => $feed ,
" limit " => $limit ,
" view_mode " => $view_mode ,
" cat_view " => $cat_view ,
" search " => $search ,
2015-08-04 12:53:48 +02:00
" search_language " => $search_language ,
2015-07-12 00:29:36 +02:00
" override_order " => $override_order ,
" offset " => $offset ,
" include_children " => $include_children ,
2015-11-21 20:20:00 +01:00
" check_first_id " => $check_first_id ,
" skip_first_id_check " => $skip_first_id_check
2015-07-12 00:29:36 +02:00
);
$qfh_ret = queryFeedHeadlines ( $params );
2013-03-27 13:14:27 +01:00
}
2013-02-21 15:58:06 +01:00
2014-03-12 22:07:52 +01:00
$vfeed_group_enabled = get_pref ( " VFEED_GROUP_BY_FEED " ) && $feed != - 6 ;
2013-02-21 15:58:06 +01:00
if ( $_REQUEST [ " debug " ]) $timing_info = print_checkpoint ( " H1 " , $timing_info );
$result = $qfh_ret [ 0 ];
$feed_title = $qfh_ret [ 1 ];
$feed_site_url = $qfh_ret [ 2 ];
$last_error = $qfh_ret [ 3 ];
2013-04-25 16:42:48 +02:00
$last_updated = strpos ( $qfh_ret [ 4 ], '1970-' ) === FALSE ?
make_local_datetime ( $qfh_ret [ 4 ], false ) : __ ( " Never " );
2013-07-31 12:53:34 +02:00
$highlight_words = $qfh_ret [ 5 ];
2015-07-12 16:55:35 +02:00
$reply [ 'first_id' ] = $qfh_ret [ 6 ];
2013-02-21 15:58:06 +01:00
$vgroup_last_feed = $vgr_last_feed ;
$reply [ 'toolbar' ] = $this -> format_headline_subtoolbar ( $feed_site_url ,
$feed_title ,
2015-07-07 14:59:32 +02:00
$feed , $cat_view , $search , $view_mode ,
2013-04-25 14:27:33 +02:00
$last_error , $last_updated );
2013-02-21 15:58:06 +01:00
2015-12-05 02:04:44 +01:00
$headlines_count = is_numeric ( $result ) ? 0 : $this -> dbh -> num_rows ( $result );
2013-02-21 15:58:06 +01:00
2014-08-19 12:24:34 +02:00
if ( $offset == 0 ) {
foreach ( PluginHost :: getInstance () -> get_hooks ( PluginHost :: HOOK_HEADLINES_BEFORE ) as $p ) {
$reply [ 'content' ] .= $p -> hook_headlines_before ( $feed , $cat_view , $qfh_ret );
}
}
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] = '' ;
2015-07-13 12:29:13 +02:00
2015-12-05 02:04:44 +01:00
if ( $headlines_count > 0 ) {
2013-02-21 15:58:06 +01:00
$lnum = $offset ;
$num_unread = 0 ;
$cur_feed_title = '' ;
if ( $_REQUEST [ " debug " ]) $timing_info = print_checkpoint ( " PS " , $timing_info );
2013-04-17 16:34:18 +02:00
$expand_cdm = get_pref ( 'CDM_EXPANDED' );
2013-07-10 14:52:03 +02:00
2013-04-17 18:12:14 +02:00
while ( $line = $this -> dbh -> fetch_assoc ( $result )) {
2015-07-13 00:19:52 +02:00
2013-11-29 10:54:30 +01:00
$line [ " content_preview " ] = " — " . truncate_string ( strip_tags ( $line [ " content " ]), 250 );
2013-07-10 14:52:03 +02:00
2013-06-27 17:18:23 +02:00
foreach ( PluginHost :: getInstance () -> get_hooks ( PluginHost :: HOOK_QUERY_HEADLINES ) as $p ) {
2013-07-10 10:24:29 +02:00
$line = $p -> hook_query_headlines ( $line , 250 , false );
2013-06-27 17:18:23 +02:00
}
2013-07-10 14:52:03 +02:00
if ( get_pref ( 'SHOW_CONTENT_PREVIEW' )) {
$content_preview = $line [ " content_preview " ];
}
2013-02-21 15:58:06 +01:00
$id = $line [ " id " ];
$feed_id = $line [ " feed_id " ];
$label_cache = $line [ " label_cache " ];
$labels = false ;
if ( $label_cache ) {
$label_cache = json_decode ( $label_cache , true );
if ( $label_cache ) {
if ( $label_cache [ " no-labels " ] == 1 )
$labels = array ();
else
$labels = $label_cache ;
}
}
2013-04-17 16:34:18 +02:00
if ( ! is_array ( $labels )) $labels = get_article_labels ( $id );
2013-02-21 15:58:06 +01:00
2013-07-11 14:49:25 +02:00
$labels_str = " <span class= \" HLLCTR- $id\ " > " ;
2013-02-21 15:58:06 +01:00
$labels_str .= format_article_labels ( $labels , $id );
$labels_str .= " </span> " ;
if ( count ( $topmost_article_ids ) < 3 ) {
array_push ( $topmost_article_ids , $id );
}
2013-05-04 10:01:53 +02:00
$class = " " ;
2013-04-09 14:13:32 +02:00
if ( sql_bool_to_bool ( $line [ " unread " ])) {
2013-02-21 15:58:06 +01:00
$class .= " Unread " ;
++ $num_unread ;
}
2013-04-09 14:13:32 +02:00
if ( sql_bool_to_bool ( $line [ " marked " ])) {
$marked_pic = " <img
2013-07-10 11:09:12 +02:00
src = \ " images/mark_set.png \"
2013-02-21 15:58:06 +01:00
class = \ " markedPic \" alt= \" Unstar article \"
2013-04-09 14:13:32 +02:00
onclick = 'toggleMark($id)' > " ;
$class .= " marked " ;
2013-02-21 15:58:06 +01:00
} else {
2013-04-09 14:13:32 +02:00
$marked_pic = " <img
2013-07-10 11:09:12 +02:00
src = \ " images/mark_unset.png \"
2013-02-21 15:58:06 +01:00
class = \ " markedPic \" alt= \" Star article \"
2013-04-09 14:13:32 +02:00
onclick = 'toggleMark($id)' > " ;
2013-02-21 15:58:06 +01:00
}
2013-04-09 14:13:32 +02:00
if ( sql_bool_to_bool ( $line [ " published " ])) {
2013-07-10 11:09:12 +02:00
$published_pic = " <img src= \" images/pub_set.png \"
2013-04-09 14:13:32 +02:00
class = \ " pubPic \"
alt = \ " Unpublish article \" onclick='togglePub( $id )'> " ;
$class .= " published " ;
2013-02-21 15:58:06 +01:00
} else {
2013-07-10 11:09:12 +02:00
$published_pic = " <img src= \" images/pub_unset.png \"
2013-04-09 14:13:32 +02:00
class = \ " pubPic \"
alt = \ " Publish article \" onclick='togglePub( $id )'> " ;
2013-02-21 15:58:06 +01:00
}
# $content_link = "<a target=\"_blank\" href=\"".$line["link"]."\">" .
# $line["title"] . "</a>";
# $content_link = "<a
# href=\"" . htmlspecialchars($line["link"]) . "\"
# onclick=\"view($id,$feed_id);\">" .
# $line["title"] . "</a>";
# $content_link = "<a href=\"javascript:viewContentUrl('".$line["link"]."');\">" .
# $line["title"] . "</a>";
2015-07-03 22:36:47 +02:00
$updated_fmt = make_local_datetime ( $line [ " updated " ], false , false , false , true );
2013-03-27 10:34:04 +01:00
$date_entered_fmt = T_sprintf ( " Imported at %s " ,
2013-04-17 16:34:18 +02:00
make_local_datetime ( $line [ " date_entered " ], false ));
2013-02-21 15:58:06 +01:00
$score = $line [ " score " ];
2013-03-20 22:59:08 +01:00
$score_pic = " images/ " . get_score_pic ( $score );
2013-02-21 15:58:06 +01:00
/* $score_title = __ ( " (Click to change) " );
$score_pic = " <img class='hlScorePic' src= \" images/ $score_pic\ "
onclick = \ " adjustArticleScore( $id , $score ) \" title= \" $score $score_title\ " > " ; */
$score_pic = " <img class='hlScorePic' score=' $score ' onclick='changeScore( $id , this)' src= \" $score_pic\ "
title = \ " $score\ " > " ;
if ( $score > 500 ) {
2013-07-06 10:34:58 +02:00
$hlc_suffix = " high " ;
2013-02-21 15:58:06 +01:00
} else if ( $score < - 100 ) {
2013-07-06 10:34:58 +02:00
$hlc_suffix = " low " ;
2013-02-21 15:58:06 +01:00
} else {
$hlc_suffix = " " ;
}
$entry_author = $line [ " author " ];
if ( $entry_author ) {
2013-04-15 10:57:52 +02:00
$entry_author = " — $entry_author " ;
2013-02-21 15:58:06 +01:00
}
$has_feed_icon = feed_has_icon ( $feed_id );
if ( $has_feed_icon ) {
$feed_icon_img = " <img class= \" tinyFeedIcon \" src= \" " . ICONS_URL . " / $feed_id .ico \" alt= \" \" > " ;
} else {
2013-07-10 11:09:12 +02:00
$feed_icon_img = " <img class= \" tinyFeedIcon \" src= \" images/pub_set.png \" alt= \" \" > " ;
2013-02-21 15:58:06 +01:00
}
2013-03-18 12:42:28 +01:00
$entry_site_url = $line [ " site_url " ];
2013-04-15 13:38:05 +02:00
//setting feed headline background color, needs to change text color based on dark/light
$fav_color = $line [ 'favicon_avg_color' ];
require_once " colors.php " ;
2013-04-24 13:08:37 +02:00
if ( $fav_color && $fav_color != 'fail' ) {
2013-04-15 13:56:08 +02:00
if ( ! isset ( $rgba_cache [ $feed_id ])) {
2013-04-15 15:07:06 +02:00
$rgba_cache [ $feed_id ] = join ( " , " , _color_unpack ( $fav_color ));
2013-04-15 13:56:08 +02:00
}
2013-04-15 13:38:05 +02:00
}
2013-04-17 16:34:18 +02:00
if ( ! get_pref ( 'COMBINED_DISPLAY_MODE' )) {
2013-02-21 15:58:06 +01:00
2014-03-12 22:07:52 +01:00
if ( $vfeed_group_enabled ) {
2013-02-21 15:58:06 +01:00
if ( $feed_id != $vgroup_last_feed && $line [ " feed_title " ]) {
$cur_feed_title = $line [ " feed_title " ];
$vgroup_last_feed = $feed_id ;
$cur_feed_title = htmlspecialchars ( $cur_feed_title );
2013-10-17 11:38:48 +02:00
$vf_catchup_link = " <a class='catchup' onclick='catchupFeedInGroup( $feed_id );' href='#'> " . __ ( 'mark feed as read' ) . " </a> " ;
2013-02-21 15:58:06 +01:00
2016-03-22 21:22:28 +01:00
$reply [ 'content' ] .= " <div data-feed-id=' $feed_id ' id='FTITLE- $feed_id ' class='cdmFeedTitle'> " .
2013-10-17 11:38:48 +02:00
" <div style='float : right'> $feed_icon_img </div> " .
2015-08-13 08:51:39 +02:00
" <a class='title' href= \" # \" onclick= \" viewfeed( { feed: $feed_id }) \" > " .
2015-07-13 00:19:52 +02:00
$line [ " feed_title " ] . " </a>
2013-10-17 11:38:48 +02:00
$vf_catchup_link </ div > " ;
2013-02-21 15:58:06 +01:00
2015-07-13 00:19:52 +02:00
2013-02-21 15:58:06 +01:00
}
}
2013-03-25 13:08:20 +01:00
$mouseover_attrs = " onmouseover='postMouseIn(event, $id )'
2013-02-21 15:58:06 +01:00
onmouseout = 'postMouseOut($id)' " ;
2016-03-22 21:43:32 +01:00
$reply [ 'content' ] .= " <div class='hl $class ' data-orig-feed-id=' $feed_id ' data-article-id=' $id ' id='RROW- $id ' $mouseover_attrs > " ;
2013-02-21 15:58:06 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " <div class='hlLeft'> " ;
2013-02-21 15:58:06 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " <input dojoType= \" dijit.form.CheckBox \"
2013-02-28 12:48:09 +01:00
type = \ " checkbox \" onclick= \" toggleSelectRow2(this) \"
2013-04-06 22:52:39 +02:00
class = 'rchk' > " ;
2013-02-21 15:58:06 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " $marked_pic " ;
$reply [ 'content' ] .= " $published_pic " ;
2013-02-21 15:58:06 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " </div> " ;
2013-02-21 15:58:06 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " <div onclick='return hlClicked(event, $id )'
2013-07-06 10:34:58 +02:00
class = \ " hlTitle \" ><span class='hlContent $hlc_suffix '> " ;
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " <a id= \" RTITLE- $id\ " class = \ " title $hlc_suffix\ "
2013-03-23 07:49:50 +01:00
href = \ " " . htmlspecialchars ( $line [ " link " ]) . " \"
2013-02-21 15:58:06 +01:00
onclick = \ " \" > " .
truncate_string ( $line [ " title " ], 200 );
2013-04-17 16:34:18 +02:00
if ( get_pref ( 'SHOW_CONTENT_PREVIEW' )) {
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " <span class= \" contentPreview \" > " . $line [ " content_preview " ] . " </span> " ;
2013-02-21 15:58:06 +01:00
}
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " </a></span> " ;
2013-02-21 15:58:06 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= $labels_str ;
2013-02-21 15:58:06 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " </div> " ;
2013-03-16 14:17:55 +01:00
2014-03-12 22:07:52 +01:00
if ( ! $vfeed_group_enabled ) {
2013-03-21 20:22:04 +01:00
if ( @ $line [ " feed_title " ]) {
2013-05-07 17:39:04 +02:00
$rgba = @ $rgba_cache [ $feed_id ];
2015-08-13 08:51:39 +02:00
$reply [ 'content' ] .= " <span class= \" hlFeed \" ><a style= \" background : rgba( $rgba , 0.3) \" href= \" # \" onclick= \" viewfeed( { feed: $feed_id }) \" > " .
2014-01-28 21:21:57 +01:00
truncate_string ( $line [ " feed_title " ], 30 ) . " </a></span> " ;
2013-02-21 15:58:06 +01:00
}
2013-03-21 20:22:04 +01:00
}
2013-02-21 15:58:06 +01:00
2014-01-28 21:21:57 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " <span class= \" hlUpdated \" > " ;
2014-01-28 21:21:57 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " <div title=' $date_entered_fmt '> $updated_fmt </div>
2013-03-27 10:34:04 +01:00
</ span > " ;
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " <div class= \" hlRight \" > " ;
2013-02-21 15:58:06 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= $score_pic ;
2013-02-21 15:58:06 +01:00
2014-03-12 22:07:52 +01:00
if ( $line [ " feed_title " ] && ! $vfeed_group_enabled ) {
2013-02-21 15:58:06 +01:00
2015-08-13 08:51:39 +02:00
$reply [ 'content' ] .= " <span onclick= \" viewfeed( { feed: $feed_id }) \"
2013-02-21 15:58:06 +01:00
style = \ " cursor : pointer \"
title = \ " " . htmlspecialchars ( $line [ 'feed_title' ]) . " \" >
2014-03-21 11:17:34 +01:00
$feed_icon_img </ span > " ;
2013-02-21 15:58:06 +01:00
}
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " </div> " ;
$reply [ 'content' ] .= " </div> " ;
2013-02-21 15:58:06 +01:00
} else {
2013-05-02 08:09:01 +02:00
if ( $line [ " tag_cache " ])
$tags = explode ( " , " , $line [ " tag_cache " ]);
else
$tags = false ;
2013-02-23 13:01:51 +01:00
2013-06-27 17:18:23 +02:00
$line [ " content " ] = sanitize ( $line [ " content " ],
2013-08-02 12:04:14 +02:00
sql_bool_to_bool ( $line [ 'hide_images' ]), false , $entry_site_url , $highlight_words , $line [ " id " ]);
2013-02-23 13:01:51 +01:00
2013-04-18 10:27:34 +02:00
foreach ( PluginHost :: getInstance () -> get_hooks ( PluginHost :: HOOK_RENDER_ARTICLE_CDM ) as $p ) {
2013-02-23 13:01:51 +01:00
$line = $p -> hook_render_article_cdm ( $line );
}
2014-03-12 22:07:52 +01:00
if ( $vfeed_group_enabled && $line [ " feed_title " ]) {
2013-02-21 15:58:06 +01:00
if ( $feed_id != $vgroup_last_feed ) {
$cur_feed_title = $line [ " feed_title " ];
$vgroup_last_feed = $feed_id ;
$cur_feed_title = htmlspecialchars ( $cur_feed_title );
2013-10-17 11:38:48 +02:00
$vf_catchup_link = " <a class='catchup' onclick='catchupFeedInGroup( $feed_id );' href='#'> " . __ ( 'mark feed as read' ) . " </a> " ;
2013-02-21 15:58:06 +01:00
$has_feed_icon = feed_has_icon ( $feed_id );
if ( $has_feed_icon ) {
$feed_icon_img = " <img class= \" tinyFeedIcon \" src= \" " . ICONS_URL . " / $feed_id .ico \" alt= \" \" > " ;
} else {
//$feed_icon_img = "<img class=\"tinyFeedIcon\" src=\"images/blank_icon.gif\" alt=\"\">";
}
2016-03-22 21:22:28 +01:00
$reply [ 'content' ] .= " <div data-feed-id=' $feed_id ' id='FTITLE- $feed_id ' class='cdmFeedTitle'> " .
2013-02-21 15:58:06 +01:00
" <div style= \" float : right \" > $feed_icon_img </div> " .
2015-08-13 08:51:39 +02:00
" <a href= \" # \" class='title' onclick= \" viewfeed( { feed: $feed_id }) \" > " .
2013-02-21 15:58:06 +01:00
$line [ " feed_title " ] . " </a> $vf_catchup_link </div> " ;
2015-07-13 00:19:52 +02:00
2013-02-21 15:58:06 +01:00
}
}
2013-03-25 13:08:20 +01:00
$mouseover_attrs = " onmouseover='postMouseIn(event, $id )'
2013-02-21 15:58:06 +01:00
onmouseout = 'postMouseOut($id)' " ;
2013-03-29 15:53:16 +01:00
$expanded_class = $expand_cdm ? " expanded " : " expandable " ;
2013-03-20 07:59:12 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " <div class= \" cdm $hlc_suffix $expanded_class $class\ "
2016-03-22 21:43:32 +01:00
id = \ " RROW- $id\ " data - article - id = '$id' data - orig - feed - id = '$feed_id' $mouseover_attrs > " ;
2013-02-21 15:58:06 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " <div class= \" cdmHeader \" > " ;
$reply [ 'content' ] .= " <div style= \" vertical-align : middle \" > " ;
2013-02-21 15:58:06 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " <input dojoType= \" dijit.form.CheckBox \"
2013-02-28 12:48:09 +01:00
type = \ " checkbox \" onclick= \" toggleSelectRow2(this, false, true) \"
2013-04-06 22:52:39 +02:00
class = 'rchk' > " ;
2013-02-21 15:58:06 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " $marked_pic " ;
$reply [ 'content' ] .= " $published_pic " ;
2013-02-21 15:58:06 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " </div> " ;
2013-02-21 15:58:06 +01:00
2013-07-31 14:41:06 +02:00
if ( $highlight_words && count ( $highlight_words > 0 )) {
foreach ( $highlight_words as $word ) {
$line [ " title " ] = preg_replace ( " /( \ Q $word\E )/i " ,
" <span class= \" highlight \" > $ 1</span> " , $line [ " title " ]);
}
}
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " <span id= \" RTITLE- $id\ "
2013-02-21 15:58:06 +01:00
onclick = \ " return cdmClicked(event, $id ); \"
2013-07-06 10:34:58 +02:00
class = \ " titleWrap $hlc_suffix\ " >
< a class = \ " title $hlc_suffix\ "
2015-03-21 14:49:38 +01:00
title = \ " " . htmlspecialchars ( $line [ " title " ]) . " \"
2013-02-21 15:58:06 +01:00
target = \ " _blank \" href= \" " .
htmlspecialchars ( $line [ " link " ]) . " \" > " .
$line [ " title " ] .
2013-05-15 18:39:23 +02:00
" </a> <span class= \" author \" > $entry_author </span> " ;
2013-02-21 15:58:06 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= $labels_str ;
2013-02-21 15:58:06 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " <span class='collapseBtn' style='display : none'>
2013-03-20 07:21:14 +01:00
< img src = \ " images/collapse.png \" onclick= \" cdmCollapseArticle(event, $id ) \"
title = \ " " . __ ( " Collapse article " ) . " \" /></span> " ;
2013-02-21 15:58:06 +01:00
if ( ! $expand_cdm )
$content_hidden = " style= \" display : none \" " ;
else
$excerpt_hidden = " style= \" display : none \" " ;
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " <span $excerpt_hidden id= \" CEXC- $id\ " class = \ " cdmExcerpt \" > " . $content_preview . " </span> " ;
2013-06-27 18:21:14 +02:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " </span> " ;
2013-02-21 15:58:06 +01:00
2014-03-12 22:07:52 +01:00
if ( ! $vfeed_group_enabled ) {
2013-03-16 13:59:31 +01:00
if ( @ $line [ " feed_title " ]) {
2013-05-07 17:39:04 +02:00
$rgba = @ $rgba_cache [ $feed_id ];
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " <div class= \" hlFeed \" >
2013-05-07 17:39:04 +02:00
< a href = \ " # \" style= \" background-color: rgba( $rgba ,0.3) \"
2015-08-13 08:51:39 +02:00
onclick = \ " viewfeed( { feed: $feed_id }) \" > " .
2013-03-27 11:20:11 +01:00
truncate_string ( $line [ " feed_title " ], 30 ) . " </a>
2013-03-16 13:59:31 +01:00
</ div > " ;
}
}
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " <span class='updated' title=' $date_entered_fmt '>
2013-03-27 10:34:04 +01:00
$updated_fmt </ span > " ;
2013-03-16 14:17:55 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " <div class='scoreWrap' style= \" vertical-align : middle \" > " ;
$reply [ 'content' ] .= " $score_pic " ;
2013-02-21 15:58:06 +01:00
2013-04-17 16:34:18 +02:00
if ( ! get_pref ( " VFEED_GROUP_BY_FEED " ) && $line [ " feed_title " ]) {
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " <span style= \" cursor : pointer \"
2013-02-21 15:58:06 +01:00
title = \ " " . htmlspecialchars ( $line [ " feed_title " ]) . " \"
2015-08-13 08:51:39 +02:00
onclick = \ " viewfeed( { feed: $feed_id }) \" > $feed_icon_img </span> " ;
2013-02-21 15:58:06 +01:00
}
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " </div> " ;
2013-02-21 15:58:06 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " </div> " ;
2013-02-21 15:58:06 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " <div class= \" cdmContent \" $content_hidden
2013-02-21 15:58:06 +01:00
onclick = \ " return cdmClicked(event, $id ); \"
id = \ " CICD- $id\ " > " ;
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " <div id= \" POSTNOTE- $id\ " > " ;
2013-02-28 13:23:33 +01:00
if ( $line [ 'note' ]) {
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= format_article_note ( $id , $line [ 'note' ]);
2013-02-28 13:23:33 +01:00
}
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " </div> " ;
2013-02-28 13:23:33 +01:00
2013-07-31 09:57:11 +02:00
if ( ! $line [ 'lang' ]) $line [ 'lang' ] = 'en' ;
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " <div class= \" cdmContentInner \" lang= \" " . $line [ 'lang' ] . " \" > " ;
2013-02-21 15:58:06 +01:00
if ( $line [ " orig_feed_id " ]) {
2013-04-17 18:12:14 +02:00
$tmp_result = $this -> dbh -> query ( " SELECT * FROM ttrss_archived_feeds
2016-01-26 17:03:05 +01:00
WHERE id = " . $line["orig_feed_id"] . " AND owner_uid = " . $_SESSION["uid"] );
2013-02-21 15:58:06 +01:00
2013-04-17 18:12:14 +02:00
if ( $this -> dbh -> num_rows ( $tmp_result ) != 0 ) {
2013-02-21 15:58:06 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " <div clear='both'> " ;
$reply [ 'content' ] .= __ ( " Originally from: " );
2013-02-21 15:58:06 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " " ;
2013-02-21 15:58:06 +01:00
2013-04-17 18:12:14 +02:00
$tmp_line = $this -> dbh -> fetch_assoc ( $tmp_result );
2013-02-21 15:58:06 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " <a target='_blank'
2013-02-21 15:58:06 +01:00
href = ' " . htmlspecialchars($tmp_line[' site_url ']) . "' > " .
$tmp_line [ 'title' ] . " </a> " ;
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " " ;
2013-02-21 15:58:06 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " <a target='_blank' href=' " . htmlspecialchars ( $tmp_line [ 'feed_url' ]) . " '> " ;
$reply [ 'content' ] .= " <img title=' " . __ ( 'Feed URL' ) . " 'class='tinyFeedIcon' src='images/pub_unset.png'></a> " ;
2013-02-21 15:58:06 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " </div> " ;
2013-02-21 15:58:06 +01:00
}
}
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " <span id= \" CWRAP- $id\ " > " ;
2013-02-21 15:58:06 +01:00
2013-03-21 07:34:36 +01:00
// if (!$expand_cdm) {
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " <span id= \" CENCW- $id\ " style = \ " display : none \" > " ;
$reply [ 'content' ] .= htmlspecialchars ( $line [ " content " ]);
$reply [ 'content' ] .= " </span. " ;
2013-03-20 10:17:48 +01:00
2013-03-21 07:34:36 +01:00
// } else {
2015-07-13 21:01:29 +02:00
// $reply['content'] .= $line["content"];
2013-03-21 07:34:36 +01:00
// }
2013-02-21 15:58:06 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " </span> " ;
2013-02-21 15:58:06 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " </div> " ;
2013-02-21 15:58:06 +01:00
2015-08-12 07:29:09 +02:00
$reply [ 'content' ] .= " <div class= \" cdmIntermediate \" > " ;
$always_display_enclosures = sql_bool_to_bool ( $line [ " always_display_enclosures " ]);
$reply [ 'content' ] .= format_article_enclosures ( $id , $always_display_enclosures , $line [ " content " ], sql_bool_to_bool ( $line [ " hide_images " ]));
$reply [ 'content' ] .= " </div> " ;
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " <div class= \" cdmFooter \" onclick= \" cdmFooterClick(event) \" > " ;
2013-02-21 15:58:06 +01:00
2013-04-18 10:27:34 +02:00
foreach ( PluginHost :: getInstance () -> get_hooks ( PluginHost :: HOOK_ARTICLE_LEFT_BUTTON ) as $p ) {
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= $p -> hook_article_left_button ( $line );
2013-04-09 14:46:56 +02:00
}
2013-05-02 08:09:01 +02:00
$tags_str = format_tags_string ( $tags , $id );
2013-02-21 15:58:06 +01:00
2015-08-11 14:29:27 +02:00
$reply [ 'content' ] .= " <span class='left'> " ;
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " <img src='images/tag.png' alt='Tags' title='Tags'>
2013-02-21 15:58:06 +01:00
< span id = \ " ATSTR- $id\ " > $tags_str </ span >
< a title = \ " " . __ ( 'Edit tags for this article' ) . " \"
2013-04-30 18:07:08 +02:00
href = \ " # \" onclick= \" editArticleTags( $id ) \" >(+)</a> " ;
2013-02-21 15:58:06 +01:00
2017-01-22 08:18:43 +01:00
$num_comments = ( int ) $line [ " num_comments " ];
2013-02-21 15:58:06 +01:00
$entry_comments = " " ;
if ( $num_comments > 0 ) {
if ( $line [ " comments " ]) {
$comments_url = htmlspecialchars ( $line [ " comments " ]);
} else {
$comments_url = htmlspecialchars ( $line [ " link " ]);
}
2013-09-02 10:58:14 +02:00
$entry_comments = " <a class= \" postComments \"
target = '_blank' href = \ " $comments_url\ " > $num_comments " .
_ngettext ( " comment " , " comments " , $num_comments ) . " </a> " ;
2013-02-21 15:58:06 +01:00
} else {
if ( $line [ " comments " ] && $line [ " link " ] != $line [ " comments " ]) {
2013-09-02 10:58:14 +02:00
$entry_comments = " <a class= \" postComments \" target='_blank' href= \" " . htmlspecialchars ( $line [ " comments " ]) . " \" > " . __ ( " comments " ) . " </a> " ;
2013-02-21 15:58:06 +01:00
}
}
2015-07-13 21:01:29 +02:00
if ( $entry_comments ) $reply [ 'content' ] .= " ( $entry_comments ) " ;
2013-02-21 15:58:06 +01:00
2015-08-11 14:29:27 +02:00
$reply [ 'content' ] .= " </span> " ;
$reply [ 'content' ] .= " <div> " ;
2013-02-21 15:58:06 +01:00
2015-07-13 21:01:29 +02:00
// $reply['content'] .= "$marked_pic";
// $reply['content'] .= "$published_pic";
2013-04-09 14:13:32 +02:00
2013-04-18 10:27:34 +02:00
foreach ( PluginHost :: getInstance () -> get_hooks ( PluginHost :: HOOK_ARTICLE_BUTTON ) as $p ) {
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= $p -> hook_article_button ( $line );
2013-02-21 15:58:06 +01:00
}
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " </div> " ;
$reply [ 'content' ] .= " </div> " ;
2013-02-21 15:58:06 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " </div> " ;
2013-02-21 15:58:06 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " </div> " ;
2013-02-21 15:58:06 +01:00
}
++ $lnum ;
}
if ( $_REQUEST [ " debug " ]) $timing_info = print_checkpoint ( " PE " , $timing_info );
2015-07-12 13:23:32 +02:00
} else if ( ! is_numeric ( $result )) {
2013-02-21 15:58:06 +01:00
$message = " " ;
switch ( $view_mode ) {
case " unread " :
$message = __ ( " No unread articles found to display. " );
break ;
case " updated " :
$message = __ ( " No updated articles found to display. " );
break ;
case " marked " :
$message = __ ( " No starred articles found to display. " );
break ;
default :
2013-03-27 06:40:07 +01:00
if ( $feed < LABEL_BASE_INDEX ) {
2013-04-02 08:21:45 +02:00
$message = __ ( " No articles found to display. You can assign articles to labels manually from article header context menu (applies to all selected articles) or use a filter. " );
2013-02-21 15:58:06 +01:00
} else {
$message = __ ( " No articles found to display. " );
}
}
if ( ! $offset && $message ) {
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] = " <div class='whiteBox'> $message " ;
2013-02-21 15:58:06 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " <p><span class= \" insensitive \" > " ;
2013-02-21 15:58:06 +01:00
2013-04-17 18:12:14 +02:00
$result = $this -> dbh -> query ( " SELECT " . SUBSTRING_FOR_DATE . " (MAX(last_updated), 1, 19) AS last_updated FROM ttrss_feeds
2013-02-21 15:58:06 +01:00
WHERE owner_uid = " . $_SESSION['uid'] );
2013-04-17 18:12:14 +02:00
$last_updated = $this -> dbh -> fetch_result ( $result , 0 , " last_updated " );
2013-04-17 16:34:18 +02:00
$last_updated = make_local_datetime ( $last_updated , false );
2013-02-21 15:58:06 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= sprintf ( __ ( " Feeds last updated at %s " ), $last_updated );
2013-02-21 15:58:06 +01:00
2013-04-17 18:12:14 +02:00
$result = $this -> dbh -> query ( " SELECT COUNT(id) AS num_errors
2013-02-21 15:58:06 +01:00
FROM ttrss_feeds WHERE last_error != '' AND owner_uid = " . $_SESSION["uid"] );
2013-04-17 18:12:14 +02:00
$num_errors = $this -> dbh -> fetch_result ( $result , 0 , " num_errors " );
2013-02-21 15:58:06 +01:00
if ( $num_errors > 0 ) {
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " <br/> " ;
$reply [ 'content' ] .= " <a class= \" insensitive \" href= \" # \" onclick= \" showFeedsWithErrors() \" > " .
2013-02-21 15:58:06 +01:00
__ ( 'Some feeds have update errors (click for details)' ) . " </a> " ;
}
2015-07-13 21:01:29 +02:00
$reply [ 'content' ] .= " </span></p></div> " ;
2015-07-13 12:29:13 +02:00
2013-02-21 15:58:06 +01:00
}
2015-07-12 11:01:34 +02:00
} else if ( is_numeric ( $result ) && $result == - 1 ) {
2015-07-12 16:55:35 +02:00
$reply [ 'first_id_changed' ] = true ;
2013-02-21 15:58:06 +01:00
}
if ( $_REQUEST [ " debug " ]) $timing_info = print_checkpoint ( " H2 " , $timing_info );
return array ( $topmost_article_ids , $headlines_count , $feed , $disable_cache ,
$vgroup_last_feed , $reply );
}
function catchupAll () {
2013-04-17 18:12:14 +02:00
$this -> dbh -> query ( " UPDATE ttrss_user_entries SET
2013-02-26 19:49:46 +01:00
last_read = NOW (), unread = false WHERE unread = true AND owner_uid = " . $_SESSION["uid"] );
2013-04-17 16:34:18 +02:00
ccache_zero_all ( $_SESSION [ " uid " ]);
2013-02-21 15:58:06 +01:00
}
function view () {
2013-02-27 19:16:58 +01:00
$timing_info = microtime ( true );
2013-02-21 15:58:06 +01:00
$reply = array ();
if ( $_REQUEST [ " debug " ]) $timing_info = print_checkpoint ( " 0 " , $timing_info );
2013-04-17 18:12:14 +02:00
$feed = $this -> dbh -> escape_string ( $_REQUEST [ " feed " ]);
$method = $this -> dbh -> escape_string ( $_REQUEST [ " m " ]);
$view_mode = $this -> dbh -> escape_string ( $_REQUEST [ " view_mode " ]);
2013-04-02 13:32:47 +02:00
$limit = 30 ;
2013-02-21 15:58:06 +01:00
@ $cat_view = $_REQUEST [ " cat " ] == " true " ;
2013-04-17 18:12:14 +02:00
@ $next_unread_feed = $this -> dbh -> escape_string ( $_REQUEST [ " nuf " ]);
@ $offset = $this -> dbh -> escape_string ( $_REQUEST [ " skip " ]);
@ $vgroup_last_feed = $this -> dbh -> escape_string ( $_REQUEST [ " vgrlf " ]);
$order_by = $this -> dbh -> escape_string ( $_REQUEST [ " order_by " ]);
2015-07-12 16:55:35 +02:00
$check_first_id = $this -> dbh -> escape_string ( $_REQUEST [ " fid " ]);
2013-02-21 15:58:06 +01:00
if ( is_numeric ( $feed )) $feed = ( int ) $feed ;
/* Feed - 5 is a special case : it is used to display auxiliary information
* when there ' s nothing to load - e . g . no stuff in fresh feed */
if ( $feed == - 5 ) {
2013-04-17 14:23:15 +02:00
print json_encode ( $this -> generate_dashboard_feed ());
2013-02-21 15:58:06 +01:00
return ;
}
$result = false ;
2013-03-27 06:40:07 +01:00
if ( $feed < LABEL_BASE_INDEX ) {
$label_feed = feed_to_label_id ( $feed );
2013-04-17 18:12:14 +02:00
$result = $this -> dbh -> query ( " SELECT id FROM ttrss_labels2 WHERE
2013-02-21 15:58:06 +01:00
id = '$label_feed' AND owner_uid = " . $_SESSION['uid'] );
} else if ( ! $cat_view && is_numeric ( $feed ) && $feed > 0 ) {
2013-04-17 18:12:14 +02:00
$result = $this -> dbh -> query ( " SELECT id FROM ttrss_feeds WHERE
2013-02-21 15:58:06 +01:00
id = '$feed' AND owner_uid = " . $_SESSION['uid'] );
} else if ( $cat_view && is_numeric ( $feed ) && $feed > 0 ) {
2013-04-17 18:12:14 +02:00
$result = $this -> dbh -> query ( " SELECT id FROM ttrss_feed_categories WHERE
2013-02-21 15:58:06 +01:00
id = '$feed' AND owner_uid = " . $_SESSION['uid'] );
}
2013-04-17 18:12:14 +02:00
if ( $result && $this -> dbh -> num_rows ( $result ) == 0 ) {
2013-04-17 16:34:18 +02:00
print json_encode ( $this -> generate_error_feed ( __ ( " Feed not found. " )));
2013-02-21 15:58:06 +01:00
return ;
}
/* Updating a label ccache means recalculating all of the caches
* so for performance reasons we don ' t do that here */
if ( $feed >= 0 ) {
2013-04-17 16:34:18 +02:00
ccache_update ( $feed , $_SESSION [ " uid " ], $cat_view );
2013-02-21 15:58:06 +01:00
}
2013-04-17 16:34:18 +02:00
set_pref ( " _DEFAULT_VIEW_MODE " , $view_mode );
set_pref ( " _DEFAULT_VIEW_ORDER_BY " , $order_by );
2013-02-21 15:58:06 +01:00
2013-03-22 09:37:42 +01:00
/* bump login timestamp if needed */
if ( time () - $_SESSION [ " last_login_update " ] > 3600 ) {
2013-04-17 18:12:14 +02:00
$this -> dbh -> query ( " UPDATE ttrss_users SET last_login = NOW() WHERE id = " .
2013-03-22 09:37:42 +01:00
$_SESSION [ " uid " ]);
$_SESSION [ " last_login_update " ] = time ();
}
2013-02-21 15:58:06 +01:00
if ( ! $cat_view && is_numeric ( $feed ) && $feed > 0 ) {
2013-04-17 18:12:14 +02:00
$this -> dbh -> query ( " UPDATE ttrss_feeds SET last_viewed = NOW()
2013-02-21 15:58:06 +01:00
WHERE id = '$feed' AND owner_uid = " . $_SESSION["uid"] );
}
$reply [ 'headlines' ] = array ();
$override_order = false ;
2015-11-21 20:20:00 +01:00
$skip_first_id_check = false ;
2013-02-21 15:58:06 +01:00
switch ( $order_by ) {
2013-04-04 18:44:55 +02:00
case " title " :
$override_order = " ttrss_entries.title " ;
break ;
case " date_reverse " :
2013-07-06 10:03:01 +02:00
$override_order = " score DESC, date_entered, updated " ;
2015-11-21 20:20:00 +01:00
$skip_first_id_check = true ;
2013-04-04 18:44:55 +02:00
break ;
case " feed_dates " :
$override_order = " updated DESC " ;
break ;
2013-02-21 15:58:06 +01:00
}
if ( $_REQUEST [ " debug " ]) $timing_info = print_checkpoint ( " 04 " , $timing_info );
$ret = $this -> format_headlines_list ( $feed , $method ,
$view_mode , $limit , $cat_view , $next_unread_feed , $offset ,
2015-11-21 20:20:00 +01:00
$vgroup_last_feed , $override_order , true , $check_first_id , $skip_first_id_check );
2013-02-21 15:58:06 +01:00
2013-02-28 13:09:41 +01:00
//$topmost_article_ids = $ret[0];
2013-02-21 15:58:06 +01:00
$headlines_count = $ret [ 1 ];
2014-02-19 12:42:52 +01:00
/* $returned_feed = $ret[2]; */
2013-02-21 15:58:06 +01:00
$disable_cache = $ret [ 3 ];
$vgroup_last_feed = $ret [ 4 ];
2015-07-12 11:01:34 +02:00
//$reply['headlines']['content'] =& $ret[5]['content'];
//$reply['headlines']['toolbar'] =& $ret[5]['toolbar'];
2015-12-04 07:29:58 +01:00
$reply [ 'headlines' ] = $ret [ 5 ];
2015-07-12 11:01:34 +02:00
if ( ! $next_unread_feed )
$reply [ 'headlines' ][ 'id' ] = $feed ;
else
$reply [ 'headlines' ][ 'id' ] = $next_unread_feed ;
$reply [ 'headlines' ][ 'is_cat' ] = ( bool ) $cat_view ;
2013-02-21 15:58:06 +01:00
if ( $_REQUEST [ " debug " ]) $timing_info = print_checkpoint ( " 05 " , $timing_info );
$reply [ 'headlines-info' ] = array ( " count " => ( int ) $headlines_count ,
" vgroup_last_feed " => $vgroup_last_feed ,
" disable_cache " => ( bool ) $disable_cache );
if ( $_REQUEST [ " debug " ]) $timing_info = print_checkpoint ( " 30 " , $timing_info );
2013-04-17 14:23:15 +02:00
$reply [ 'runtime-info' ] = make_runtime_info ();
2013-02-21 15:58:06 +01:00
print json_encode ( $reply );
}
2013-04-17 14:23:15 +02:00
private function generate_dashboard_feed () {
2013-02-21 15:58:06 +01:00
$reply = array ();
$reply [ 'headlines' ][ 'id' ] = - 5 ;
$reply [ 'headlines' ][ 'is_cat' ] = false ;
$reply [ 'headlines' ][ 'toolbar' ] = '' ;
2015-07-13 21:01:29 +02:00
$reply [ 'headlines' ][ 'content' ] = " <div class='whiteBox'> " . __ ( 'No feed selected.' );
2015-07-13 17:43:54 +02:00
2015-07-13 21:01:29 +02:00
$reply [ 'headlines' ][ 'content' ] .= " <p><span class= \" insensitive \" > " ;
2013-02-21 15:58:06 +01:00
2013-04-17 18:12:14 +02:00
$result = $this -> dbh -> query ( " SELECT " . SUBSTRING_FOR_DATE . " (MAX(last_updated), 1, 19) AS last_updated FROM ttrss_feeds
2013-02-21 15:58:06 +01:00
WHERE owner_uid = " . $_SESSION['uid'] );
2013-04-17 18:12:14 +02:00
$last_updated = $this -> dbh -> fetch_result ( $result , 0 , " last_updated " );
2013-04-17 16:34:18 +02:00
$last_updated = make_local_datetime ( $last_updated , false );
2013-02-21 15:58:06 +01:00
2015-07-13 21:01:29 +02:00
$reply [ 'headlines' ][ 'content' ] .= sprintf ( __ ( " Feeds last updated at %s " ), $last_updated );
2013-02-21 15:58:06 +01:00
2013-04-17 18:12:14 +02:00
$result = $this -> dbh -> query ( " SELECT COUNT(id) AS num_errors
2013-02-21 15:58:06 +01:00
FROM ttrss_feeds WHERE last_error != '' AND owner_uid = " . $_SESSION["uid"] );
2013-04-17 18:12:14 +02:00
$num_errors = $this -> dbh -> fetch_result ( $result , 0 , " num_errors " );
2013-02-21 15:58:06 +01:00
if ( $num_errors > 0 ) {
2015-07-13 21:01:29 +02:00
$reply [ 'headlines' ][ 'content' ] .= " <br/> " ;
$reply [ 'headlines' ][ 'content' ] .= " <a class= \" insensitive \" href= \" # \" onclick= \" showFeedsWithErrors() \" > " .
2013-02-21 15:58:06 +01:00
__ ( 'Some feeds have update errors (click for details)' ) . " </a> " ;
}
2015-07-13 21:01:29 +02:00
$reply [ 'headlines' ][ 'content' ] .= " </span></p> " ;
2013-02-21 15:58:06 +01:00
$reply [ 'headlines-info' ] = array ( " count " => 0 ,
" vgroup_last_feed " => '' ,
" unread " => 0 ,
" disable_cache " => true );
return $reply ;
}
2013-04-17 16:34:18 +02:00
private function generate_error_feed ( $error ) {
2013-02-21 15:58:06 +01:00
$reply = array ();
2015-07-13 21:04:21 +02:00
$reply [ 'headlines' ][ 'id' ] = - 7 ;
2013-02-21 15:58:06 +01:00
$reply [ 'headlines' ][ 'is_cat' ] = false ;
$reply [ 'headlines' ][ 'toolbar' ] = '' ;
$reply [ 'headlines' ][ 'content' ] = " <div class='whiteBox'> " . $error . " </div> " ;
$reply [ 'headlines-info' ] = array ( " count " => 0 ,
" vgroup_last_feed " => '' ,
" unread " => 0 ,
" disable_cache " => true );
return $reply ;
}
2013-04-01 09:14:27 +02:00
function quickAddFeed () {
print " <input dojoType= \" dijit.form.TextBox \" style= \" display : none \" name= \" op \" value= \" rpc \" > " ;
print " <input dojoType= \" dijit.form.TextBox \" style= \" display : none \" name= \" method \" value= \" addfeed \" > " ;
2013-10-02 13:24:08 +02:00
print " <div id='fadd_multiple_notify' style='display : none'> " ;
print_notice ( " Provided URL is a HTML page referencing multiple feeds, please select required feed from the dropdown menu below. " );
print " <p></div> " ;
2013-04-01 09:14:27 +02:00
print " <div class= \" dlgSec \" > " . __ ( " Feed or site URL " ) . " </div> " ;
print " <div class= \" dlgSecCont \" > " ;
print " <div style='float : right'>
< img style = 'display : none'
id = 'feed_add_spinner' src = 'images/indicator_white.gif' ></ div > " ;
print " <input style= \" font-size : 16px; width : 20em; \"
placeHolder = \ " " . __ ( " Feed or site URL " ) . " \"
dojoType = \ " dijit.form.ValidationTextBox \" required= \" 1 \" name= \" feed \" id= \" feedDlg_feedUrl \" > " ;
print " <hr/> " ;
2013-04-17 16:34:18 +02:00
if ( get_pref ( 'ENABLE_FEED_CATS' )) {
2013-04-01 09:14:27 +02:00
print __ ( 'Place in category:' ) . " " ;
2013-04-17 16:34:18 +02:00
print_feed_cat_select ( " cat " , false , 'dojoType="dijit.form.Select"' );
2013-04-01 09:14:27 +02:00
}
print " </div> " ;
print ' < div id = " feedDlg_feedsContainer " style = " display : none " >
< div class = " dlgSec " > ' . __(' Available feeds ') . ' </ div >
< div class = " dlgSecCont " > ' .
' < select id = " feedDlg_feedContainerSelect "
dojoType = " dijit.form.Select " size = " 3 " >
< script type = " dojo/method " event = " onChange " args = " value " >
dijit . byId ( " feedDlg_feedUrl " ) . attr ( " value " , value );
</ script >
</ select > ' .
'</div></div>' ;
print " <div id='feedDlg_loginContainer' style='display : none'>
< div class = \ " dlgSec \" > " . __ ( " Authentication " ) . " </div>
< div class = \ " dlgSecCont \" > " .
" <input dojoType= \" dijit.form.TextBox \" name='login' \"
placeHolder = \ " " . __ ( " Login " ) . " \"
2016-05-18 13:48:51 +02:00
autocomplete = \ " new-password \"
2013-04-01 09:14:27 +02:00
style = \ " width : 10em; \" > " .
" <input
placeHolder = \ " " . __ ( " Password " ) . " \"
dojoType = \ " dijit.form.TextBox \" type='password'
2016-05-18 13:48:51 +02:00
autocomplete = \ " new-password \"
2013-04-01 09:14:27 +02:00
style = \ " width : 10em; \" name='pass' \" >
</ div ></ div > " ;
print " <div style= \" clear : both \" >
< input type = \ " checkbox \" name= \" need_auth \" dojoType= \" dijit.form.CheckBox \" id= \" feedDlg_loginCheck \"
onclick = 'checkboxToggleElement(this, \"feedDlg_loginContainer\")' >
< label for = \ " feedDlg_loginCheck \" > " .
__ ( 'This feed requires authentication.' ) . " </div> " ;
print " </form> " ;
print " <div class= \" dlgButtons \" >
< button dojoType = \ " dijit.form.Button \" onclick= \" return dijit.byId('feedAddDlg').execute() \" > " . __ ( 'Subscribe' ) . " </button> " ;
if ( ! ( defined ( '_DISABLE_FEED_BROWSER' ) && _DISABLE_FEED_BROWSER )) {
print " <button dojoType= \" dijit.form.Button \" onclick= \" return feedBrowser() \" > " . __ ( 'More feeds' ) . " </button> " ;
}
print " <button dojoType= \" dijit.form.Button \" onclick= \" return dijit.byId('feedAddDlg').hide() \" > " . __ ( 'Cancel' ) . " </button>
</ div > " ;
//return;
}
function feedBrowser () {
if ( defined ( '_DISABLE_FEED_BROWSER' ) && _DISABLE_FEED_BROWSER ) return ;
2013-04-17 18:12:14 +02:00
$browser_search = $this -> dbh -> escape_string ( $_REQUEST [ " search " ]);
2013-04-01 09:14:27 +02:00
print " <input dojoType= \" dijit.form.TextBox \" style= \" display : none \" name= \" op \" value= \" rpc \" > " ;
print " <input dojoType= \" dijit.form.TextBox \" style= \" display : none \" name= \" method \" value= \" updateFeedBrowser \" > " ;
print " <div dojoType= \" dijit.Toolbar \" >
< div style = 'float : right' >
< img style = 'display : none'
id = 'feed_browser_spinner' src = 'images/indicator_white.gif' >
< input name = \ " search \" dojoType= \" dijit.form.TextBox \" size= \" 20 \" type= \" search \"
onchange = \ " dijit.byId('feedBrowserDlg').update() \" value= \" $browser_search\ " >
< button dojoType = \ " dijit.form.Button \" onclick= \" dijit.byId('feedBrowserDlg').update() \" > " . __ ( 'Search' ) . " </button>
</ div > " ;
print " <select name= \" mode \" dojoType= \" dijit.form.Select \" onchange= \" dijit.byId('feedBrowserDlg').update() \" >
< option value = '1' > " . __('Popular feeds') . " </ option >
< option value = '2' > " . __('Feed archive') . " </ option >
</ select > " ;
print __ ( " limit: " );
print " <select dojoType= \" dijit.form.Select \" name= \" limit \" onchange= \" dijit.byId('feedBrowserDlg').update() \" > " ;
foreach ( array ( 25 , 50 , 100 , 200 ) as $l ) {
2014-02-19 12:42:52 +01:00
//$issel = ($l == $limit) ? "selected=\"1\"" : "";
print " <option value= \" $l\ " > $l </ option > " ;
2013-04-01 09:14:27 +02:00
}
print " </select> " ;
print " </div> " ;
require_once " feedbrowser.php " ;
print " <ul class='browseFeedList' id='browseFeedList'> " ;
2014-02-19 12:42:52 +01:00
print make_feed_browser ( " " , 25 );
2013-04-01 09:14:27 +02:00
print " </ul> " ;
print " <div align='center'>
< button dojoType = \ " dijit.form.Button \" onclick= \" dijit.byId('feedBrowserDlg').execute() \" > " . __ ( 'Subscribe' ) . " </button>
< button dojoType = \ " dijit.form.Button \" style='display : none' id='feed_archive_remove' onclick= \" dijit.byId('feedBrowserDlg').removeFromArchive() \" > " . __ ( 'Remove' ) . " </button>
< button dojoType = \ " dijit.form.Button \" onclick= \" dijit.byId('feedBrowserDlg').hide() \" > " . __ ( 'Cancel' ) . " </button></div> " ;
}
function search () {
2013-04-17 18:12:14 +02:00
$this -> params = explode ( " : " , $this -> dbh -> escape_string ( $_REQUEST [ " param " ]), 2 );
2013-04-01 09:14:27 +02:00
$active_feed_id = sprintf ( " %d " , $this -> params [ 0 ]);
$is_cat = $this -> params [ 1 ] != " false " ;
print " <div class= \" dlgSec \" > " . __ ( 'Look for' ) . " </div> " ;
print " <div class= \" dlgSecCont \" > " ;
print " <input dojoType= \" dijit.form.ValidationTextBox \"
style = \ " font-size : 16px; width : 20em; \"
required = \ " 1 \" name= \" query \" type= \" search \" value=''> " ;
2015-07-07 14:59:32 +02:00
print " <hr/><span style='float : right'> " . T_sprintf ( 'in %s' , getFeedTitle ( $active_feed_id , $is_cat )) . " </span> " ;
2013-04-01 09:14:27 +02:00
2015-08-04 12:53:48 +02:00
if ( DB_TYPE == " pgsql " ) {
print " <hr/> " ;
print_select ( " search_language " , " " , Pref_Feeds :: $feed_languages ,
" dojoType='dijit.form.Select' title= \" " . __ ( 'Used for word stemming' ) . " \" " );
}
2013-04-01 09:14:27 +02:00
print " </div> " ;
print " <div class= \" dlgButtons \" > " ;
2014-04-15 06:18:33 +02:00
if ( count ( PluginHost :: getInstance () -> get_hooks ( PluginHost :: HOOK_SEARCH )) == 0 ) {
2013-04-01 09:14:27 +02:00
print " <div style= \" float : left \" >
2013-09-02 11:54:41 +02:00
< a class = \ " visibleLink \" target= \" _blank \" href= \" http://tt-rss.org/wiki/SearchSyntax \" > " . __ ( " Search syntax " ) . " </a>
2013-04-01 09:14:27 +02:00
</ div > " ;
}
print " <button dojoType= \" dijit.form.Button \" onclick= \" dijit.byId('searchDlg').execute() \" > " . __ ( 'Search' ) . " </button>
< button dojoType = \ " dijit.form.Button \" onclick= \" dijit.byId('searchDlg').hide() \" > " . __ ( 'Cancel' ) . " </button>
</ div > " ;
}
2015-06-12 12:06:36 +02:00
function update_debugger () {
header ( " Content-type: text/html " );
$feed_id = ( int ) $_REQUEST [ " feed_id " ];
@ $do_update = $_REQUEST [ " action " ] == " do_update " ;
$csrf_token = $_REQUEST [ " csrf_token " ];
$refetch_checked = isset ( $_REQUEST [ " force_refetch " ]) ? " checked " : " " ;
$rehash_checked = isset ( $_REQUEST [ " force_rehash " ]) ? " checked " : " " ;
?>
< html >
< head >
< link rel = " stylesheet " type = " text/css " href = " css/utility.css " >
< title > Feed Debugger </ title >
</ head >
< body class = " small_margins " >
< h1 > Feed Debugger : < ? php echo " $feed_id : " . getFeedTitle ( $feed_id ) ?> </h1>
< form method = " GET " action = " " >
< input type = " hidden " name = " op " value = " feeds " >
< input type = " hidden " name = " method " value = " update_debugger " >
< input type = " hidden " name = " xdebug " value = " 1 " >
< input type = " hidden " name = " csrf_token " value = " <?php echo $csrf_token ?> " >
< input type = " hidden " name = " action " value = " do_update " >
< input type = " hidden " name = " feed_id " value = " <?php echo $feed_id ?> " >
< input type = " checkbox " name = " force_refetch " value = " 1 " < ? php echo $refetch_checked ?> > Force refetch<br/>
< input type = " checkbox " name = " force_rehash " value = " 1 " < ? php echo $rehash_checked ?> > Force rehash<br/>
< p />< button type = " submit " > Continue </ button >
</ form >
< hr >
< pre >< ? php
if ( $do_update ) {
include " rssfuncs.php " ;
update_rss_feed ( $feed_id , true , true );
}
?> </pre>
2013-04-01 09:14:27 +02:00
2015-06-12 12:06:36 +02:00
</ body >
</ html >
< ? php
}
2013-02-21 15:58:06 +01:00
}
?>