Example #1
0
function sec_section_list($message = '')
{
    pagetop(gTxt('sections'), $message);
    global $wlink;
    $pageslist = safe_column("name", "txp_page", "1=1");
    $styleslist = safe_column("name", "txp_css", "1=1");
    $out[] = tr(tdcs(strong(gTxt('section_head')) . popHelp('section_category'), 3));
    $out[] = tr(tdcs(form(fInput('text', 'name', '', 'edit', '', '', 10) . fInput('submit', '', gTxt('Create'), 'smallerbox') . eInput('section') . sInput('section_create')), 3));
    $defrow = safe_row("page, css", "txp_section", "name like 'default'");
    $out[] = form(tr(td(gTxt('default')) . td(startTable('edit', 'left', '') . tr(fLabelCell(gTxt('uses_page') . ':') . td(selectInput('page', $pageslist, $defrow['page']) . popHelp('section_uses_page'), '', 'noline')) . tr(fLabelCell(gTxt('uses_style') . ':') . td(selectInput('css', $styleslist, $defrow['css']) . popHelp('section_uses_css'), '', 'noline')) . tr(tda(fInput('submit', '', gTxt('save_button'), 'smallerbox'), ' colspan="2" style="border:0"')) . endTable()) . td()) . eInput('section') . sInput('section_save') . hInput('name', 'default'));
    $rs = safe_rows_start("*", "txp_section", "name!='' order by name");
    if ($rs) {
        while ($a = nextRow($rs)) {
            extract($a);
            if ($name == 'default') {
                continue;
            }
            $deletelink = dLink('section', 'section_delete', 'name', $name, '', 'type', 'section');
            $form = startTable('edit') . stackRows(fLabelCell(gTxt('section_name') . ':') . fInputCell('name', $name, 1, 20), fLabelCell(gTxt('section_longtitle') . ':') . fInputCell('title', $title, 1, 20), fLabelCell(gTxt('uses_page') . ':') . td(selectInput('page', $pageslist, $page) . popHelp('section_uses_page'), '', 'noline'), fLabelCell(gTxt('uses_style') . ':') . td(selectInput('css', $styleslist, $css) . popHelp('section_uses_css'), '', 'noline'), fLabelCell(gTxt('selected_by_default') . '?') . td(yesnoradio('is_default', $is_default) . popHelp('section_is_default'), '', 'noline'), fLabelCell(gTxt('on_front_page') . '?') . td(yesnoradio('on_frontpage', $on_frontpage) . popHelp('section_on_frontpage'), '', 'noline'), fLabelCell(gTxt('syndicate') . '?') . td(yesnoradio('in_rss', $in_rss) . popHelp('section_syndicate'), '', 'noline'), fLabelCell(gTxt('include_in_search') . '?') . td(yesnoradio('searchable', $searchable) . popHelp('section_searchable'), '', 'noline'), tda(fInput('submit', '', gTxt('save_button'), 'smallerbox'), ' colspan="2" style="border:0"')) . endTable() . eInput('section') . sInput('section_save') . hInput('old_name', $name);
            $form = form($form);
            $out[] = tr(td($name) . td($form) . td($deletelink));
        }
    }
    echo startTable('list') . join('', $out) . endTable();
}
Example #2
0
/**
 * Renders a list of stylesheets.
 *
 * @param  string $current The active stylesheet
 * @param  string $default Not used
 * @return string HTML
 */
function css_list($current, $default)
{
    $out = array();
    $protected = safe_column('DISTINCT css', 'txp_section', '1=1');
    $criteria = 1;
    $criteria .= callback_event('admin_criteria', 'css_list', 0, $criteria);
    $rs = safe_rows_start('name', 'txp_css', $criteria);
    if ($rs) {
        while ($a = nextRow($rs)) {
            extract($a);
            $active = $current === $name;
            if ($active) {
                $edit = txpspecialchars($name);
            } else {
                $edit = eLink('css', '', 'name', $name, $name);
            }
            if (!array_key_exists($name, $protected)) {
                $edit .= dLink('css', 'css_delete', 'name', $name);
            }
            $out[] = tag(n . $edit . n, 'li', array('class' => $active ? 'active' : ''));
        }
        $out = tag(join(n, $out), 'ul', array('class' => 'switcher-list'));
        return wrapGroup('all_styles', $out, 'all_stylesheets');
    }
}
Example #3
0
function section_list($message = '')
{
    pagetop(gTxt('sections'), $message);
    global $url_mode, $txpac, $wlink;
    $out[] = tr(tdcs(strong(gTxt('section_head')) . popHelp('section_category'), 3));
    $out[] = tr(tdcs(form(fInput('text', 'name', '', 'edit', '', '', 10) . fInput('submit', '', gTxt('Create'), 'smallerbox') . eInput('section') . sInput('section_create')), 3));
    $pageslist = safe_column("name", "txp_page", "1");
    $styleslist = safe_column("name", "txp_css", "1");
    $rs = safe_rows("*", "txp_section", "name!='' order by name");
    if ($rs) {
        foreach ($rs as $a) {
            extract($a);
            if ($name == 'default') {
                continue;
            }
            if ($url_mode) {
                $wlink = !check_sections($name) ? sp . wLink('section', 'missing_section_file', 'name', $name) : '';
            }
            $deletelink = dLink('section', 'section_delete', 'name', $name, '', 'type', 'section');
            $form = startTable('edit') . stackRows(fLabelCell(gTxt('section_name') . ':') . fInputCell('name', $name, 1, 20), fLabelCell(gTxt('uses_page') . ':') . td(selectInput('page', $pageslist, $page) . popHelp('section_uses_page'), '', 'noline'), fLabelCell(gTxt('uses_style') . ':') . td(selectInput('css', $styleslist, $css) . popHelp('section_uses_css'), '', 'noline'), fLabelCell(gTxt('selected_by_default') . '?') . td(yesnoradio('is_default', $is_default) . popHelp('section_is_default'), '', 'noline'), fLabelCell(gTxt('on_front_page') . '?') . td(yesnoradio('on_frontpage', $on_frontpage) . popHelp('section_on_frontpage'), '', 'noline'), fLabelCell(gTxt('syndicate') . '?') . td(yesnoradio('in_rss', $in_rss) . popHelp('section_syndicate'), '', 'noline'), fLabelCell(gTxt('include_in_search') . '?') . td(yesnoradio('searchable', $searchable) . popHelp('section_searchable'), '', 'noline'), tda(fInput('submit', '', gTxt('save_button'), 'smallerbox'), ' colspan="2" style="border:0"')) . endTable() . eInput('section') . sInput('section_save') . hInput('old_name', $name);
            $form = form($form);
            $out[] = tr(td($name . $wlink) . td($form) . td($deletelink));
        }
    }
    echo startTable('list') . join('', $out) . endTable();
}
 /**
  * Constructor.
  *
  * @param mixed $value
  * @param array $options
  */
 public function __construct($value, $options = array())
 {
     static $choices = null;
     if (null === $choices) {
         $choices = safe_column('name', 'txp_section', '1=1');
     }
     $options['choices'] = $choices;
     $options['message'] = 'unknown_section';
     parent::__construct($value, $options);
 }
 /**
  * Constructor.
  *
  * @param mixed $value
  * @param array $options
  */
 public function __construct($value, $options = array())
 {
     static $choices = null;
     $options = lAtts(array('allow_blank' => true, 'type' => '', 'message' => 'unknown_form'), $options, false);
     if (null === $choices) {
         $choices = safe_column('name', 'txp_form', $options['type'] !== '' ? 'type=\'' . doSlash($options['type']) . '\'' : '1=1');
     }
     $options['choices'] = $choices;
     parent::__construct($value, $options);
 }
Example #6
0
function tree_rebuild($table, $parent, $left, $where = '1=1', $sortby = 'name')
{
    $right = $left + 1;
    $result = safe_column("id", $table, "parent='" . doSlash($parent) . "' and {$where} order by {$sortby}");
    foreach ($result as $row) {
        $right = tree_rebuild($table, $row, $right, $where, $sortby);
    }
    safe_update($table, "lft={$left}, rgt={$right}", "id='{$parent}' and {$where}");
    return $right + 1;
}
Example #7
0
function filterSearch()
{
    $rs = safe_column("name", "txp_section", "searchable != '1'");
    if ($rs) {
        foreach ($rs as $name) {
            $filters[] = "and Section != '" . doSlash($name) . "'";
        }
        return join(' ', $filters);
    }
    return false;
}
Example #8
0
function page_list($current)
{
    $protected = safe_column('DISTINCT page', 'txp_section', '1=1') + array('error_default');
    $rs = safe_rows_start('name', 'txp_page', "1 order by name asc");
    while ($a = nextRow($rs)) {
        extract($a);
        $link = eLink('page', '', 'name', $name, $name);
        $dlink = !in_array($name, $protected) ? dLink('page', 'page_delete', 'name', $name) : '';
        $out[] = $current == $name ? tr(td($name) . td($dlink)) : tr(td($link) . td($dlink));
    }
    return startTable('list') . join(n, $out) . endTable();
}
Example #9
0
/**
 * Generate a <select> element of installed languages.
 *
 * @param  string $name The HTML name and ID to assign to the select control
 * @param  string $val  The currently active language identifier (en-gb, fr-fr, ...)
 * @return string HTML
 */
function languages($name, $val)
{
    $installed_langs = safe_column("lang", 'txp_lang', "1 = 1 GROUP BY lang");
    $vals = array();
    foreach ($installed_langs as $lang) {
        $vals[$lang] = safe_field("data", 'txp_lang', "name = '" . doSlash($lang) . "' AND lang = '" . doSlash($lang) . "'");
        if (trim($vals[$lang]) == '') {
            $vals[$lang] = $lang;
        }
    }
    asort($vals);
    reset($vals);
    return selectInput($name, $vals, $val, false, true, $name);
}
Example #10
0
function page_list($current)
{
    $protected = safe_column('DISTINCT page', 'txp_section', '1=1') + array('error_default');
    $rs = safe_rows_start('name', 'txp_page', "1 order by name asc");
    $ctr = 1;
    while ($a = nextRow($rs)) {
        extract($a);
        $link = eLink('page', '', 'name', $name, $name);
        $dlink = !in_array($name, $protected) ? dLink('page', 'page_delete', 'name', $name) : '';
        $trcls = ' class="' . (($ctr == 1 ? 'first ' : '') . ($ctr % 2 == 0 ? 'even' : 'odd')) . '"';
        $out[] = $current == $name ? tr(td($name) . td($dlink), $trcls) : tr(td($link) . td($dlink), $trcls);
        $ctr++;
    }
    return startTable('list', '', 'list') . join(n, $out) . endTable();
}
Example #11
0
/**
 * Build a query qualifier to remove non-frontpage articles from the result set
 *
 * @return string A SQL qualifier for a querys 'WHERE' part
 */
function filterFrontPage()
{
    static $filterFrontPage;
    if (isset($filterFrontPage)) {
        return $filterFrontPage;
    }
    $filterFrontPage = false;
    $rs = safe_column('name', 'txp_section', "on_frontpage != '1'");
    if ($rs) {
        $filters = array();
        foreach ($rs as $name) {
            $filters[] = " and Section != '" . doSlash($name) . "'";
        }
        $filterFrontPage = join('', $filters);
    }
    return $filterFrontPage;
}
function sec_section_list($message = '')
{
    global $wlink;
    pagetop(gTxt('sections'), $message);
    $default = safe_row('page, css', 'txp_section', "name = 'default'");
    $pages = safe_column('name', 'txp_page', "1 = 1");
    $styles = safe_column('name', 'txp_css', "1 = 1");
    echo n . n . startTable('list') . n . n . tr(tda(n . n . hed(gTxt('section_head') . sp . popHelp('section_category'), 1) . n . n . form(fInput('text', 'name', '', 'edit', '', '', 10) . fInput('submit', '', gTxt('create'), 'smallerbox') . eInput('section') . sInput('section_create')), ' colspan="3"')) . n . n . tr(td(gTxt('default')) . td(form('<table>' . tr(fLabelCell(gTxt('uses_page') . ':') . td(selectInput('page', $pages, $default['page']) . sp . popHelp('section_uses_page'), '', 'noline')) . tr(fLabelCell(gTxt('uses_style') . ':') . td(selectInput('css', $styles, $default['css']) . sp . popHelp('section_uses_css'), '', 'noline')) . tr(tda(fInput('submit', '', gTxt('save_button'), 'smallerbox') . eInput('section') . sInput('section_save') . hInput('name', 'default'), ' colspan="2" class="noline"')) . endTable())) . td());
    $rs = safe_rows_start('*', 'txp_section', "name != 'default' order by name");
    if ($rs) {
        while ($a = nextRow($rs)) {
            extract($a);
            echo n . n . tr(n . td($name) . n . td(form('<table>' . n . n . tr(fLabelCell(gTxt('section_name') . ':') . fInputCell('name', $name, 1, 20)) . n . n . tr(fLabelCell(gTxt('section_longtitle') . ':') . fInputCell('title', $title, 1, 20)) . n . n . tr(fLabelCell(gTxt('uses_page') . ':') . td(selectInput('page', $pages, $page) . sp . popHelp('section_uses_page'), '', 'noline')) . n . n . tr(fLabelCell(gTxt('uses_style') . ':') . td(selectInput('css', $styles, $css) . sp . popHelp('section_uses_css'), '', 'noline')) . n . n . tr(fLabelCell(gTxt('selected_by_default')) . td(yesnoradio('is_default', $is_default, '', $name) . sp . popHelp('section_is_default'), '', 'noline')) . n . n . tr(fLabelCell(gTxt('on_front_page')) . td(yesnoradio('on_frontpage', $on_frontpage, '', $name) . sp . popHelp('section_on_frontpage'), '', 'noline')) . n . n . tr(fLabelCell(gTxt('syndicate')) . td(yesnoradio('in_rss', $in_rss, '', $name) . sp . popHelp('section_syndicate'), '', 'noline')) . n . n . tr(fLabelCell(gTxt('include_in_search')) . td(yesnoradio('searchable', $searchable, '', $name) . sp . popHelp('section_searchable'), '', 'noline')) . n . n . tr(tda(fInput('submit', '', gTxt('save_button'), 'smallerbox') . eInput('section') . sInput('section_save') . hInput('old_name', $name), ' colspan="2" class="noline"')) . endTable(), '', '', 'post', '', 'section-' . $name)) . td(dLink('section', 'section_delete', 'name', $name, '', 'type', 'section')), " id=\"section-{$name}\"");
        }
    }
    echo n . n . endTable();
}
Example #13
0
function css_list($current, $default)
{
    $out[] = startTable('', '', 'txp-list');
    $protected = safe_column('DISTINCT css', 'txp_section', '1=1');
    $criteria = 1;
    $criteria .= callback_event('admin_criteria', 'css_list', 0, $criteria);
    $rs = safe_rows_start('name', 'txp_css', $criteria);
    if ($rs) {
        while ($a = nextRow($rs)) {
            extract($a);
            $edit = $current != $name ? eLink('css', '', 'name', $name, $name) : txpspecialchars($name);
            $delete = !array_key_exists($name, $protected) ? dLink('css', 'css_delete', 'name', $name) : '';
            $out[] = tr(td($edit) . td($delete));
        }
        $out[] = endTable();
        return join('', $out);
    }
}
Example #14
0
function sec_section_list($message = '')
{
    global $wlink;
    pagetop(gTxt('sections'), $message);
    $default = safe_row('page, css', 'txp_section', "name = 'default'");
    $home = safe_row('page, css', 'txp_section', "name = 'home'");
    $pages = safe_column('name', 'txp_page', "1 = 1");
    $styles = safe_column('name', 'txp_css', "1 = 1");
    echo n . n . startTable('list') . n . n . tr(tda(n . n . hed(gTxt('section_head') . sp . popHelp('section_category'), 1) . n . n . form(fInput('text', 'name', '', 'edit', '', '', 10) . fInput('submit', '', gTxt('create'), 'smallerbox') . eInput('section') . sInput('section_create')), ' colspan="3"')) . n . n . tr(tda(gTxt('home'), ' onclick="toggleDisplay(\'section_home\'); return false;"') . td(form('<table id="section_home">' . tr(fLabelCell(gTxt('uses_page') . ':') . td(selectInput('page', $pages, $home['page']) . sp . popHelp('section_uses_page'), '', 'noline')) . tr(fLabelCell(gTxt('uses_style') . ':') . td(selectInput('css', $styles, $home['css']) . sp . popHelp('section_uses_css'), '', 'noline')) . pluggable_ui('section_ui', 'extend_detail_form', '', $home) . tr(tda(fInput('submit', '', gTxt('save_button'), 'smallerbox') . eInput('section') . sInput('section_save') . hInput('name', 'home'), ' colspan="2" class="noline"')) . endTable())) . td()) . n . n . tr(tda(gTxt('default'), ' onclick="toggleDisplay(\'section_default\'); return false;"') . td(form('<table id="section_default">' . tr(fLabelCell(gTxt('uses_page') . ':') . td(selectInput('page', $pages, $default['page']) . sp . popHelp('section_uses_page'), '', 'noline')) . tr(fLabelCell(gTxt('uses_style') . ':') . td(selectInput('css', $styles, $default['css']) . sp . popHelp('section_uses_css'), '', 'noline')) . pluggable_ui('section_ui', 'extend_detail_form', '', $default) . tr(tda(fInput('submit', '', gTxt('save_button'), 'smallerbox') . eInput('section') . sInput('section_save') . hInput('name', 'default'), ' colspan="2" class="noline"')) . endTable())) . td());
    $rs = safe_rows_start('*', 'txp_section', "name != 'default' AND name != 'home' order by name");
    if ($rs) {
        while ($a = nextRow($rs)) {
            extract($a);
            echo n . n . tr(n . tda($name, ' onclick="toggleDisplay(\'section_' . $name . '\'); return false;"') . n . td(form('<table id="section_' . $name . '">' . n . n . tr(fLabelCell(gTxt('section_name') . ':') . fInputCell('name', $name, 1, 20)) . n . n . tr(fLabelCell(gTxt('section_longtitle') . ':') . fInputCell('title', $title, 1, 20)) . n . n . tr(fLabelCell(gTxt('uses_page') . ':') . td(selectInput('page', $pages, $page) . sp . popHelp('section_uses_page'), '', 'noline')) . n . n . tr(fLabelCell(gTxt('uses_style') . ':') . td(selectInput('css', $styles, $css) . sp . popHelp('section_uses_css'), '', 'noline')) . n . n . tr(fLabelCell(gTxt('selected_by_default')) . td(yesnoradio('is_default', $is_default, '', $name) . sp . popHelp('section_is_default'), '', 'noline')) . n . n . tr(fLabelCell(gTxt('on_front_page')) . td(yesnoradio('on_frontpage', $on_frontpage, '', $name) . sp . popHelp('section_on_frontpage'), '', 'noline')) . n . n . tr(fLabelCell(gTxt('syndicate')) . td(yesnoradio('in_rss', $in_rss, '', $name) . sp . popHelp('section_syndicate'), '', 'noline')) . n . n . tr(fLabelCell(gTxt('include_in_search')) . td(yesnoradio('searchable', $searchable, '', $name) . sp . popHelp('section_searchable'), '', 'noline')) . n . n . tr(fLabelCell(gTxt('section_descr') . ':') . fTextCell('descr', $descr, 1, 4, 20)) . n . n . tr(fLabelCell(gTxt('section_metakey') . ':') . fInputCell('metakey', $metakey, 1, 20)) . n . n . tr(fLabelCell(gTxt('section_metadesc') . ':') . fTextCell('metadesc', $metadesc, 1, 4, 20)) . pluggable_ui('section_ui', 'extend_detail_form', '', $a) . n . n . tr(tda(fInput('submit', '', gTxt('save_button'), 'smallerbox') . eInput('section') . sInput('section_save') . hInput('old_name', $name), ' colspan="2" class="noline"')) . endTable(), '', '', 'post', '', 'section-' . $name)) . td(dLink('section', 'section_delete', 'name', $name, '', 'type', 'section')), " id=\"section-{$name}\" class=\"jsection\" ");
        }
    }
    echo n . n . endTable();
}
Example #15
0
function sec_section_list($message = '')
{
    global $wlink, $event;
    pagetop(gTxt('sections'), $message);
    $default = safe_row('page, css', 'txp_section', "name = 'default'");
    $pages = safe_column('name', 'txp_page', "1 = 1");
    $styles = safe_column('name', 'txp_css', "1 = 1");
    echo n . '<div id="' . $event . '_container" class="txp-container txp-list">';
    echo n . n . startTable('list') . n . n . tr(tda(n . n . hed(gTxt('section_head') . sp . popHelp('section_category'), 2) . n . '<div id="' . $event . '_control" class="txp-control-panel">' . n . n . form(fInput('text', 'name', '', 'edit', '', '', 10) . fInput('submit', '', gTxt('create'), 'smallerbox') . eInput('section') . sInput('section_create'), '', '', 'post', 'edit-form', '', 'section_create') . n . '</div>', ' colspan="3"')) . n . n . tr(td(gTxt('default'), '', 'label') . td(form('<table>' . tr(fLabelCell(gTxt('uses_page') . ':') . td(selectInput('page', $pages, $default['page']) . sp . popHelp('section_uses_page'), '', 'noline'), ' class="uses-page"') . tr(fLabelCell(gTxt('uses_style') . ':') . td(selectInput('css', $styles, $default['css']) . sp . popHelp('section_uses_css'), '', 'noline'), ' class="uses-style"') . pluggable_ui('section_ui', 'extend_detail_form', '', $default) . tr(tda(fInput('submit', '', gTxt('save_button'), 'smallerbox') . eInput('section') . sInput('section_save') . hInput('name', 'default'), ' colspan="2" class="noline"')) . endTable())) . td(), ' class="section default"');
    $rs = safe_rows_start('*', 'txp_section', "name != 'default' order by name");
    if ($rs) {
        $ctr = 1;
        while ($a = nextRow($rs)) {
            extract($a);
            echo n . n . tr(n . td($name, '', 'label') . n . td(form('<table>' . n . n . tr(fLabelCell(gTxt('section_name') . ':') . fInputCell('name', $name, 1, 20), ' class="name"') . n . n . tr(fLabelCell(gTxt('section_longtitle') . ':') . fInputCell('title', $title, 1, 20), ' class="title"') . n . n . tr(fLabelCell(gTxt('uses_page') . ':') . td(selectInput('page', $pages, $page) . sp . popHelp('section_uses_page'), '', 'noline'), ' class="uses-page"') . n . n . tr(fLabelCell(gTxt('uses_style') . ':') . td(selectInput('css', $styles, $css) . sp . popHelp('section_uses_css'), '', 'noline'), ' class="uses-style"') . n . n . tr(fLabelCell(gTxt('selected_by_default')) . td(yesnoradio('is_default', $is_default, '', $name) . sp . popHelp('section_is_default'), '', 'noline'), ' class="option is-default"') . n . n . tr(fLabelCell(gTxt('on_front_page')) . td(yesnoradio('on_frontpage', $on_frontpage, '', $name) . sp . popHelp('section_on_frontpage'), '', 'noline'), ' class="option on-frontpage"') . n . n . tr(fLabelCell(gTxt('syndicate')) . td(yesnoradio('in_rss', $in_rss, '', $name) . sp . popHelp('section_syndicate'), '', 'noline'), ' class="option in-rss"') . n . n . tr(fLabelCell(gTxt('include_in_search')) . td(yesnoradio('searchable', $searchable, '', $name) . sp . popHelp('section_searchable'), '', 'noline'), ' class="option is-searchable"') . pluggable_ui('section_ui', 'extend_detail_form', '', $a) . n . n . tr(tda(fInput('submit', '', gTxt('save_button'), 'smallerbox') . eInput('section') . sInput('section_save') . hInput('old_name', $name), ' colspan="2" class="noline"')) . endTable(), '', '', 'post', '', 'section-' . $name), '', 'main') . td(dLink('section', 'section_delete', 'name', $name, '', 'type', 'section'), '', 'actions'), ' id="section-' . $name . '" class="section ' . ($ctr % 2 == 0 ? 'even' : 'odd') . '"');
            $ctr++;
        }
    }
    echo n . n . endTable() . '</div>';
}
Example #16
0
function feed($type)
{
    global $prefs;
    set_error_handler('feedErrorHandler');
    ob_clean();
    extract($prefs);
    extract(doSlash(gpsa(array('category', 'section', 'limit', 'area'))));
    if ($area != 'link') {
        $area = 'article';
    }
    $sitename .= $section ? ' - ' . fetch_section_title($section) : '';
    $sitename .= $category ? ' - ' . fetch_category_title($category, $area) : '';
    $self_ref = pagelinkurl(array('atom' => 1, 'area' => $area == 'article' ? '' : $area, 'section' => $section, 'category' => $category, 'limit' => $limit));
    $id_ext = ($section ? '/' . $section : '') . ($category ? '/' . $category : '');
    if ($area == 'article') {
        $sfilter = $section ? "and Section = '" . $section . "'" : '';
        $cfilter = $category ? "and (Category1='" . $category . "' or Category2='" . $category . "')" : '';
        $limit = $limit ? $limit : $rss_how_many;
        $limit = intval(min($limit, max(100, $rss_how_many)));
        $frs = safe_column("name", "txp_section", "in_rss != '1'");
        $query = array();
        foreach ($frs as $f) {
            $query[] = "and Section != '" . doSlash($f) . "'";
        }
        $query[] = $sfilter;
        $query[] = $cfilter;
        $expired = $publish_expired_articles ? '' : ' and (now() <= Expires or Expires = ' . NULLDATETIME . ') ';
        $rs = safe_rows_start("*, ID as thisid, unix_timestamp(Posted) as uPosted, unix_timestamp(Expires) as uExpires, unix_timestamp(LastMod) as uLastMod", "textpattern", "Status=4 and Posted <= now() {$expired}" . join(' ', $query) . "order by Posted desc limit {$limit}");
        return render_feed($rs, $area, $type, $sitename, $self_ref, $id_ext);
    } elseif ($area == 'link') {
        $cfilter = $category ? "category='" . $category . "'" : '1';
        $limit = $limit ? $limit : $rss_how_many;
        $limit = intval(min($limit, max(100, $rss_how_many)));
        $rs = safe_rows_start("*" . ($atom ? '' : ", unix_timestamp(date) as uDate"), "txp_link", "{$cfilter} order by date desc" . ($atom ? ", id desc" : '') . " limit {$limit}");
        return render_feed($rs, $area, $type, $sitename, $self_ref, $id_ext);
    }
}
Example #17
0
function atom()
{
    global $thisarticle;
    extract($GLOBALS['prefs']);
    define("t_texthtml", ' type="text/html"');
    define("t_text", ' type="text"');
    define("t_html", ' type="html"');
    define("t_xhtml", ' type="xhtml"');
    define('t_appxhtml', ' type="xhtml"');
    define("r_relalt", ' rel="alternate"');
    define("r_relself", ' rel="self"');
    $area = doSlash(gps('area'));
    extract(doSlash(gpsa(array('category', 'section', 'limit'))));
    $last = fetch('unix_timestamp(val)', 'txp_prefs', 'name', 'lastmod');
    $sitename .= $section ? ' - ' . $section : '';
    $sitename .= $category ? ' - ' . $category : '';
    $pub = safe_row("RealName, email", "txp_users", "privs=1");
    $out[] = tag(escape_output($sitename), 'title', t_text);
    $out[] = tag(escape_output($site_slogan), 'subtitle', t_text);
    $out[] = '<link' . r_relself . ' href="' . pagelinkurl(array('atom' => 1, 'area' => $area, 'section' => $section, 'category' => $category, 'limit' => $limit)) . '" />';
    $out[] = '<link' . r_relalt . t_texthtml . ' href="' . hu . '" />';
    $articles = array();
    //Atom feeds with mail or domain name
    $dn = explode('/', $siteurl);
    $mail_or_domain = $use_mail_on_feeds_id ? eE($blog_mail_uid) : $dn[0];
    $out[] = tag('tag:' . $mail_or_domain . ',' . $blog_time_uid . ':' . $blog_uid . ($section ? '/' . $section : '') . ($category ? '/' . $category : ''), 'id');
    $out[] = tag('Textpattern', 'generator', ' uri="http://textpattern.com/" version="' . $version . '"');
    $out[] = tag(safe_strftime("w3cdtf", $last), 'updated');
    $auth[] = tag($pub['RealName'], 'name');
    $auth[] = $include_email_atom ? tag(eE($pub['email']), 'email') : '';
    $auth[] = tag(hu, 'uri');
    $out[] = tag(n . t . t . join(n . t . t, $auth) . n, 'author');
    if (!$area or $area == 'article') {
        $sfilter = $section ? "and Section = '" . $section . "'" : '';
        $cfilter = $category ? "and (Category1='" . $category . "' or Category2='" . $category . "')" : '';
        $limit = $limit ? $limit : $rss_how_many;
        $limit = intval(min($limit, max(100, $rss_how_many)));
        $frs = safe_column("name", "txp_section", "in_rss != '1'");
        $query = array();
        foreach ($frs as $f) {
            $query[] = "and Section != '" . doSlash($f) . "'";
        }
        $query[] = $sfilter;
        $query[] = $cfilter;
        $rs = safe_rows_start("*, \n\t\t\t\tID as thisid, \n\t\t\t\tunix_timestamp(Posted) as uPosted,\n\t\t\t\tunix_timestamp(LastMod) as uLastMod", "textpattern", "Status=4 and Posted <= now() " . join(' ', $query) . "order by Posted desc limit {$limit}");
        if ($rs) {
            while ($a = nextRow($rs)) {
                extract($a);
                populateArticleData($a);
                $cb = callback_event('atom_entry');
                $e = array();
                $a['posted'] = $uPosted;
                if ($show_comment_count_in_feed) {
                    $count = $comments_count > 0 ? ' [' . $comments_count . ']' : '';
                } else {
                    $count = '';
                }
                $thisauthor = get_author_name($AuthorID);
                $e['thisauthor'] = tag(n . t . t . t . tag(htmlspecialchars($thisauthor), 'name') . n . t . t, 'author');
                $e['issued'] = tag(safe_strftime('w3cdtf', $uPosted), 'published');
                $e['modified'] = tag(safe_strftime('w3cdtf', $uLastMod), 'updated');
                $escaped_title = escape_output($Title);
                $e['title'] = tag($escaped_title . $count, 'title', t_html);
                $permlink = permlinkurl($a);
                $e['link'] = '<link' . r_relalt . t_texthtml . ' href="' . $permlink . '" />';
                $e['id'] = tag('tag:' . $mail_or_domain . ',' . $feed_time . ':' . $blog_uid . '/' . $uid, 'id');
                $e['category1'] = trim($Category1) ? '<category term="' . htmlspecialchars($Category1) . '" />' : '';
                $e['category2'] = trim($Category2) ? '<category term="' . htmlspecialchars($Category2) . '" />' : '';
                $summary = trim(replace_relative_urls(parse($thisarticle['excerpt']), $permlink));
                $content = trim(replace_relative_urls(parse($thisarticle['body']), $permlink));
                if ($syndicate_body_or_excerpt) {
                    # short feed: use body as summary if there's no excerpt
                    if (!trim($summary)) {
                        $summary = $content;
                    }
                    $content = '';
                }
                if (trim($content)) {
                    $e['content'] = tag(n . escape_cdata($content) . n, 'content', t_html);
                }
                if (trim($summary)) {
                    $e['summary'] = tag(n . escape_cdata($summary) . n, 'summary', t_html);
                }
                $articles[$ID] = tag(n . t . t . join(n . t . t, $e) . n . $cb, 'entry');
                $etags[$ID] = strtoupper(dechex(crc32($articles[$ID])));
                $dates[$ID] = $uLastMod;
            }
        }
    } elseif ($area == 'link') {
        $cfilter = $category ? "category='" . $category . "'" : '1';
        $limit = $limit ? $limit : $rss_how_many;
        $limit = intval(min($limit, max(100, $rss_how_many)));
        $rs = safe_rows_start("*", "txp_link", "{$cfilter} order by date desc, id desc limit {$limit}");
        if ($rs) {
            while ($a = nextRow($rs)) {
                extract($a);
                $e['title'] = tag(htmlspecialchars($linkname), 'title', t_html);
                $e['content'] = tag(n . htmlspecialchars($description) . n, 'content', t_html);
                $url = preg_replace("/^\\/(.*)/", "https?://{$siteurl}/\$1", $url);
                $url = preg_replace("/&((?U).*)=/", "&amp;\\1=", $url);
                $e['link'] = '<link' . r_relalt . t_texthtml . ' href="' . $url . '" />';
                $e['issued'] = tag(safe_strftime('w3cdtf', strtotime($date)), 'published');
                $e['modified'] = tag(gmdate('Y-m-d\\TH:i:s\\Z', strtotime($date)), 'updated');
                $e['id'] = tag('tag:' . $mail_or_domain . ',' . $feed_time . ':' . $id, 'id');
                $articles[$id] = tag(n . t . t . join(n . t . t, $e) . n, 'entry');
                $etags[$id] = strtoupper(dechex(crc32($articles[$id])));
                $dates[$id] = $date;
            }
        }
    }
    if (!empty($articles)) {
        //turn on compression if we aren't using it already
        if (extension_loaded('zlib') && ini_get("zlib.output_compression") == 0 && ini_get('output_handler') != 'ob_gzhandler' && !headers_sent()) {
            @ob_start("ob_gzhandler");
        }
        handle_lastmod();
        $hims = serverset('HTTP_IF_MODIFIED_SINCE');
        $imsd = $hims ? strtotime($hims) : 0;
        if ($imsd >= $last) {
            txp_status_header("304 Not Modified");
            exit;
        }
        header("Last-Modified: " . gmdate('D, d M Y H:i:s \\G\\M\\T', $last));
        if (is_callable('apache_request_headers')) {
            $headers = apache_request_headers();
            if (isset($headers["A-IM"])) {
                $canaim = strpos($headers["A-IM"], "feed");
            } else {
                $canaim = false;
            }
        } else {
            $canaim = false;
        }
        $hinm = stripslashes(serverset('HTTP_IF_NONE_MATCH'));
        $cutarticles = false;
        if ($canaim !== false) {
            foreach ($articles as $id => $thing) {
                if (strpos($hinm, $etags[$id])) {
                    unset($articles[$id]);
                    $cutarticles = true;
                    $cut_etag = true;
                }
                if ($dates[$id] < $imsd) {
                    unset($articles[$id]);
                    $cutarticles = true;
                    $cut_time = true;
                }
            }
        }
        if (isset($cut_etag) && isset($cut_time)) {
            header("Vary: If-None-Match, If-Modified-Since");
        } else {
            if (isset($cut_etag)) {
                header("Vary: If-None-Match");
            } else {
                if (isset($cut_time)) {
                    header("Vary: If-Modified-Since");
                }
            }
        }
        $etag = @join("-", $etags);
        if (strstr($hinm, $etag)) {
            header("HTTP/1.1 304 Not Modified");
            exit;
        }
        if ($etag) {
            header('ETag: "' . $etag . '"');
        }
        if ($cutarticles) {
            //header("HTTP/1.1 226 IM Used");
            //This should be used as opposed to 200, but Apache doesn't like it.
            //http://intertwingly.net/blog/2004/09/11/Vary-ETag/ says that the status code should be 200.
            header("Cache-Control: no-store, im");
            header("IM: feed");
        }
        $out = array_merge($out, $articles);
        header('Content-type: application/atom+xml; charset=utf-8');
        return chr(60) . '?xml version="1.0" encoding="UTF-8"?' . chr(62) . n . '<feed xml:lang="' . $language . '" xmlns="http://www.w3.org/2005/Atom">' . join(n, $out) . '</feed>';
    }
}
Example #18
0
safe_update('txp_form', "Form = REPLACE(Form, '<txp:message', '<txp:comment_message')", "1 = 1");
// Expiry datetime for articles
safe_upgrade_table('textpattern', array('Expires' => "datetime NOT NULL default '0000-00-00 00:00:00' after `Posted`"));
if (!safe_field('name', 'txp_prefs', "name = 'publish_expired_articles'")) {
    safe_insert('txp_prefs', "prefs_id = 1, name = 'publish_expired_articles', val = '0', type = '1', event='publish', html='yesnoradio', position='130'");
}
/*
 * @todo determine section:article relation key
 */
// populate section_id values
// foreach (safe_rows('id, name', 'txp_section', '1=1') as $row) {
//	safe_update('textpattern', "section_id='".doSlash($row['id'])."'", "Section='".doSlash($row['name'])."'");
//}
// fix up the parent field in txp_category
safe_query("alter ignore table " . safe_pfx('txp_category') . " modify parent INT not null");
$types = safe_column('distinct type', 'txp_category', '1=1');
foreach ($types as $type) {
    $root = safe_field('id', 'txp_category', "type='" . doSlash($type) . "' and name='root' and parent=0");
    if (!$root) {
        $root = safe_insert('txp_category', "name='root', type='" . doSlash($type) . "', parent=0");
    }
    safe_update('txp_category', "parent='" . $root . "'", "type='" . doSlash($type) . "' and parent=0 and id != '" . $root . "'");
    tree_rebuild_full('txp_category', "type='" . doSlash($type) . "'");
}
// index on form type
safe_upgrade_index('txp_form', 'type_idx', '', 'type');
// dropdown ui for certain prefs
safe_upgrade_table('txp_prefs', array('choices' => 'varchar(64)'));
safe_update('txp_prefs', "html='checkbox'", "html='yesnoradio'");
safe_update('txp_prefs', "html='text'", "html='text_input'");
safe_update('txp_prefs', "choices='commentmode', html='select'", "html='commentmode'");
Example #19
0
function doDiagnostics()
{
    global $files, $txpcfg, $step;
    extract(get_prefs());
    $urlparts = parse_url(hu);
    $mydomain = $urlparts['host'];
    $server_software = @$_SERVER['SERVER_SOFTWARE'] || @$_SERVER['HTTP_HOST'] ? @$_SERVER['SERVER_SOFTWARE'] ? @$_SERVER['SERVER_SOFTWARE'] : $_SERVER['HTTP_HOST'] : '';
    $is_apache = ($server_software and stristr($server_software, 'Apache')) or is_callable('apache_get_version');
    $real_doc_root = isset($_SERVER['DOCUMENT_ROOT']) ? realpath($_SERVER['DOCUMENT_ROOT']) : '';
    // ini_get() returns string values passed via php_value as a string, not boolean
    $is_register_globals = (strcasecmp(ini_get('register_globals'), 'on') === 0 or ini_get('register_globals') === '1');
    $fail = array('path_to_site_missing' => !isset($path_to_site) ? gTxt('path_to_site_missing') : '', 'dns_lookup_fails' => @gethostbyname($mydomain) == $mydomain ? gTxt('dns_lookup_fails') . cs . $mydomain : '', 'path_to_site_inacc' => !@is_dir($path_to_site) ? gTxt('path_to_site_inacc') . cs . $path_to_site : '', 'site_trailing_slash' => rtrim($siteurl, '/') != $siteurl ? gTxt('site_trailing_slash') . cs . $path_to_site : '', 'index_inaccessible' => (!@is_file($path_to_site . "/index.php") or !@is_readable($path_to_site . "/index.php")) ? "{$path_to_site}/index.php " . gTxt('is_inaccessible') : '', 'dir_not_writable' => trim((!@is_writable($path_to_site . '/' . $img_dir) ? str_replace('{dirtype}', gTxt('img_dir'), gTxt('dir_not_writable')) . ": {$path_to_site}/{$img_dir}\r\n" : '') . (!@is_writable($file_base_path) ? str_replace('{dirtype}', gTxt('file_base_path'), gTxt('dir_not_writable')) . ": {$file_base_path}\r\n" : '') . (!@is_writable($tempdir) ? str_replace('{dirtype}', gTxt('tempdir'), gTxt('dir_not_writable')) . ": {$tempdir}\r\n" : '')), 'cleanurl_only_apache' => ($permlink_mode != 'messy' and !$is_apache) ? gTxt('cleanurl_only_apache') : '', 'htaccess_missing' => ($permlink_mode != 'messy' and !@is_readable($path_to_site . '/.htaccess')) ? gTxt('htaccess_missing') : '', 'mod_rewrite_missing' => ($permlink_mode != 'messy' and is_callable('apache_get_modules') and !apache_module('mod_rewrite')) ? gTxt('mod_rewrite_missing') : '', 'file_uploads_disabled' => !ini_get('file_uploads') ? gTxt('file_uploads_disabled') : '', 'setup_still_exists' => @is_dir($txpcfg['txpath'] . DS . 'setup') ? $txpcfg['txpath'] . DS . "setup" . DS . ' ' . gTxt('still_exists') : '', 'no_temp_dir' => empty($tempdir) ? gTxt('no_temp_dir') : '', 'warn_mail_unavailable' => !is_callable('mail') ? gTxt('warn_mail_unavailable') : '', 'warn_register_globals_or_update' => $is_register_globals && (version_compare(phpversion(), '4.4.0', '<=') or version_compare(phpversion(), '5.0.0', '>=') and version_compare(phpversion(), '5.0.5', '<=')) ? gTxt('warn_register_globals_or_update') : '');
    if ($permlink_mode != 'messy') {
        $rs = safe_column("name", "txp_section", "1");
        foreach ($rs as $name) {
            if (@file_exists($path_to_site . '/' . $name)) {
                $fail['old_placeholder_exists'] = gTxt('old_placeholder') . ": {$path_to_site}/{$name}";
            }
        }
    }
    $missing = array();
    foreach ($files as $f) {
        if (!is_readable($txpcfg['txpath'] . $f)) {
            $missing[] = $txpcfg['txpath'] . $f;
        }
    }
    if ($missing) {
        $fail['missing_files'] = gTxt('missing_files') . cs . join(', ', $missing);
    }
    foreach ($fail as $k => $v) {
        if (empty($v)) {
            unset($fail[$k]);
        }
    }
    # Find the highest revision number
    $file_revs = array();
    $rev = 0;
    foreach ($files as $f) {
        $lines = @file($txpcfg['txpath'] . $f);
        if ($lines) {
            foreach ($lines as $line) {
                if (preg_match('/^\\$LastChangedRevision: (\\w+) \\$/', $line, $match)) {
                    $file_revs[$f] = $match[1];
                    if ($match[1] > $rev) {
                        $rev = $match[1];
                    }
                }
            }
        }
    }
    echo pagetop(gTxt('tab_diagnostics'), ''), startTable('list'), tr(td(hed(gTxt('preflight_check'), 1)));
    if ($fail) {
        foreach ($fail as $help => $message) {
            echo tr(tda(nl2br($message) . popHelp($help), ' style="color:red;"'));
        }
    } else {
        echo tr(td(gTxt('all_checks_passed')));
    }
    echo tr(td(hed(gTxt('diagnostic_info'), 1)));
    $fmt_date = '%Y-%m-%d %H:%M:%S';
    $out = array('<textarea style="width:500px;height:300px;" readonly="readonly">', gTxt('txp_version') . cs . txp_version . ' (' . ($rev ? 'r' . $rev : 'unknown revision') . ')' . n, gTxt('last_update') . cs . gmstrftime($fmt_date, $dbupdatetime) . '/' . gmstrftime($fmt_date, @filemtime(txpath . '/update/_update.php')) . n, gTxt('document_root') . cs . @$_SERVER['DOCUMENT_ROOT'] . ($real_doc_root != @$_SERVER['DOCUMENT_ROOT'] ? ' (' . $real_doc_root . ')' : '') . n, '$path_to_site' . cs . $path_to_site . n, gTxt('txp_path') . cs . $txpcfg['txpath'] . n, gTxt('permlink_mode') . cs . $permlink_mode . n, ini_get('open_basedir') ? 'open_basedir: ' . ini_get('open_basedir') . n : '', ini_get('upload_tmp_dir') ? 'upload_tmp_dir: ' . ini_get('upload_tmp_dir') . n : '', gTxt('tempdir') . cs . $tempdir . n, gTxt('web_domain') . cs . $siteurl . n, getenv('TZ') ? 'TZ: ' . getenv('TZ') . n : '', gTxt('php_version') . cs . phpversion() . n, $is_register_globals ? gTxt('register_globals') . cs . $is_register_globals . n : '', gTxt('server_time') . cs . strftime('%Y-%m-%d %H:%M:%S') . n, 'MySQL' . cs . mysql_get_server_info() . n, gTxt('locale') . cs . $locale . n, isset($_SERVER['SERVER_SOFTWARE']) ? gTxt('server') . cs . $_SERVER['SERVER_SOFTWARE'] . n : '', is_callable('apache_get_version') ? gTxt('apache_version') . cs . apache_get_version() . n : '', $fail ? n . gTxt('preflight_check') . cs . n . ln . join("\n", $fail) . n . ln : '', is_readable($path_to_site . '/.htaccess') ? n . gTxt('htaccess_contents') . cs . n . ln . join('', file($path_to_site . '/.htaccess')) . n . ln : '');
    if ($step == 'high') {
        $mysql_client_encoding = is_callable('mysql_client_encoding') ? mysql_client_encoding() : '-';
        $out[] = n . 'Charset (default/config)' . cs . $mysql_client_encoding . '/' . @$txpcfg['dbcharset'] . n;
        $result = safe_query("SHOW variables like 'character_se%'");
        while ($row = mysql_fetch_row($result)) {
            $out[] = $row[0] . cs . $row[1] . n;
            if ($row[0] == 'character_set_connection') {
                $conn_char = $row[1];
            }
        }
        $table_names = array(PFX . 'textpattern');
        $result = safe_query("SHOW TABLES LIKE '" . PFX . "txp\\_%'");
        while ($row = mysql_fetch_row($result)) {
            $table_names[] = $row[0];
        }
        $table_msg = array();
        foreach ($table_names as $table) {
            $ctr = safe_query("SHOW CREATE TABLE " . $table . "");
            if (!$ctr) {
                unset($table_names[$table]);
                continue;
            }
            $ctcharset = preg_replace('#^CREATE TABLE.*SET=([^ ]+)[^)]*$#is', '\\1', mysql_result($ctr, 0, 'Create Table'));
            if (isset($conn_char) && !stristr($ctcharset, 'CREATE') && $conn_char != $ctcharset) {
                $table_msg[] = "{$table} is {$ctcharset}";
            }
            $ctr = safe_query("CHECK TABLE " . $table);
            if (in_array(mysql_result($ctr, 0, 'Msg_type'), array('error', 'warning'))) {
                $table_msg[] = $table . cs . mysql_result($ctr, 0, 'Msg_Text');
            }
        }
        if ($table_msg == array()) {
            $table_msg = count($table_names) < 18 ? array('-') : array('OK');
        }
        $out[] = count($table_names) . ' Tables' . cs . implode(', ', $table_msg) . n;
        $extns = get_loaded_extensions();
        $extv = array();
        foreach ($extns as $e) {
            $extv[] = $e . (phpversion($e) ? '/' . phpversion($e) : '');
        }
        $out[] = n . gTxt('php_extensions') . cs . join(', ', $extv) . n;
        if (is_callable('apache_get_modules')) {
            $out[] = n . gTxt('apache_modules') . cs . join(', ', apache_get_modules()) . n . n;
        }
        foreach ($files as $f) {
            $rev = '';
            $checksum = '';
            if (is_callable('md5_file')) {
                $checksum = md5_file($txpcfg['txpath'] . $f);
            }
            if (isset($file_revs[$f])) {
                $rev = $file_revs[$f];
            }
            $out[] = "{$f}" . cs . ($rev ? "r" . $rev : gTxt('unknown')) . ' (' . ($checksum ? $checksum : gTxt('unknown')) . ')' . n;
        }
    }
    $out[] = '</textarea>' . br;
    $dets = array('low' => gTxt('low'), 'high' => gTxt('high'));
    $out[] = form(eInput('diag') . n . gTxt('detail') . cs . selectInput('step', $dets, $step, 0, 1));
    echo tr(td(join('', $out))), endTable();
}
Example #20
0
function rss()
{
    global $prefs, $thisarticle;
    set_error_handler('feedErrorHandler');
    ob_clean();
    extract($prefs);
    extract(doSlash(gpsa(array('limit', 'area'))));
    // build filter criteria from a comma-separated list of sections and categories
    $feed_filter_limit = get_pref('feed_filter_limit', 10);
    $section = gps('section');
    $category = gps('category');
    if (!is_scalar($section) || !is_scalar($category)) {
        txp_die('Not Found', 404);
    }
    $section = $section ? array_slice(array_unique(do_list($section)), 0, $feed_filter_limit) : array();
    $category = $category ? array_slice(array_unique(do_list($category)), 0, $feed_filter_limit) : array();
    $st = array();
    foreach ($section as $s) {
        $st[] = fetch_section_title($s);
    }
    $ct = array();
    foreach ($category as $c) {
        $ct[] = fetch_category_title($c);
    }
    $sitename .= $section ? ' - ' . join(' - ', $st) : '';
    $sitename .= $category ? ' - ' . join(' - ', $ct) : '';
    $dn = explode('/', $siteurl);
    $mail_or_domain = $use_mail_on_feeds_id ? eE($blog_mail_uid) : $dn[0];
    // feed header
    $out[] = tag('http://textpattern.com/?v=' . $version, 'generator');
    $out[] = tag(doSpecial($sitename), 'title');
    $out[] = tag(hu, 'link');
    $out[] = '<atom:link href="' . pagelinkurl(array('rss' => 1, 'area' => $area, 'section' => $section, 'category' => $category, 'limit' => $limit)) . '" rel="self" type="application/rss+xml" />';
    $out[] = tag(doSpecial($site_slogan), 'description');
    $last = fetch('unix_timestamp(val)', 'txp_prefs', 'name', 'lastmod');
    $out[] = tag(safe_strftime('rfc822', $last), 'pubDate');
    $out[] = callback_event('rss_head');
    // feed items
    $articles = array();
    $section = doSlash($section);
    $category = doSlash($category);
    if (!$area or $area == 'article') {
        $sfilter = !empty($section) ? "and Section in ('" . join("','", $section) . "')" : '';
        $cfilter = !empty($category) ? "and (Category1 in ('" . join("','", $category) . "') or Category2 in ('" . join("','", $category) . "'))" : '';
        $limit = $limit ? $limit : $rss_how_many;
        $limit = intval(min($limit, max(100, $rss_how_many)));
        $frs = safe_column("name", "txp_section", "in_rss != '1'");
        if ($frs) {
            foreach ($frs as $f) {
                $query[] = "and Section != '" . doSlash($f) . "'";
            }
        }
        $query[] = $sfilter;
        $query[] = $cfilter;
        $expired = $publish_expired_articles ? '' : ' and (now() <= Expires or Expires = ' . NULLDATETIME . ') ';
        $rs = safe_rows_start("*, unix_timestamp(Posted) as uPosted, unix_timestamp(LastMod) as uLastMod, unix_timestamp(Expires) as uExpires, ID as thisid", "textpattern", "Status = 4 " . join(' ', $query) . "and Posted < now()" . $expired . "order by Posted desc limit {$limit}");
        if ($rs) {
            while ($a = nextRow($rs)) {
                extract($a);
                populateArticleData($a);
                $cb = callback_event('rss_entry');
                $a['posted'] = $uPosted;
                $permlink = permlinkurl($a);
                $summary = trim(replace_relative_urls(parse($thisarticle['excerpt']), $permlink));
                $content = trim(replace_relative_urls(parse($thisarticle['body']), $permlink));
                if ($syndicate_body_or_excerpt) {
                    # short feed: use body as summary if there's no excerpt
                    if (!trim($summary)) {
                        $summary = $content;
                    }
                    $content = '';
                }
                if ($show_comment_count_in_feed) {
                    $count = $comments_count > 0 ? ' [' . $comments_count . ']' : '';
                } else {
                    $count = '';
                }
                $Title = escape_title(strip_tags($Title)) . $count;
                $thisauthor = get_author_name($AuthorID);
                $item = tag($Title, 'title') . n . (trim($summary) ? tag(n . escape_cdata($summary) . n, 'description') . n : '') . (trim($content) ? tag(n . escape_cdata($content) . n, 'content:encoded') . n : '') . tag($permlink, 'link') . n . tag(safe_strftime('rfc822', $a['posted']), 'pubDate') . n . tag(htmlspecialchars($thisauthor), 'dc:creator') . n . tag('tag:' . $mail_or_domain . ',' . $feed_time . ':' . $blog_uid . '/' . $uid, 'guid', ' isPermaLink="false"') . n . $cb;
                $articles[$ID] = tag($item, 'item');
                $etags[$ID] = strtoupper(dechex(crc32($articles[$ID])));
                $dates[$ID] = $uPosted;
            }
        }
    } elseif ($area == 'link') {
        $cfilter = $category ? "category in ('" . join("','", $category) . "')" : '1';
        $limit = $limit ? $limit : $rss_how_many;
        $limit = intval(min($limit, max(100, $rss_how_many)));
        $rs = safe_rows_start("*, unix_timestamp(date) as uDate", "txp_link", "{$cfilter} order by date desc limit {$limit}");
        if ($rs) {
            while ($a = nextRow($rs)) {
                extract($a);
                $item = tag(doSpecial($linkname), 'title') . n . tag(doSpecial($description), 'description') . n . tag(doSpecial($url), 'link') . n . tag(safe_strftime('rfc822', $uDate), 'pubDate');
                $articles[$id] = tag($item, 'item');
                $etags[$id] = strtoupper(dechex(crc32($articles[$id])));
                $dates[$id] = $date;
            }
        }
    }
    if (!$articles) {
        if ($section) {
            if (safe_field('name', 'txp_section', "name in ('" . join("','", $section) . "')") == false) {
                txp_die(gTxt('404_not_found'), '404');
            }
        } elseif ($category) {
            switch ($area) {
                case 'link':
                    if (safe_field('id', 'txp_category', "name = '{$category}' and type = 'link'") == false) {
                        txp_die(gTxt('404_not_found'), '404');
                    }
                    break;
                case 'article':
                default:
                    if (safe_field('id', 'txp_category', "name in ('" . join("','", $category) . "') and type = 'article'") == false) {
                        txp_die(gTxt('404_not_found'), '404');
                    }
                    break;
            }
        }
    } else {
        //turn on compression if we aren't using it already
        if (extension_loaded('zlib') && ini_get("zlib.output_compression") == 0 && ini_get('output_handler') != 'ob_gzhandler' && !headers_sent()) {
            // make sure notices/warnings/errors don't fudge up the feed
            // when compression is used
            $buf = '';
            while ($b = @ob_get_clean()) {
                $buf .= $b;
            }
            @ob_start('ob_gzhandler');
            echo $buf;
        }
        handle_lastmod();
        $hims = serverset('HTTP_IF_MODIFIED_SINCE');
        $imsd = $hims ? strtotime($hims) : 0;
        if (is_callable('apache_request_headers')) {
            $headers = apache_request_headers();
            if (isset($headers["A-IM"])) {
                $canaim = strpos($headers["A-IM"], "feed");
            } else {
                $canaim = false;
            }
        } else {
            $canaim = false;
        }
        $hinm = stripslashes(serverset('HTTP_IF_NONE_MATCH'));
        $cutarticles = false;
        if ($canaim !== false) {
            foreach ($articles as $id => $thing) {
                if (strpos($hinm, $etags[$id]) !== false) {
                    unset($articles[$id]);
                    $cutarticles = true;
                    $cut_etag = true;
                }
                if ($dates[$id] < $imsd) {
                    unset($articles[$id]);
                    $cutarticles = true;
                    $cut_time = true;
                }
            }
        }
        if (isset($cut_etag) && isset($cut_time)) {
            header("Vary: If-None-Match, If-Modified-Since");
        } else {
            if (isset($cut_etag)) {
                header("Vary: If-None-Match");
            } else {
                if (isset($cut_time)) {
                    header("Vary: If-Modified-Since");
                }
            }
        }
        $etag = @join("-", $etags);
        if (strstr($hinm, $etag)) {
            txp_status_header('304 Not Modified');
            exit(0);
        }
        if ($cutarticles) {
            //header("HTTP/1.1 226 IM Used");
            //This should be used as opposed to 200, but Apache doesn't like it.
            //http://intertwingly.net/blog/2004/09/11/Vary-ETag/ says that the status code should be 200.
            header("Cache-Control: no-store, im");
            header("IM: feed");
        }
    }
    $out = array_merge($out, $articles);
    header("Content-Type: application/rss+xml; charset=utf-8");
    if (isset($etag)) {
        header('ETag: "' . $etag . '"');
    }
    return '<?xml version="1.0" encoding="utf-8"?>' . n . '<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">' . n . tag(join(n, $out), 'channel') . n . '</rss>';
}
Example #21
0
/**
 * Processes multi-edit actions.
 *
 * Accessing requires 'admin.edit' privileges.
 */
function admin_multi_edit()
{
    global $txp_user;
    require_privs('admin.edit');
    $selected = ps('selected');
    $method = ps('edit_method');
    $changed = array();
    $msg = '';
    if (!$selected or !is_array($selected)) {
        return author_list();
    }
    $names = safe_column('name', 'txp_users', "name IN (" . join(',', quote_list($selected)) . ") AND name != '" . doSlash($txp_user) . "'");
    if (!$names) {
        return author_list();
    }
    switch ($method) {
        case 'delete':
            $assign_assets = ps('assign_assets');
            if (!$assign_assets) {
                $msg = array('must_reassign_assets', E_ERROR);
            } elseif (in_array($assign_assets, $names)) {
                $msg = array('cannot_assign_assets_to_deletee', E_ERROR);
            } elseif (remove_user($names, $assign_assets)) {
                $changed = $names;
                callback_event('authors_deleted', '', 0, $changed);
                $msg = 'author_deleted';
            }
            break;
        case 'changeprivilege':
            if (change_user_group($names, ps('privs'))) {
                $changed = $names;
                $msg = 'author_updated';
            }
            break;
        case 'resetpassword':
            foreach ($names as $name) {
                $passwd = generate_password(PASSWORD_LENGTH);
                if (change_user_password($name, $passwd)) {
                    $email = safe_field('email', 'txp_users', "name = '" . doSlash($name) . "'");
                    if (send_new_password($passwd, $email, $name)) {
                        $changed[] = $name;
                        $msg = 'author_updated';
                    } else {
                        return author_list(array(gTxt('could_not_mail') . ' ' . txpspecialchars($name), E_ERROR));
                    }
                }
            }
            break;
    }
    if ($changed) {
        return author_list(gTxt($msg, array('{name}' => txpspecialchars(join(', ', $changed)))));
    }
    author_list($msg);
}
Example #22
0
function admin_multi_edit()
{
    global $txp_user;
    require_privs('admin.edit');
    $selected = ps('selected');
    $method = ps('edit_method');
    $changed = array();
    if (!$selected or !is_array($selected)) {
        return admin();
    }
    $names = safe_column('name', 'txp_users', "name IN ('" . join("','", doSlash($selected)) . "') AND name != '" . doSlash($txp_user) . "'");
    if (!$names) {
        return admin();
    }
    switch ($method) {
        case 'delete':
            if (safe_delete('txp_users', "name IN ('" . join("','", doSlash($names)) . "')")) {
                $changed = $names;
                $msg = 'author_deleted';
            }
            break;
        case 'changeprivilege':
            global $levels;
            $privilege = ps('privs');
            if (!isset($levels[$privilege])) {
                return admin();
            }
            if (safe_update('txp_users', 'privs = ' . intval($privilege), "name IN ('" . join("','", doSlash($names)) . "')")) {
                $changed = $names;
                $msg = 'author_updated';
            }
            break;
        case 'resetpassword':
            $failed = array();
            foreach ($names as $name) {
                $passwd = generate_password(6);
                if (safe_update('txp_users', "pass = password(lower('" . doSlash($passwd) . "'))", "name = '" . doSlash($name) . "'")) {
                }
                $email = safe_field('email', 'txp_users', "name = '" . doSlash($name) . "'");
                if (send_new_password($passwd, $email, $name)) {
                    $changed[] = $name;
                    $msg = 'author_updated';
                } else {
                    return admin(gTxt('could_not_mail') . ' ' . htmlspecialchars($name));
                }
            }
            break;
    }
    if ($changed) {
        return admin(gTxt($msg, array('{name}' => htmlspecialchars(join(', ', $changed)))));
    }
    admin();
}
Example #23
0
function rebuild_tree($parent, $left, $type)
{
    $right = $left + 1;
    $parent = doSlash($parent);
    $result = safe_column("name", "txp_category", "parent='{$parent}' and type='{$type}' order by name");
    foreach ($result as $row) {
        $right = rebuild_tree($row, $right, $type);
    }
    safe_update("txp_category", "lft={$left}, rgt={$right}", "name='{$parent}' and type='{$type}'");
    return $right + 1;
}
function pagetop($pagetitle, $message = "")
{
    global $css_mode, $siteurl, $sitename, $txp_user, $event;
    $area = gps('area');
    $event = !$event ? 'article' : $event;
    $bm = gps('bm');
    $privs = safe_field("privs", "txp_users", "name = '" . doSlash($txp_user) . "'");
    $GLOBALS['privs'] = $privs;
    $areas = areas();
    $area = false;
    foreach ($areas as $k => $v) {
        if (in_array($event, $v)) {
            $area = $k;
            break;
        }
    }
    if (gps('logout')) {
        $body_id = 'page-logout';
    } elseif (!$txp_user) {
        $body_id = 'page-login';
    } else {
        $body_id = 'page-' . $event;
    }
    ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
	<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php 
    echo LANG;
    ?>
" lang="<?php 
    echo LANG;
    ?>
" dir="<?php 
    echo gTxt('lang_dir');
    ?>
">
	<head>
	<meta http-equiv="content-type" content="text/html; charset=utf-8" />
	<meta name="robots" content="noindex, nofollow" />
	<title>Txp &#8250; <?php 
    echo htmlspecialchars($sitename);
    ?>
 &#8250; <?php 
    echo escape_title($pagetitle);
    ?>
</title>
	<link href="textpattern.css" rel="stylesheet" type="text/css" />
	<script type="text/javascript" src="textpattern.js"></script>
	<script type="text/javascript">
	<!--

		var cookieEnabled = checkCookies();

		if (!cookieEnabled)
		{
			confirm('<?php 
    echo trim(gTxt('cookies_must_be_enabled'));
    ?>
');
		}

<?php 
    $edit = array();
    if ($event == 'list') {
        $rs = safe_column('name', 'txp_section', "name != 'default'");
        $edit['section'] = $rs ? selectInput('Section', $rs, '', true) : '';
        $rs = getTree('root', 'article');
        $edit['category1'] = $rs ? treeSelectInput('Category1', $rs, '') : '';
        $edit['category2'] = $rs ? treeSelectInput('Category2', $rs, '') : '';
        $edit['comments'] = onoffRadio('Annotate', safe_field('val', 'txp_prefs', "name = 'comments_on_default'"));
        $edit['status'] = selectInput('Status', array(1 => gTxt('draft'), 2 => gTxt('hidden'), 3 => gTxt('pending'), 4 => gTxt('live'), 5 => gTxt('sticky')), '', true);
        $rs = safe_column('name', 'txp_users', "privs not in(0,6)");
        $edit['author'] = $rs ? selectInput('AuthorID', $rs, '', true) : '';
    }
    if (in_array($event, array('image', 'file', 'link'))) {
        $rs = getTree('root', $event);
        $edit['category'] = $rs ? treeSelectInput('category', $rs, '') : '';
    }
    if ($event == 'plugin') {
        $edit['order'] = selectInput('order', array(1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5, 6 => 6, 7 => 7, 8 => 8, 9 => 9), 5, false);
    }
    if ($event == 'admin') {
        $edit['privilege'] = privs();
    }
    // output JavaScript
    ?>
		function poweredit(elm)
		{
			var something = elm.options[elm.selectedIndex].value;

			// Add another chunk of HTML
			var pjs = document.getElementById('js');

			if (pjs == null)
			{
				var br = document.createElement('br');
				elm.parentNode.appendChild(br);

				pjs = document.createElement('P');
				pjs.setAttribute('id','js');
				elm.parentNode.appendChild(pjs);
			}

			if (pjs.style.display == 'none' || pjs.style.display == '')
			{
				pjs.style.display = 'block';
			}

			if (something != '')
			{
				switch (something)
				{
<?php 
    foreach ($edit as $key => $val) {
        echo "case 'change" . $key . "':" . n . t . "pjs.innerHTML = '<span>" . str_replace(array("\n", '-'), array('', '&#45;'), addslashes($val)) . "</span>';" . n . t . 'break;' . n . n;
    }
    ?>
					default:
						pjs.style.display = 'none';
					break;
				}
			}

			return false;
		}

		addEvent(window, 'load', cleanSelects);
	-->
	</script>
	<script type="text/javascript" src="jquery.js"></script>
	<?php 
    callback_event('admin_side', 'head_end');
    ?>
	</head>
	<body id="<?php 
    echo $body_id;
    ?>
">
	<?php 
    callback_event('admin_side', 'pagetop');
    ?>
  <table id="pagetop" cellpadding="0" cellspacing="0">
  <tr id="branding"><td><h1 id="textpattern">Textpattern</h1></td><td id="navpop"><?php 
    echo navPop(1);
    ?>
</td></tr>
  <tr id="nav-primary"><td align="center" class="tabs" colspan="2">
 		<?php 
    if (!$bm) {
        echo '<table cellpadding="0" cellspacing="0" align="center"><tr>
  <td valign="middle" style="width:368px">&nbsp;' . $message . '</td>', has_privs('tab.content') ? areatab(gTxt('tab_content'), 'content', 'article', $area) : '', has_privs('tab.presentation') ? areatab(gTxt('tab_presentation'), 'presentation', 'page', $area) : '', has_privs('tab.admin') ? areatab(gTxt('tab_admin'), 'admin', 'admin', $area) : '', (has_privs('tab.extensions') and !empty($areas['extensions'])) ? areatab(gTxt('tab_extensions'), 'extensions', array_shift($areas['extensions']), $area) : '', '<td class="tabdown"><a href="' . hu . '" class="plain" target="_blank">' . gTxt('tab_view_site') . '</a></td>', '</tr></table>';
        $secondary = tabsort($area, $event);
        if ($secondary) {
            echo '</td></tr><tr id="nav-secondary"><td align="center" class="tabs" colspan="2">
			<table cellpadding="0" cellspacing="0" align="center"><tr>', $secondary, '</tr></table>';
        }
    }
    echo '</td></tr></table>';
    callback_event('admin_side', 'pagetop_end');
}
Example #25
0
function form_pop($form, $id)
{
    $arr = array(' ');
    $rs = safe_column('name', 'txp_form', "type = 'article' and name != 'default' order by name");
    if ($rs) {
        return selectInput('override_form', $rs, $form, true, '', $id);
    }
}
Example #26
0
function section_multi_edit()
{
    global $txp_user, $all_pages, $all_styles;
    $selected = ps('selected');
    if (!$selected or !is_array($selected)) {
        return sec_section_list();
    }
    $method = ps('edit_method');
    $changed = array();
    $key = $msg = '';
    switch ($method) {
        case 'delete':
            return section_delete($selected);
            break;
        case 'changepage':
            $val = ps('uses_page');
            if (in_array($val, $all_pages)) {
                $key = 'page';
            }
            break;
        case 'changecss':
            $val = ps('css');
            if (in_array($val, $all_styles)) {
                $key = 'css';
            }
            break;
        case 'changeonfrontpage':
            $key = 'on_frontpage';
            $val = (int) ps('on_frontpage');
            break;
        case 'changesyndicate':
            $key = 'in_rss';
            $val = (int) ps('in_rss');
            break;
        case 'changesearchable':
            $key = 'searchable';
            $val = (int) ps('searchable');
            break;
        default:
            $key = '';
            $val = '';
            break;
    }
    $selected = safe_column('name', 'txp_section', "name IN ('" . join("','", doSlash($selected)) . "')");
    if ($selected and $key) {
        foreach ($selected as $id) {
            if (safe_update('txp_section', "{$key} = '" . doSlash($val) . "'", "name = '" . doSlash($id) . "'")) {
                $changed[] = $id;
            }
        }
        $msg = gTxt('section_updated', array('{name}' => join(', ', $changed)));
    }
    return sec_section_list($msg);
}
Example #27
0
function install_textpack($textpack, $add_new_langs = false)
{
    global $prefs;
    $textpack = explode(n, $textpack);
    if (empty($textpack)) {
        return 0;
    }
    // presume site language equals textpack language
    $language = get_pref('language', 'en-gb');
    $installed_langs = safe_column('lang', 'txp_lang', "1 = 1 group by lang");
    $doit = true;
    $done = 0;
    foreach ($textpack as $line) {
        $line = trim($line);
        // A line starting with #, not followed by @ is a simple comment
        if (preg_match('/^#[^@]/', $line, $m)) {
            continue;
        }
        // A line matching "#@language xx-xx" establishes the designated language for all subsequent lines
        if (preg_match('/^#@language\\s+(.+)$/', $line, $m)) {
            $language = doSlash($m[1]);
            // May this Textpack introduce texts for this language?
            $doit = $add_new_langs || in_array($language, $installed_langs);
            continue;
        }
        // A line matching "#@event_name" establishes the event value for all subsequent lines
        if (preg_match('/^#@([a-zA-Z0-9_-]+)$/', $line, $m)) {
            $event = doSlash($m[1]);
            continue;
        }
        // Data lines match a "name => value" pattern. Some white space allowed.
        if ($doit && preg_match('/^(\\w+)\\s*=>\\s*(.+)$/', $line, $m)) {
            if (!empty($m[1]) && !empty($m[2])) {
                $name = doSlash($m[1]);
                $value = doSlash($m[2]);
                $where = "lang='{$language}' AND name='{$name}'";
                // Store text; do *not* tamper with last modification date from RPC but use a well-known date in the past
                if (safe_count('txp_lang', $where)) {
                    safe_update('txp_lang', "lastmod='2005-08-14', data='{$value}', event='{$event}'", $where);
                } else {
                    safe_insert('txp_lang', "lastmod='2005-08-14', data='{$value}', event='{$event}', lang='{$language}', name='{$name}'");
                }
                ++$done;
            }
        }
    }
    return $done;
}
Example #28
0
function form_pop($form)
{
    $arr = array(' ');
    $rs = safe_column("name", "txp_form", "type='article' and name!='default'");
    if ($rs) {
        return selectInput('override_form', $rs, $form, 1);
    }
}
Example #29
0
/**
 * Renders a &lt;select&gt; input containing all available sections.
 *
 * @param  string $Section The selected option
 * @return string HTML
 * @access private
 */
function import_section_popup($Section)
{
    $rs = safe_column("name", "txp_section", "name!='default'");
    if ($rs) {
        return selectInput("import_section", $rs, $Section, 1, '', 'import_section');
    }
    return false;
}
Example #30
0
function rss()
{
    global $prefs, $thisarticle;
    extract($prefs);
    ob_start();
    extract(doSlash(gpsa(array('category', 'section', 'limit', 'area'))));
    $area = gps('area');
    $sitename .= $section ? ' - ' . $section : '';
    $sitename .= $category ? ' - ' . $category : '';
    $out[] = tag(doSpecial($sitename), 'title');
    $out[] = tag(hu, 'link');
    $out[] = tag(doSpecial($site_slogan), 'description');
    $articles = array();
    if (!$area or $area == 'article') {
        $sfilter = $section ? "and Section = '" . $section . "'" : '';
        $cfilter = $category ? "and (Category1='" . $category . "' or Category2='" . $category . "')" : '';
        $limit = $limit ? $limit : '5';
        $frs = safe_column("name", "txp_section", "in_rss != '1'");
        if ($frs) {
            foreach ($frs as $f) {
                $query[] = "and Section != '" . $f . "'";
            }
        }
        $query[] = $sfilter;
        $query[] = $cfilter;
        $rs = safe_rows_start("*, unix_timestamp(Posted) as uPosted, ID as thisid", "textpattern", "Status = 4 " . join(' ', $query) . "and Posted < now() order by Posted desc limit {$limit}");
        if ($rs) {
            while ($a = nextRow($rs)) {
                extract($a);
                populateArticleData($a);
                $a['posted'] = $uPosted;
                $Body = !$syndicate_body_or_excerpt ? $thisarticle['body'] : $thisarticle['excerpt'];
                $Body = !trim($Body) ? $thisarticle['body'] : $Body;
                $Body = str_replace('href="/', 'href="' . hu, $Body);
                $Body = preg_replace("/href=\\\"#(.*)\"/", "href=\"" . permlinkurl($a) . "#\\1\"", $Body);
                $Body = safe_hed($Body);
                $Body = preg_replace(array('/</', '/>/', "/'/", '/"/'), array('&lt;', '&gt;', '&#039;', '&quot;'), $Body);
                // encode bare ampersands
                $Body = preg_replace("/&(?![#0-9]+;|\\w+;)/i", '&amp;', $Body);
                $uTitle = $url_title ? $url_title : stripSpace($Title);
                $uTitle = htmlspecialchars($uTitle, ENT_NOQUOTES);
                if ($show_comment_count_in_feed) {
                    $dc = getCount('txp_discuss', "parentid={$ID} and visible=1");
                    $count = $dc > 0 ? ' [' . $dc . ']' : '';
                } else {
                    $count = '';
                }
                $Title = doSpecial($Title) . $count;
                $permlink = permlinkurl($a);
                $item = tag(strip_tags($Title), 'title') . n . tag($Body, 'description') . n . tag($permlink, 'link');
                $articles[$ID] = tag($item, 'item');
                $etags[$ID] = strtoupper(dechex(crc32($articles[$ID])));
                $dates[$ID] = $uPosted;
            }
        }
    } elseif ($area == 'link') {
        $cfilter = $category ? "category='{$category}'" : '1';
        $limit = $limit ? $limit : 15;
        $rs = safe_rows_start("*", "txp_link", "{$cfilter} order by date desc limit {$limit}");
        if ($rs) {
            while ($a = nextRow($rs)) {
                extract($a);
                $item = tag(doSpecial($linkname), 'title') . n . tag(doSpecial($description), 'description') . n . tag(doSpecial($url), 'link');
                $articles[$id] = tag($item, 'item');
                $etags[$id] = strtoupper(dechex(crc32($articles[$id])));
                $dates[$id] = $date;
            }
        }
    }
    //turn on compression if we aren't using it already
    if (extension_loaded('zlib') && ini_get("zlib.output_compression") == 0 && ini_get('output_handler') != 'ob_gzhandler' && !headers_sent()) {
        ob_start("ob_gzhandler");
    }
    $last = fetch('unix_timestamp(val)', 'txp_prefs', 'name', 'lastmod');
    $last = gmdate("D, d M Y H:i:s \\G\\M\\T", $last);
    header("Last-Modified: {$last}");
    $expires = gmdate('D, d M Y H:i:s \\G\\M\\T', time() + 3600 * 1);
    header("Expires: {$expires}");
    $hims = serverset('HTTP_IF_MODIFIED_SINCE');
    if ($hims == $last) {
        header("HTTP/1.1 304 Not Modified");
        exit;
    }
    $imsd = @strtotime($hims);
    if (is_callable('apache_request_headers')) {
        $headers = apache_request_headers();
        if (isset($headers["A-IM"])) {
            $canaim = strpos($headers["A-IM"], "feed");
        } else {
            $canaim = false;
        }
    } else {
        $canaim = false;
    }
    $hinm = stripslashes(serverset('HTTP_IF_NONE_MATCH'));
    $cutarticles = false;
    if ($canaim !== false) {
        foreach ($articles as $id => $thing) {
            if (strpos($hinm, $etags[$id]) !== false) {
                unset($articles[$id]);
                $cutarticles = true;
                $cut_etag = true;
            }
            if ($dates[$id] < $imsd) {
                unset($articles[$id]);
                $cutarticles = true;
                $cut_time = true;
            }
        }
    }
    if (isset($cut_etag) && isset($cut_time)) {
        header("Vary: If-None-Match, If-Modified-Since");
    } else {
        if (isset($cut_etag)) {
            header("Vary: If-None-Match");
        } else {
            if (isset($cut_time)) {
                header("Vary: If-Modified-Since");
            }
        }
    }
    $etag = @join("-", $etags);
    if (strstr($hinm, $etag)) {
        header("HTTP/1.1 304 Not Modified");
        exit;
    }
    if ($cutarticles) {
        //header("HTTP/1.1 226 IM Used");
        //This should be used as opposed to 200, but Apache doesn't like it.
        //http://intertwingly.net/blog/2004/09/11/Vary-ETag/ says that the status code should be 200.
        header("Cache-Control: no-store, im");
        header("IM: feed");
    }
    $out = array_merge($out, $articles);
    header("Content-Type: application/rss+xml; charset=utf-8");
    if ($etag) {
        header('ETag: "' . $etag . '"');
    }
    return '<rss version="0.92">' . tag(join(n, $out), 'channel') . '</rss>';
}