<?php
// File: $Id: rss.php,v 1.20 2001/12/04 00:50:23 gregorrothfuss Exp $ $Name: $
// ----------------------------------------------------------------------
// POST-NUKE Content Management System
// Copyright (C) 2001 by the Post-Nuke Development Team.
// http://www.postnuke.com/
// ----------------------------------------------------------------------
// Based on:
// PHP-NUKE Web Portal System - http://phpnuke.org/
// Thatware - http://thatware.org/
// ----------------------------------------------------------------------
// LICENSE
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License (GPL)
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// To read the license please visit http://www.gnu.org/copyleft/gpl.html
// ----------------------------------------------------------------------
// Original Author of file: Patrick Kellum
// Purpose of file: Retrive and display RSS feeds from other websites
// ----------------------------------------------------------------------
$blocks_modules['rss'] = array(
'func_display' => 'blocks_rss_block',
'func_add' => 'blocks_rss_test',
'func_update' => 'blocks_rss_update',
'func_edit' => 'blocks_rss_select',
'text_type' => 'RSS',
'text_type_long' => 'RSS Newsfeed',
'allow_multiple' => true,
'form_content' => false,
'form_refresh' => true,
'show_preview' => true
);
function blocks_rss_block($row) {
advheadlines($row);
}
function blocks_rss_update($row) {
global $pntable, $dbconn;
if($row['rssurl']) {
$row['url'] = $row['rssurl'];
blocks_rss_test($row);
if(!$row['title']) {
$column = &$pntable['sitename_column'];
$sitename_result = $dbconn->Execute("SELECT $column[sitename] FROM $pntable[headlines] WHERE $column[rssurl]='$row[url]'");
list($row['title']) = $sitename_result->fields;
}
}
else {
blocks_rss_test($row);
$vars = array('sitename'=>$row['title'],'rssurl'=>$row['url']);
HeadlinesAdd($vars);
}
return $row;
}
function blocks_rss_test($row) {
if(!ereg('http://' , $row['url'])) {
$row['url'] = 'http://' . $row['url'];
}
if($row['url'] == 'http://') {
$row['url'] = '';
}
return $row;
}
function blocks_rss_select($row)
{
global $pntable, $dbconn;
$output = '<tr><td class="pn-normal">RSS File URL:</td><td>'
."<input type=\"text\" name=\"url\" size=\"$url_size\" maxlength=\"$url_maxlength\" value=\"$row[url]\">"
.' <select name="rssurl" size="1">'
;
if ($row['url'])
{
$output.= "<option value=\"\" selected><--- Current</option>";
} else {
$output .= "<option value=\"\" selected>"._CUSTOM.'</option>';
}
$column = &$pntable['headlines_column'];
$sites_result = $dbconn->Execute("SELECT $column[rssurl] as rssurl, $column[sitename] as sitename
FROM $pntable[headlines]
ORDER BY $column[sitename],$column[id]");
while(!$sites_result->EOF) {
$sites = $sites_result->GetRowAssoc(false);
$sites_result->MoveNext();
$output .= "<option value=\"$sites[rssurl]\">$sites[sitename]</option>\n";
}
$output .= '</select> [ <a href="admin.php?op=AdvHeadlinesAdmin">Setup</a> ]'
.'</td></tr>'
;
// $sel[$row['ur'l]] = ' checked';
// $output .= "<tr><td class=\"pn-normal\">Maximum Items Listed:</td><td><input type=\"text\" name=\"\" size=\"4\" maxlength=\"4\" value=\"$row[]\"></td></tr>";
// $output .= "<tr><td class=\"pn-normal\">Use Old-Style Output:</td><td><input type=\"checkbox\" name=\"\" value=\"1\"$sel_old[1]></td></tr>";
return $output;
}
/*
* Parse RSS File (as array of lines)
* A rather un-optimized function to parse an rss file (sent as an array)
* I'll have to clean it up some later.
*
* If all goes well, the resulting array should be compatable with the results from
* the built-in xml_parse_into_struct() function. Except for some differences in
* parsing of html entities.
*/
function rss_parse_array($f)
{
$struct = '';
foreach ($f as $line)
{
$parse = '';
// get our positions
$sp = strpos($line,'>');
$ep = strrpos($line,'<');
$ep2 = strrpos($line,'>');
// split into first tag, last tag, and content
$first_tag = substr($line,1,($sp - 1));
$last_tag = substr($line,($ep + 1),(($ep2 - $ep) - 1));
$content = substr($line,($sp + 1),(($ep - 1) - $sp));
if (!$line)
{ // blank line
continue;
}
if ($first_tag == $last_tag)
{ // no content, single tag line
if ($first_tag[0] == '/')
{
$parse['type'] = 'close';
if ($temp_str = strstr($first_tag, ':'))
{
$first_tag = $temp_str;
}
$parse['tag'] = strtolower(substr($first_tag,1,(strlen($first_tag) - 1)));
} else {
$parse['type'] = 'open';
if ($temp_str = strstr($first_tag, ':'))
{
$first_tag = substr($temp_str,1,(strlen($temp_str) - 1));
}
$parse['tag'] = strtolower($first_tag);
}
$parse['value'] = '';
} else { // complete
$parse['type'] = 'complete';
$parse['tag'] = strtolower($first_tag);
if ($content)
{ // convert everything to html entities except tags
$content = htmlspecialchars($content);
$content = str_replace('&','&',$content); // me no like, but no other way I can find
$content = str_replace('>','>',$content);
$content = str_replace('<','<',$content);
}
$parse['value'] = $content;
}
$struct[] = $parse;
}
return $struct;
}
function advheadlines($row) {
global $pntable, $dbconn;
$max_items = 10;
$show_descriptions = true;
$use_old_style_rss = false; // set to true to use the php-Nuke style.
$past = time() - $row['refresh'];
if($row['unix_update'] < $past && $row['url']) {
$rss = parse_url($row['url']);
$rss['port'] = ($rss['port'])?$rss['port']:80;
// retrive the rss file
$fp = fsockopen($rss['host'], $rss['port'], $errno, $errstr, 5);
if(!$fp) {
$content = addslashes('<font class=\"pn-normal">' . _RSSPROBLEM . '</font>');
$next_try = time() + 600;
$column = &$pntable['blocks_column'];
$result = $dbconn->Execute("UPDATE $pntable[blocks] SET $column[content]='$content',$column[last_update]=FROM_UNIXTIME($next_try) WHERE $column[bid]=$bid");
$row['title'] = "$row[title] *";
$row['content'] = "$row[content]\n\n\n<!--\n\n\n\n\n\n\n".ml_ftime(_DATETIMELONG,$row['unix_update'])."\n\n\n\n\n-->\n\n\n\n";
themesideblock($row);
return;
}
else {
fputs($fp, 'GET ' . $rss['path'] . '?' . $rss['query'] . " HTTP/1.0\r\n");
fputs($fp, 'HOST: ' . $rss['host'] . "\r\n\r\n");
$rss_file = '';
$start_time = time();
while(!feof($fp)) {
$line = fgets($fp, 4096);
if(!$go) {
if($line[0] == '<') {
$go = true;
}
}
else {
$rss_file[] = trim($line);
}
if((time() - $start_time) == 5) { // if the source server is too slow, we give up. 5 seconds is more then enough time
fputs($fp, "Connection: close\r\n\r\n");
fclose($fp);
$column = &$pntable['blocks_column'];
$sql = "UPDATE $pntable[blocks] SET $column[last_update]=0 WHERE $column[bid]=$row[bid]";
$result = $dbconn->Execute($sql);
if($dbconn->ErrorNo()<>0) { // we want to try again in a few minutes
print "\n\n\n<!--Time Out\n\n\n".$dbconn->ErrorMsg()."\n\n\n$sql\n\n\n-->";
}
return;
}
}
fputs($fp, "Connection: close\r\n\r\n");
fclose($fp);
$struct = rss_parse_array($rss_file);
// parse the file
$channel_data = '';
$image_data = '';
$item_data = '';
$search_data = '';
$total_items = 0;
foreach($struct as $v) {
if(!is_array($v)) {
continue;
}
if($v['type'] == 'open') {
switch($v['tag']) {
case 'channel' :
$cur_block = 'channel';
break;
case 'image' :
$cur_block = 'image';
break;
case 'item' :
$cur_block = 'item';
break;
case 'textinput' :
$cur_block = 'textinput';
break;
}
}
elseif($v['type'] == 'close') {
switch($v['tag']) {
case 'channel' :
$cur_block = '';
break;
case 'image' :
$cur_block = '';
break;
case 'item' :
$cur_block = '';
$total_items++;
break;
case 'textinput' :
$cur_block = '';
break;
}
}
elseif($v['type'] == 'complete') {
$tag = $v['tag'];
switch($cur_block) {
case 'channel' :
$channel_data[$tag] = $v['value'];
break;
case 'image' :
$image_data[$tag] = $v['value'];
break;
case 'item' :
$item_data[$total_items][$tag] = $v['value'];
break;
case 'textinput' :
$search_data[$tag] = $v['value'];
break;
}
}
}
// start generating content
$content = '';
// image & link
if($image_data['url'] && $image_data['url'] != 'http://yoursite.com/images/logo.gif') {
if(!$image_data['link']) {
$image_data['link'] = $channel_data['link'];
}
if(!$image_data['title']) {
$image_data['title'] = $channel_data['title'];
}
if(!$image_data['description']) {
if($channel_data['description']) {
$image_data['description'] = $channel_data['description'];
}
else {
$image_data['description'] = 'No description provided...';
}
}
if(!$image_data['width']) {
$image_data['width'] = 88;
}
if(!$image_data['height']) {
$image_data['height'] = 31;
}
if ($use_old_style_rss)
{
$content .= "<a class=\"pn-normal\" href=\"$image_data[link]\" target=\"_blank\" title=\"$image_data[description]\">\n"
."<img src=\"$image_data[url]\" border=\"0\" alt=\"$image_data[title]\" width=\"$image_data[width]\" height=\"$image_data[height]\"></a>\n"
.'<br>\n'
;
} else {
$content .= "<div align=\"center\" style=\"text-align:center\"><a class=\"pn-normal\" href=\"$image_data[link]\" target=\"_blank\" title=\"$image_data[description]\">\n"
."<img src=\"$image_data[url]\" border=\"0\" alt=\"$image_data[title]\" width=\"$image_data[width]\" height=\"$image_data[height]\"></a>\n"
.'</div>'
;
}
}
// pub date
if($channel_data['pubDate']) {
$content .= "<div align=\"center\" style=\"text-align:center\">\n"
."<b>($channel_data[pubDate])</b></div>";
}
// items
if($max_items > $total_items) { // we don't want a bunch of empty item spaces
$max_items = $total_items;
}
for($i = 0; $i < ($max_items); $i++) {
if($i) {
if ($use_old_style_rss)
{
$content .= "\n";
} else {
$content .= "<hr noshade size=\"1\" width=\"50%\">\n";
}
}
if(!$item_data[$i]['title']) {
$item_data[$i]['title'] = '<i>[no title]</i>';
}
if ($use_old_style_rss)
{
$content .= '<font class="pn-normal"><strong><big>·</big></strong> </font><a class="pn-normal" href="' . $item_data[$i]['link'] . '" title="' . $item_data[$i]['title'] . '" target="_blank">' . $item_data[$i]['title'] . '</a><br>';
} else {
$content .= '<a href="' . $item_data[$i]['link'] . '" title="' . $item_data[$i]['title'] . '" target="_blank" class="pn-normal">' . $item_data[$i]['title'] . '</a><br>';
}
if($show_descriptions && $item_data[$i]['description']) {
$content .= '<font class="pn-normal"><i>' . $item_data[$i]['description'] . '</i></font><br>';
}
}
// search
if($search_data['link'] && $search_data['name'] && $search_data['title']) {
if ($use_old_style_rss)
{
$content .= '<br>';
} else {
$content .= '<hr noshade size="1" width="50%">';
}
$content .= "<center><form method=\"get\" action=\"$search_data[link]\" target=\"_blank\">\n";
if($search_data['description']) {
$content .= htmlspecialchars($search_data['description']) . '<br>';
}
$content .= "<input type=\"text\" name=\"$search_data[name]\" size=\"15\"><br><input type=\"submit\" value=\"$search_data[title]\"></form></center>\n";
}
// copyright
if($channel_data['copyright']) {
$content .= "<font class=\"pn-normal\">$channel_data[copyright]</font>\n";
}
// done with rdf file
if ($use_old_style_rss)
{
$content .= "<br><a class=\"pn-normal\" href=\"$channel_data[link]\" target=\"_blank\"><b>_READMORE</b></a>\n";
$row['content'] = "<font class=\"pn-normal\">$content</font>\n";
} else {
$content .= "<div align=\"right\" style=\"text-align:right\"><a class=\"pn-normal\" href=\"$channel_data[link]\" target=\"_blank\"><b>_READMORE</b></a></div>\n";
$row['content'] = "<font class=\"pn-normal\">$content</font>\n";
}
}
$sql_content = addslashes($row['content']);
$column = &$pntable['blocks_column'];
//FTO Use a php date time to stay compatible with
// all databases.
$now=$dbconn->DBTimeStamp(mktime());
$sql = "UPDATE $pntable[blocks] SET $column[content]='$sql_content', $column[last_update]=$now WHERE $column[bid]=$row[bid]";
$result = $dbconn->Execute($sql);
if($dbconn->ErrorNo()<>0) {
$row['title'] .= ' *';
$row['content'] .= "<!--\n\n\n".$dbconn->ErrorMsg()."\n\n\n$sql\n\n\n-->";
}
}
// patch to get around ML problems.
$row['content'] = str_replace('_READMORE', _READMORE, $row['content']);
themesideblock($row);
}
?>