<?

// Я.RSS

/***************************************************************************

* Author Konstantin Likhachev
* All rights reserved.
*
****************************************************************************/


// Настройки
// Проверять доступ для пауков
// Группа для пауков задается в настройках
$botAccess = true;  // Если true - пауки = гости
// Версия
$version        = ' revision 29.09.2008 (SMF 1.1.x)';
// Количество записей на 1-ой странице в RSS
$limit   = 40;



/**
 * Подгружаемые данные используются в parseBbc()
 *
 * Вообще то, вся это бодяга грузиться с помощью loadTheme, но т.к. нам тема
 * сама по себе не нужна, я выдернул нужный код и вставил его сюда... :)
 */
function loadServerAndBrowser() {
    global $context;

    // This determines the server... not used in many places, except for login fixing.
    $context['server'] = array(
        'is_iis'             => isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') !== false,
        'is_apache'          => isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Apache') !== false,
        'is_cgi'             => isset($_SERVER['SERVER_SOFTWARE']) && strpos(php_sapi_name(), 'cgi') !== false,
        'is_windows'         => stristr(PHP_OS, 'WIN') !== false,
        'iso_case_folding'   => ord(strtolower(chr(138))) === 154,
        'complex_preg_chars' => @version_compare(PHP_VERSION, '4.3.3') != -1,
    );

    // A bug in some versions of IIS under CGI (older ones) makes cookie setting not work with Location: headers.
    $context['server']['needs_login_fix'] = $context['server']['is_cgi'];

    // The following determines the user agent (browser) as best it can.
    $context['browser'] = array(
        'is_opera'     => strpos($_SERVER['HTTP_USER_AGENT'], 'Opera')      !== false,
        'is_opera6'    => strpos($_SERVER['HTTP_USER_AGENT'], 'Opera 6')    !== false,
        'is_opera7'    => strpos($_SERVER['HTTP_USER_AGENT'], 'Opera 7')    !== false || strpos($_SERVER['HTTP_USER_AGENT'], 'Opera/7') !== false,
        'is_opera8'    => strpos($_SERVER['HTTP_USER_AGENT'], 'Opera 8')    !== false || strpos($_SERVER['HTTP_USER_AGENT'], 'Opera/8') !== false,
        'is_opera9'    => strpos($_SERVER['HTTP_USER_AGENT'], 'Opera 9')    !== false || strpos($_SERVER['HTTP_USER_AGENT'], 'Opera/9') !== false,
        'is_ie4'       => strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 4')     !== false && strpos($_SERVER['HTTP_USER_AGENT'], 'WebTV')   === false,
        'is_safari'    => strpos($_SERVER['HTTP_USER_AGENT'], 'Safari')     !== false,
        'is_mac_ie'    => strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 5.')    !== false && strpos($_SERVER['HTTP_USER_AGENT'], 'Mac')     !== false,
        'is_web_tv'    => strpos($_SERVER['HTTP_USER_AGENT'], 'WebTV')      !== false,
        'is_konqueror' => strpos($_SERVER['HTTP_USER_AGENT'], 'Konqueror')  !== false,
        'is_firefox'   => strpos($_SERVER['HTTP_USER_AGENT'], 'Firefox')    !== false,
        'is_firefox1'  => strpos($_SERVER['HTTP_USER_AGENT'], 'Firefox/1.') !== false,
        'is_firefox2'  => strpos($_SERVER['HTTP_USER_AGENT'], 'Firefox/2.') !== false,
        'is_iphone'    => strpos($_SERVER['HTTP_USER_AGENT'], 'iPhone')     !== false,
    );

    $context['browser']['is_gecko'] = strpos($_SERVER['HTTP_USER_AGENT'], 'Gecko') !== false && !$context['browser']['is_safari'] && !$context['browser']['is_konqueror'];

    // Internet Explorer 5 and 6 are often "emulated".
    $context['browser']['is_ie7']   = strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 7') !== false && !$context['browser']['is_opera'] && !$context['browser']['is_gecko'] && !$context['browser']['is_web_tv'];
    $context['browser']['is_ie6']   = strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 6') !== false && !$context['browser']['is_opera'] && !$context['browser']['is_gecko'] && !$context['browser']['is_web_tv'];
    $context['browser']['is_ie5.5'] = strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 5.5') !== false && !$context['browser']['is_opera'] && !$context['browser']['is_gecko'] && !$context['browser']['is_web_tv'];
    $context['browser']['is_ie5']   = strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 5.0') !== false && !$context['browser']['is_opera'] && !$context['browser']['is_gecko'] && !$context['browser']['is_web_tv'];

    $context['browser']['is_ie'] = $context['browser']['is_ie4'] || $context['browser']['is_ie5'] || $context['browser']['is_ie5.5'] || $context['browser']['is_ie6'] || $context['browser']['is_ie7'];
    $context['browser']['needs_size_fix'] = ($context['browser']['is_ie5'] || $context['browser']['is_ie5.5'] || $context['browser']['is_ie4'] || $context['browser']['is_opera6']) && strpos($_SERVER['HTTP_USER_AGENT'], 'Mac') === false;

    // This isn't meant to be reliable, it's just meant to catch most bots to prevent PHPSESSID from showing up.
    $context['browser']['possibly_robot'] = !empty($user_info['possibly_robot']);
}

define('SMF', 'YARSS');

// We're going to want a few globals... these are all set later.
global $context, $modSettings;

// Get the forum's settings for database and file paths.
require_once(dirname(__FILE__) . '/Settings.php');

$ssi_error_reporting = error_reporting(E_ALL);

// Don't do john didley if the forum's been shut down competely.
if ($maintenance == 2 && (!isset($ssi_maintenance_off) || $ssi_maintenance_off !== true))
    die($mmessage);

// Fix for using the current directory as a path.
if (substr($sourcedir, 0, 1) == '.' && substr($sourcedir, 1, 1) != '.')
    $sourcedir = dirname(__FILE__) . substr($sourcedir, 1);

// Load the important includes.
require_once($sourcedir . '/QueryString.php');
require_once($sourcedir . '/Subs.php');
require_once($sourcedir . '/Errors.php');
require_once($sourcedir . '/Load.php');
require_once($sourcedir . '/Security.php');

if (@version_compare(PHP_VERSION, '4.2.3') != 1)
    require_once($sourcedir . '/Subs-Compat.php');

// Connect to the MySQL database.
if (empty($db_persist))
    $db_connection = @mysql_connect($db_server, $db_user, $db_passwd);
else
    $db_connection = @mysql_pconnect($db_server, $db_user, $db_passwd);
if ($db_connection === false)
    return false;

// Add the database onto the prefix to avoid conflicts with other scripts.
/*if (strpos($db_prefix, '.') === false)
    $db_prefix = is_numeric(substr($db_prefix, 0, 1)) ? $db_name . '.' . $db_prefix : '`' . $db_name . '`.' . $db_prefix;
else*/
    @mysql_select_db($db_name, $db_connection);

// Load installed 'Mods' settings.
reloadSettings();
// Clean the request variables.
cleanRequest();

// Seed the random generator?
#if (empty($modSettings['rand_seed']) || mt_rand(1, 250) == 69)
#    smf_seed_generator();

// Check on any hacking attempts.
if (isset($_REQUEST['GLOBALS']) || isset($_COOKIE['GLOBALS']))
    die('Hacking attempt...');
elseif (isset($_REQUEST['ssi_theme']) && (int) $_REQUEST['ssi_theme'] == (int) $ssi_theme)
    die('Hacking attempt...');
elseif (isset($_COOKIE['ssi_theme']) && (int) $_COOKIE['ssi_theme'] == (int) $ssi_theme)
    die('Hacking attempt...');
elseif (isset($_REQUEST['ssi_layers']))
{
    if ((@get_magic_quotes_gpc() ? addslashes($_REQUEST['ssi_layers']) : $_REQUEST['ssi_layers']) == htmlspecialchars($ssi_layers))
        die('Hacking attempt...');
}
if (isset($_REQUEST['context']))
    die('Hacking attempt...');

// Make sure wireless is always off.
define('WIRELESS', false);

// Primarily, this is to fix the URLs...
ob_start('ob_sessrewrite');

$mode  = @$_GET['mode'];
if ($mode == 'comments') {
	header ("Status: 404 Not Found");
	die;
}
$forum = (int)@$_GET['forum'];
$topic = (int)@$_GET['topic'];
$post  = (int)@$_GET['post'];

$characterSet = 'UTF-8';
// список всех RSS в opml (yarss.php?mode=opml)
if ($mode == 'opml') {

    header('Content-Type: text/xml; charset=' . $characterSet);

    $request = db_query('
        SELECT ID_BOARD, name
        FROM ' . $db_prefix . 'boards
        ' . ($botAccess ? 'WHERE (FIND_IN_SET(-1, memberGroups))' : '') . '
        ORDER BY boardOrder',
        __FILE__, __LINE__
    );

    echo '<?xml version="1.0" encoding="' . $characterSet . '"?><opml version="1.0">' . "\n"
       . '<head>' . "\n"
       . '<title>Ya.rss opml file</title>' . "\n"
       . '</head>' . "\n"
       . '<body>' . "\n";

    while ($row = mysql_fetch_assoc($request)) {
        echo '<outline text="' . htmlspecialchars($row['name']) . '" type="rss" htmlUrl="' . $scripturl . '?board=' . $row['ID_BOARD'] . '.0" xmlUrl="' . $boardurl . '/yarss.php?forum=' . $row['ID_BOARD'] . '" />' . "\n";
    }

    echo '</body>' . "\n"
       . '</opml>';
}

elseif (empty($mode) AND ! empty($topic)) { 
    // Проверяем, можно ли выдавать RSS из этого форума
    $request = db_query('
        SELECT b.name as bname, b.memberGroups, m.subject as name
        FROM ' . $db_prefix . 'boards b, ' . $db_prefix . 'topics t, ' . $db_prefix . 'messages m 
        WHERE t.ID_TOPIC = ' . $topic . '
          AND t.ID_FIRST_MSG = m.ID_MSG
        ORDER BY boardOrder',
        __FILE__, __LINE__
    );
    $row = mysql_fetch_assoc($request);

    if (empty($row['name'])) {
        header('HTTP/1.0 404 Not Found');
        echo '<html><body>Эта тема не существует.</body></html>';
    }  else {
        if ($botAccess) {
            $arMemberGroups = explode(',', $row['memberGroups']);

            if (!in_array('-1', $arMemberGroups)) {
                header('HTTP/1.0 404 Not Found');
                echo '<html><body>Эта тема не выдается в виде RSS.</body></html>';
                exit;
            }

            unset($arMemberGroups);
        }

        // шапка RSS
        $xml = '<?xml version="1.0" encoding="' . $characterSet . '"?>' . "\n"
             . '<rss version="2.0" xmlns:ya="http://blogs.yandex.ru/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/">' . "\n"
             . '<channel>' . "\n"
             . '<title>' . htmlspecialchars($row['name']) . ' — www.rock.ru</title>' . "\n"
             . '<link>' . $boardurl . 'index.php?topic=' . $topic . '.new;boardseen#new</link>' . "\n"
             . '<description>' . htmlspecialchars($row['name']) . '  — Российский рок-портал www.rock.ru</description>' . "\n"
             . '<language>ru</language>' . "\n"
             . '<webMaster>rock@rock.ru (Aleksei Miheev)</webMaster>' . "\n";

        // магический mysql-запрос, который все делает

        if (! empty ($post)) {
            $and_where = 'AND mes.ID_MSG < "' . $post . '"';
        } else {
            $and_where = '';
        }
        $order = 'mes.ID_MSG DESC';

        $request = db_query('
            SELECT mes.*, mem.realName as memberName
            FROM   ' . $db_prefix . 'messages mes, ' . $db_prefix . 'members mem
            WHERE  mes.ID_MEMBER = mem.ID_MEMBER
              AND  mes.ID_TOPIC = "' . $topic . '" ' . $and_where .'

            ORDER BY ' . $order . ' LIMIT ' . $limit,
            __FILE__, __LINE__
        );

        // для листалки
        $paginationPost  = 0;
        $paginationTopic = 0;

        // <item>-ы
        if (mysql_num_rows($request) > 0) {
            $modif = false;

            loadServerAndBrowser();

            while ($row = mysql_fetch_assoc($request)) {
                $paginationPost  = $row['ID_MSG'];

		parsecode($row['body']);
                $body = $row['body'];
                //$body = html_entity_decode($body);
                //$body = nl2br($body);
                //$body = preg_replace('/[\x00-\x08\x0B-\x0C\x0E-\x19]/', '', $body);

                $xml .= '<item>' . "\n"
                      . '<title>' . htmlspecialchars($row['subject']). '</title>' . "\n";

		$xml .= '<link>' . $scripturl . '?topic=' . $row['ID_TOPIC'] . '.msg' . $row['ID_MSG'] . '#msg' . $row['ID_MSG'] . '</link>' . "\n";

		$xml .= '<ya:post>' . $scripturl . '?topic=' . $row['ID_TOPIC'] . '</ya:post>' . "\n";

                $xml .= '<guid isPermaLink="true">' . $scripturl . '?topic=' . $row['ID_TOPIC'] . '.msg' . $row['ID_MSG'] . '#msg' . $row['ID_MSG'] . '</guid>' . "\n"
                      . '<description>' . htmlspecialchars ($body) . '</description>' . "\n"
                      . '<pubDate>' . (date('r', $row['posterTime'])) . '</pubDate>' . "\n"
#                      . '<author>' . $scripturl . '?action=profile;u=' . $row['ID_MEMBER'] . '</author>' . "\n"
                      . '<dc:creator>' . htmlspecialchars($row['memberName']) . '</dc:creator>' . "\n"
                      . '</item>' . "\n";

                if ($modif == false) {
                    $modif = true;
                    header('Last-Modified: ' . gmdate("D, d M Y H:i:s", $row['posterTime']) . ' GMT'); # дата самого свежего сообщения
                }

            }
        }

        // листалка назад, если это не последняя страница
        if ($post != $paginationPost) {
            $xml .= '<ya:more>' . $boardurl . '/yarss.php?topic=' . $topic . '&amp;post=' . $paginationPost . '</ya:more>' . "\n";
        }

        $xml .= '</channel></rss>';

        header('Content-Type: text/xml; charset=' . $characterSet);
        echo $xml;
    }
}
// список всех RSS по умолчанию (yarss.php без параметров)
elseif (empty($forum)) {


    header('Content-Type: text/html; charset=' . $characterSet);

    $request = db_query('
        SELECT ID_BOARD, name, numTopics, numPosts
        FROM ' . $db_prefix . 'boards
        ' . ($botAccess ? 'WHERE (FIND_IN_SET(-1, memberGroups))' : '') . '
        ORDER BY boardOrder',
        __FILE__, __LINE__
    );

    echo '<html><head></head><meta http-equiv="Content-Type" content="text/html; charset=' . $characterSet . '" /><body><b>' . 'Список разрешенных к индексации форумов в RSS'  . ':</b> (<a href=' . $boardurl . '/yarss.php?mode=opml>opml</a>)';

    while ($row = mysql_fetch_assoc($request)) {
        echo '<p><a href="' . $boardurl . '/yarss.php?forum=' . $row['ID_BOARD'] . '">' . $row['name'] . '</a> <small title="' . 'топики/комменты' . '">' . $row['numTopics'] . '/' . $row['numPosts'];
        echo '</small></p>';
    }

    if ($botAccess) {
        echo '<p><b>Внимание</b>: В RSS выдаются только те форумы, в которых разрешено индексирование ("Характеристики и настройки" -> "Поисковые системы" -> "Настройки", "Назначить группу для пауков").</p>';
    }

    echo '<p>Теперь вы можете <a href="http://blogs.yandex.ru/add.xml">добавить</a> желаемые потоки в Яндекс.Поиск по блогам.</p>';

    echo '</body></html>';
}

else {
    // Проверяем, можно ли выдавать RSS из этого форума
    $request = db_query('
        SELECT name, memberGroups
        FROM ' . $db_prefix . 'boards
        WHERE ID_BOARD = ' . $forum . '
        ORDER BY boardOrder',
        __FILE__, __LINE__
    );
    $row = mysql_fetch_assoc($request);

    if (empty($row['name'])) {
        header('HTTP/1.0 404 Not Found');
        echo '<html><body>Этот форум не существует.</body></html>';
    }
    else {
        if ($botAccess) {
            $arMemberGroups = explode(',', $row['memberGroups']);

            if (!in_array('-1', $arMemberGroups)) {
                header('HTTP/1.0 404 Not Found');
                echo '<html><body>Этот форум не выдается в виде RSS.</body></html>';
                exit;
            }

            unset($arMemberGroups);
        }

        // шапка RSS
        $xml = '<?xml version="1.0" encoding="' . $characterSet . '"?>' . "\n"
             . '<rss version="2.0" xmlns:ya="http://blogs.yandex.ru/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/">' . "\n"
             . '<channel>' . "\n"
             . '<title>' . htmlspecialchars($row['name']) . ' — www.rock.ru</title>' . "\n"
             . '<link>' . $boardurl . '</link>' . "\n"
             . '<description>' . htmlspecialchars($row['name']) . '  — Российский рок-портал www.rock.ru</description>' . "\n"
             . '<language>ru</language>' . "\n"
             . '<managingEditor>rock@rock.ru(Aleksei &quot;rusty_angel&quot; Miheev)</managingEditor>' . "\n"
             . '<generator>Ya:Rss ' . $version . '</generator>' . "\n";

        // магический mysql-запрос, который все делает

        $where1 = '';
        $where2 = '';
        $order = 'tps.ID_TOPIC DESC, mes.ID_MSG DESC';

#        if (empty($mode)) {  # только первые посты/остальные посты
            $where1 = '=';
#        }
#        else {
#            $where1 = '<>';
#            $order  = 'mes.ID_MSG DESC';
#        }
        if ($topic != 0) { # листалка по тредам
            $where2 = 'AND tps.ID_TOPIC < "' . $topic . '"';
            $order  = 'tps.ID_TOPIC DESC';
        }
#        if ($post != 0 && $mode == 'comments') { # листалка по постам
#            $where2 = 'AND mes.ID_MSG < "' . $post . '"';
#            $order  = 'mes.ID_MSG DESC';
#        }

        $request = db_query('
            SELECT tps.*, mes.*, mem.realName AS memberName
            FROM   ' . $db_prefix . 'topics tps, ' . $db_prefix . 'messages mes, ' . $db_prefix . 'members mem
            WHERE  mes.ID_MEMBER = mem.ID_MEMBER
              AND  tps.ID_FIRST_MSG ' . $where1 . ' mes.ID_MSG
              AND  mes.ID_TOPIC = tps.ID_TOPIC
              AND  tps.ID_BOARD = "' . $forum . '" ' . $where2 . '

            ORDER BY ' . $order . ' LIMIT ' . $limit,
            __FILE__, __LINE__
        );

        // для листалки
        $paginationPost  = 0;
        $paginationTopic = 0;

        // <item>-ы
        if (mysql_num_rows($request) > 0) {
            $modif = false;

            loadServerAndBrowser();

            while ($row = mysql_fetch_assoc($request)) {
                $paginationPost  = $row['ID_MSG'];
                $paginationTopic = $row['ID_TOPIC'];

		parsecode($row['body']);
                $body = $row['body'];
                //$body = html_entity_decode($body);
                //$body = nl2br($body);
                //$body = preg_replace('/[\x00-\x08\x0B-\x0C\x0E-\x19]/', '', $body);

                $xml .= '<item>' . "\n"
                      . '<title>' . htmlspecialchars($row['subject'], ENT_QUOTES, 'UTF-8', false). '</title>' . "\n";

#                if ($mode != 'comments') {
                    $xml .= '<link>' . $scripturl . '?topic=' . $row['ID_TOPIC'] . '</link>' . "\n";
                    $xml .= '<guid isPermaLink="true">' . $scripturl . '?topic=' . $row['ID_TOPIC'] . '</guid>' . "\n";
#                }
#                else {
#                    $xml .= '<link>' . $scripturl . '?topic=' . $row['ID_TOPIC'] . '.msg' . $row['ID_MSG'] . '#msg' . $row['ID_MSG'] . '</link>' . "\n";
#                    $xml .= '<guid isPermaLink="true">' .$scripturl . '?topic=' . $row['ID_TOPIC'] . '.msg' . $row['ID_MSG'] . '#msg' . $row['ID_MSG'] . '</guid>' . "\n";
#                }

#                if ($mode == 'comments') {
#                    $xml .= '<ya:post>' . $scripturl . '?topic=' . $row['ID_TOPIC'] . '</ya:post>' . "\n";
#                }

#                $xml .= '<guid isPermaLink="true">' . $scripturl . '?topic=' . $row['ID_TOPIC'] . '</guid>' . "\n"
                 $xml .= '<description>' . htmlspecialchars ($body) . '</description>' . "\n"
                      . '<pubDate>' . (date('r', $row['posterTime'])) . '</pubDate>' . "\n"
#                      . '<author>' . $scripturl . '?action=profile;u=' . $row['ID_MEMBER'] . '</author>' . "\n"
                      . '<dc:creator>' . $row['memberName'] . '</dc:creator>' . "\n"
                      . '</item>' . "\n";

                if ($modif == false) {
                    $modif = true;
                    header('Last-Modified: ' . gmdate("D, d M Y H:i:s", $row['posterTime']) . ' GMT'); # дата самого свежего сообщения
                }

            }
        }

        // листалка назад, если это не последняя страница
        if ($post != $paginationPost && !empty($paginationTopic)) {
#           if ($mode != 'comments') {
                $xml .= '<ya:more>' . $boardurl . '/yarss.php?forum=' . $forum . '&amp;topic=' . $paginationTopic . '</ya:more>' . "\n";
#            }
#            else {
#                $xml .= '<ya:more>' . $boardurl . '/yarss.php?forum=' . $forum . '&amp;post=' . $paginationPost . '&amp;mode=' . $mode . '</ya:more>' . "\n";
#            }
        }

        // ссылка на фид с комментами
#        if ($mode != 'comments') {
#            $xml .= '<wfw:commentRss>' . $boardurl . '/yarss.php?forum=' . $forum . '&amp;mode=comments</wfw:commentRss>';
#        }

        $xml .= '</channel></rss>';

        header('Content-Type: text/xml; charset=' . $characterSet);
        echo $xml;
    }
}
?>
