.
*/
/**
* Collection of tag functions.
*
* @package Tag
*/
Txp::get('\Textpattern\Tag\Registry')
->register('page_title')
->register('css')
->register('image')
->register('thumbnail')
->register('output_form')
->register(array('\Textpattern\Tag\Syntax\Partial', 'renderYield'), 'yield')
->register(array('\Textpattern\Tag\Syntax\Partial', 'renderIfYield'), 'if_yield')
->register('feed_link')
->register('link_feed_link')
->register('linklist')
->register('tpt_link', 'link')
->register('linkdesctitle')
->register('link_name')
->register('link_url')
->register('link_author')
->register('link_description')
->register('link_date')
->register('link_category')
->register('link_id')
->register(array('\Textpattern\Tag\Syntax\Link', 'renderIfFirstLink'), 'if_first_link')
->register(array('\Textpattern\Tag\Syntax\Link', 'renderIfLastLink'), 'if_last_link')
->register('email')
->register('password_protect')
->register('recent_articles')
->register('recent_comments')
->register('related_articles')
->register('popup')
->register('category_list')
->register('section_list')
->register('search_input')
->register('search_term')
->register('link_to_next')
->register('link_to_prev')
->register('next_title')
->register('prev_title')
->register('site_name')
->register('site_slogan')
->register('link_to_home')
->register('newer')
->register('older')
->register('text')
->register('article_id')
->register('article_url_title')
->register('if_article_id')
->register('posted')
->register('expires')
->register('if_expires')
->register('if_expired')
->register('modified')
->register('comments_count')
->register('comments_invite')
->register('comments_form')
->register('comments_error')
->register('if_comments_error')
->register('comments')
->register('comments_preview')
->register('if_comments_preview')
->register('comment_permlink')
->register('comment_id')
->register('comment_name')
->register('comment_email')
->register('comment_web')
->register('comment_time')
->register('comment_message')
->register('comment_anchor')
->register(array('\Textpattern\Tag\Syntax\Authors', 'renderAuthors'), 'authors')
->register('author')
->register('author_email')
->register('if_author')
->register('if_article_author')
->register('body')
->register('title')
->register('excerpt')
->register('category1')
->register('category2')
->register('category')
->register('section')
->register('keywords')
->register('if_keywords')
->register('if_description')
->register('if_article_image')
->register('article_image')
->register('search_result_title')
->register('search_result_excerpt')
->register('search_result_url')
->register('search_result_date')
->register('search_result_count')
->register('image_index')
->register('image_display')
->register('images')
->register('image_info')
->register('image_url')
->register('image_author')
->register('image_date')
->register(array('\Textpattern\Tag\Syntax\Image', 'renderIfFirstImage'), 'if_first_image')
->register(array('\Textpattern\Tag\Syntax\Image', 'renderIfLastImage'), 'if_last_image')
->register('if_thumbnail')
->register('if_comments')
->register('if_comments_allowed')
->register('if_comments_disallowed')
->register('if_individual_article')
->register('if_article_list')
->register('meta_keywords')
->register('meta_description')
->register('meta_author')
->register('permlink')
->register('lang')
->register('breadcrumb')
->register('if_excerpt')
->register('if_search')
->register('if_search_results')
->register('if_category')
->register('if_article_category')
->register('if_first_category')
->register('if_last_category')
->register('if_section')
->register('if_article_section')
->register('if_first_section')
->register('if_last_section')
->register('php')
->register('custom_field')
->register('if_custom_field')
->register('site_url')
->register('error_message')
->register('error_status')
->register('if_status')
->register('page_url')
->register('if_different')
->register('if_first_article')
->register('if_last_article')
->register('if_plugin')
->register('file_download_list')
->register('file_download')
->register('file_download_link')
->register('file_download_size')
->register('file_download_created')
->register('file_download_modified')
->register('file_download_id')
->register('file_download_name')
->register('file_download_category')
->register('file_download_author')
->register('file_download_downloads')
->register('file_download_description')
->register(array('\Textpattern\Tag\Syntax\File', 'renderIfFirstFile'), 'if_first_file')
->register(array('\Textpattern\Tag\Syntax\File', 'renderIfLastFile'), 'if_last_file')
->register('hide')
->register('rsd')
->register('variable')
->register('if_variable')
->register('article')
->register('article_custom')
->register('txp_die')
->register('comments_help')
->register('comment_name_input')
->register('comment_email_input')
->register('comment_web_input')
->register('comment_message_input')
->register('comment_remember')
->register('comment_preview')
->register('comment_submit');
// -------------------------------------------------------------
function page_title($atts)
{
global $parentid, $thisarticle, $id, $q, $c, $author, $context, $s, $pg, $sitename;
extract(lAtts(array(
'separator' => ': ',
), $atts));
$out = txpspecialchars($sitename.$separator);
$parent_id = (int) $parentid;
if ($parent_id) {
$out .= gTxt('comments_on').' '.escape_title(safe_field("Title", 'textpattern', "ID = $parent_id"));
} elseif ($thisarticle['title']) {
$out .= escape_title($thisarticle['title']);
} elseif ($q) {
$out .= gTxt('search_results').txpspecialchars($separator.$q);
} elseif ($c) {
$out .= txpspecialchars(fetch_category_title($c, $context));
} elseif ($s and $s != 'default') {
$out .= txpspecialchars(fetch_section_title($s));
} elseif ($author) {
$out .= txpspecialchars(get_author_name($author));
} elseif ($pg) {
$out .= gTxt('page').' '.$pg;
} else {
$out = txpspecialchars($sitename);
}
return $out;
}
// -------------------------------------------------------------
function css($atts)
{
global $css, $doctype;
extract(lAtts(array(
'format' => 'url',
'media' => 'screen',
'n' => $css, // Deprecated in 4.3.0.
'name' => $css,
'rel' => 'stylesheet',
'title' => '',
), $atts));
if (isset($atts['n'])) {
$name = $n;
trigger_error(gTxt('deprecated_attribute', array('{name}' => 'n')), E_USER_NOTICE);
}
if (empty($name)) {
$name = 'default';
}
if (has_handler('css.url')) {
$url = callback_event('css.url', '', false, compact('name'));
} else {
$url = hu.'css.php?n='.urlencode($name);
}
if ($format == 'link') {
return tag_void('link', array(
'rel' => $rel,
'type' => $doctype != 'html5' ? 'text/css' : '',
'media' => $media,
'title' => $title,
'href' => $url,
));
}
return txpspecialchars($url);
}
// -------------------------------------------------------------
function image($atts)
{
global $thisimage;
static $cache = array();
extract(lAtts(array(
'class' => '',
'escape' => 'html',
'html_id' => '',
'id' => '',
'name' => '',
'width' => '',
'height' => '',
'style' => '',
'wraptag' => '',
), $atts));
if ($name) {
if (isset($cache['n'][$name])) {
$rs = $cache['n'][$name];
} else {
$name = doSlash($name);
$rs = safe_row("*", 'txp_image', "name = '$name' LIMIT 1");
$cache['n'][$name] = $rs;
}
} elseif ($id) {
if (isset($cache['i'][$id])) {
$rs = $cache['i'][$id];
} else {
$id = (int) $id;
$rs = safe_row("*", 'txp_image', "id = $id LIMIT 1");
$cache['i'][$id] = $rs;
}
} elseif ($thisimage) {
$id = (int) $thisimage['id'];
$rs = $thisimage;
$cache['i'][$id] = $rs;
} else {
trigger_error(gTxt('unknown_image'));
return;
}
if ($rs) {
extract($rs);
if ($escape == 'html') {
$alt = txpspecialchars($alt);
$caption = txpspecialchars($caption);
}
if ($width == '' && $w) {
$width = $w;
}
if ($height == '' && $h) {
$height = $h;
}
$out = ' '',
'escape' => 'html',
'html_id' => '',
'height' => '',
'id' => '',
'link' => 0,
'link_rel' => '',
'name' => '',
'poplink' => 0, // Is this used?
'style' => '',
'wraptag' => '',
'width' => '',
), $atts));
if ($name) {
$name = doSlash($name);
$rs = safe_row("*", 'txp_image', "name = '$name' LIMIT 1");
} elseif ($id) {
$id = (int) $id;
$rs = safe_row("*", 'txp_image', "id = $id LIMIT 1");
} elseif ($thisimage) {
$id = (int) $thisimage['id'];
$rs = $thisimage;
} else {
trigger_error(gTxt('unknown_image'));
return;
}
if ($rs) {
extract($rs);
if ($thumbnail) {
if ($escape == 'html') {
$alt = txpspecialchars($alt);
$caption = txpspecialchars($caption);
}
if ($width == '' && $thumb_w) {
$width = $thumb_w;
}
if ($height == '' && $thumb_h) {
$height = $thumb_h;
}
$out = ''.$out.'';
}
if ($wraptag) {
return doTag($out, $wraptag, $class, '', $html_id);
}
return $out;
}
}
trigger_error(gTxt('unknown_image'));
}
// -------------------------------------------------------------
function output_form($atts, $thing = null)
{
global $yield;
extract(lAtts(array(
'form' => '',
), $atts));
if (!$form) {
trigger_error(gTxt('form_not_specified'));
} else {
$yield[] = $thing !== null ? parse($thing) : null;
$out = parse_form($form);
array_pop($yield);
return $out;
}
}
// -------------------------------------------------------------
function feed_link($atts, $thing = null)
{
global $s, $c;
extract(lAtts(array(
'category' => $c,
'flavor' => 'rss',
'format' => 'a',
'label' => '',
'limit' => '',
'section' => ($s == 'default' ? '' : $s),
'title' => gTxt('rss_feed_title'),
'wraptag' => '',
'class' => '',
), $atts));
$url = pagelinkurl(array(
$flavor => '1',
'section' => $section,
'category' => $category,
'limit' => $limit,
));
if ($flavor == 'atom') {
$title = ($title == gTxt('rss_feed_title')) ? gTxt('atom_feed_title') : $title;
}
$title = txpspecialchars($title);
if ($format == 'link') {
$type = ($flavor == 'atom') ? 'application/atom+xml' : 'application/rss+xml';
return '';
}
$txt = ($thing === null ? $label : parse($thing));
$out = href($txt, $url, ' title="'.$title.'"');
return ($wraptag) ? doTag($out, $wraptag, $class) : $out;
}
// -------------------------------------------------------------
function link_feed_link($atts)
{
global $c;
extract(lAtts(array(
'category' => $c,
'flavor' => 'rss',
'format' => 'a',
'label' => '',
'title' => gTxt('rss_feed_title'),
'wraptag' => '',
'class' => __FUNCTION__,
), $atts));
$url = pagelinkurl(array(
$flavor => '1',
'area' => 'link',
'category' => $category,
));
if ($flavor == 'atom') {
$title = ($title == gTxt('rss_feed_title')) ? gTxt('atom_feed_title') : $title;
}
$title = txpspecialchars($title);
if ($format == 'link') {
$type = ($flavor == 'atom') ? 'application/atom+xml' : 'application/rss+xml';
return '';
}
$out = href($label, $url, ' title="'.$title.'"');
return ($wraptag) ? doTag($out, $wraptag, $class) : $out;
}
// -------------------------------------------------------------
function linklist($atts, $thing = null)
{
global $s, $c, $context, $thislink, $thispage, $pretext;
extract(lAtts(array(
'break' => '',
'category' => '',
'author' => '',
'realname' => '',
'auto_detect' => 'category, author',
'class' => __FUNCTION__,
'form' => 'plainlinks',
'id' => '',
'label' => '',
'labeltag' => '',
'pageby' => '',
'limit' => 0,
'offset' => 0,
'sort' => 'linksort asc',
'wraptag' => '',
), $atts));
$where = array();
$filters = isset($atts['category']) || isset($atts['author']) || isset($atts['realname']);
$context_list = (empty($auto_detect) || $filters) ? array() : do_list_unique($auto_detect);
$pageby = ($pageby == 'limit') ? $limit : $pageby;
if ($category) {
$where[] = "category IN ('".join("','", doSlash(do_list_unique($category)))."')";
}
if ($id) {
$where[] = "id IN ('".join("','", doSlash(do_list_unique($id)))."')";
}
if ($author) {
$where[] = "author IN ('".join("','", doSlash(do_list_unique($author)))."')";
}
if ($realname) {
$authorlist = safe_column("name", 'txp_users', "RealName IN ('".join("','", doArray(doSlash(do_list_unique($realname)), 'urldecode'))."')");
if ($authorlist) {
$where[] = "author IN ('".join("','", doSlash($authorlist))."')";
}
}
// If no links are selected, try...
if (!$where && !$filters) {
foreach ($context_list as $ctxt) {
switch ($ctxt) {
case 'category':
// ...the global category in the URL.
if ($context == 'link' && !empty($c)) {
$where[] = "category = '".doSlash($c)."'";
}
break;
case 'author':
// ...the global author in the URL.
if ($context == 'link' && !empty($pretext['author'])) {
$where[] = "author = '".doSlash($pretext['author'])."'";
}
break;
}
// Only one context can be processed.
if ($where) {
break;
}
}
}
if (!$where && $filters) {
// If nothing matches, output nothing.
return '';
}
if (!$where) {
// If nothing matches, start with all links.
$where[] = "1 = 1";
}
$where = join(" AND ", $where);
// Set up paging if required.
if ($limit && $pageby) {
$grand_total = safe_count('txp_link', $where);
$total = $grand_total - $offset;
$numPages = ($pageby > 0) ? ceil($total/$pageby) : 1;
$pg = (!$pretext['pg']) ? 1 : $pretext['pg'];
$pgoffset = $offset + (($pg - 1) * $pageby);
// Send paging info to txp:newer and txp:older.
$pageout['pg'] = $pg;
$pageout['numPages'] = $numPages;
$pageout['s'] = $s;
$pageout['c'] = $c;
$pageout['context'] = 'link';
$pageout['grand_total'] = $grand_total;
$pageout['total'] = $total;
if (empty($thispage)) {
$thispage = $pageout;
}
} else {
$pgoffset = $offset;
}
$qparts = array(
$where,
'ORDER BY '.doSlash($sort),
($limit) ? 'LIMIT '.intval($pgoffset).', '.intval($limit) : '',
);
$rs = safe_rows_start("*, UNIX_TIMESTAMP(date) AS uDate", 'txp_link', join(' ', $qparts));
if ($rs) {
$count = 0;
$last = numRows($rs);
$out = array();
while ($a = nextRow($rs)) {
++$count;
$thislink = $a;
$thislink['date'] = $thislink['uDate'];
$thislink['is_first'] = ($count == 1);
$thislink['is_last'] = ($count == $last);
unset($thislink['uDate']);
$out[] = ($thing) ? parse($thing) : parse_form($form);
$thislink = '';
}
if ($out) {
return doLabel($label, $labeltag).doWrap($out, $wraptag, $break, $class);
}
}
return '';
}
// -------------------------------------------------------------
// NOTE: tpt_ prefix used because link() is a PHP function. See publish.php.
function tpt_link($atts)
{
global $thislink;
extract(lAtts(array(
'rel' => '',
'id' => '',
'name' => '',
), $atts));
$rs = $thislink;
$sql = array();
if ($id) {
$sql[] = "id = ".intval($id);
} elseif ($name) {
$sql[] = "linkname = '".doSlash($name)."'";
}
if ($sql) {
$rs = safe_row("linkname, url", 'txp_link', implode(" AND ", $sql)." LIMIT 1");
}
if (!$rs) {
trigger_error(gTxt('unknown_link'));
return;
}
return tag(
txpspecialchars($rs['linkname']), 'a',
($rel ? ' rel="'.txpspecialchars($rel).'"' : '').
' href="'.txpspecialchars($rs['url']).'"'
);
}
// -------------------------------------------------------------
function linkdesctitle($atts)
{
global $thislink;
assert_link();
extract(lAtts(array(
'rel' => '',
), $atts));
$description = ($thislink['description'])
? ' title="'.txpspecialchars($thislink['description']).'"'
: '';
return tag(
txpspecialchars($thislink['linkname']), 'a',
($rel ? ' rel="'.txpspecialchars($rel).'"' : '').
' href="'.doSpecial($thislink['url']).'"'.$description
);
}
// -------------------------------------------------------------
function link_name($atts)
{
global $thislink;
assert_link();
extract(lAtts(array(
'escape' => 'html',
), $atts));
return ($escape == 'html')
? txpspecialchars($thislink['linkname'])
: $thislink['linkname'];
}
// -------------------------------------------------------------
function link_url()
{
global $thislink;
assert_link();
return doSpecial($thislink['url']);
}
// -------------------------------------------------------------
function link_author($atts)
{
global $thislink, $s;
assert_link();
extract(lAtts(array(
'class' => '',
'link' => 0,
'title' => 1,
'section' => '',
'this_section' => '',
'wraptag' => '',
), $atts));
if ($thislink['author']) {
$author_name = get_author_name($thislink['author']);
$display_name = txpspecialchars(($title) ? $author_name : $thislink['author']);
$section = ($this_section) ? ($s == 'default' ? '' : $s) : $section;
$author = ($link)
? href($display_name, pagelinkurl(array('s' => $section, 'author' => $author_name, 'context' => 'link')))
: $display_name;
return ($wraptag) ? doTag($author, $wraptag, $class) : $author;
}
}
// -------------------------------------------------------------
function link_description($atts)
{
global $thislink;
assert_link();
extract(lAtts(array(
'class' => '',
'escape' => 'html',
'label' => '',
'labeltag' => '',
'wraptag' => '',
), $atts));
if ($thislink['description']) {
$description = ($escape == 'html') ?
txpspecialchars($thislink['description']) :
$thislink['description'];
return doLabel($label, $labeltag).doTag($description, $wraptag, $class);
}
}
// -------------------------------------------------------------
function link_date($atts)
{
global $thislink, $dateformat;
assert_link();
extract(lAtts(array(
'format' => $dateformat,
'gmt' => '',
'lang' => '',
), $atts));
return safe_strftime($format, $thislink['date'], $gmt, $lang);
}
// -------------------------------------------------------------
function link_category($atts)
{
global $thislink;
assert_link();
extract(lAtts(array(
'class' => '',
'label' => '',
'labeltag' => '',
'title' => 0,
'wraptag' => '',
), $atts));
if ($thislink['category']) {
$category = ($title)
? fetch_category_title($thislink['category'], 'link')
: $thislink['category'];
return doLabel($label, $labeltag).doTag($category, $wraptag, $class);
}
}
// -------------------------------------------------------------
function link_id()
{
global $thislink;
assert_link();
return $thislink['id'];
}
// -------------------------------------------------------------
function email($atts, $thing = null)
{
extract(lAtts(array(
'email' => '',
'linktext' => gTxt('contact'),
'title' => '',
), $atts));
if ($email) {
if ($thing !== null) {
$linktext = parse($thing);
}
// Obfuscate link text?
if (is_valid_email($linktext)) {
$linktext = eE($linktext);
}
return href(
$linktext,
eE('mailto:'.$email),
($title ? ' title="'.txpspecialchars($title).'"' : '')
);
}
return '';
}
// -------------------------------------------------------------
function password_protect($atts, $thing = null)
{
ob_start();
extract(lAtts(array(
'login' => null,
'pass' => null,
'privs' => null,
), $atts));
if ($pass === null) {
$access = ($user = is_logged_in($login)) !== false && ($privs === null || in_list($user['privs'], $privs));
} else {
$au = serverSet('PHP_AUTH_USER');
$ap = serverSet('PHP_AUTH_PW');
// For PHP as (f)cgi, two rules in htaccess often allow this workaround.
$ru = serverSet('REDIRECT_REMOTE_USER');
if (!$au && !$ap && strpos($ru, 'Basic') === 0) {
list($au, $ap) = explode(':', base64_decode(substr($ru, 6)));
}
$access = $au === $login && $ap === $pass;
}
if ($access === false && $pass !== null) {
header('WWW-Authenticate: Basic realm="Private"');
}
if ($thing === null) {
if ($access === false) {
txp_die(gTxt('auth_required'), '401');
}
return '';
}
return parse($thing, $access);
}
// -------------------------------------------------------------
function recent_articles($atts)
{
global $prefs;
$atts = lAtts(array(
'break' => 'br',
'category' => '',
'class' => __FUNCTION__,
'label' => gTxt('recent_articles'),
'labeltag' => '',
'limit' => 10,
'offset' => 0,
'section' => '',
'sort' => 'Posted DESC',
'sortby' => '', // Deprecated.
'sortdir' => '', // Deprecated.
'wraptag' => '',
'no_widow' => @$prefs['title_no_widow'],
), $atts);
$thing = '';
unset($atts['no_widow']);
return article_custom($atts, $thing);
}
// -------------------------------------------------------------
function recent_comments($atts, $thing = null)
{
global $prefs;
global $thisarticle, $thiscomment;
extract(lAtts(array(
'break' => br,
'class' => __FUNCTION__,
'form' => '',
'label' => '',
'labeltag' => '',
'limit' => 10,
'offset' => 0,
'sort' => 'posted DESC',
'wraptag' => '',
), $atts));
$sort = preg_replace('/\bposted\b/', 'd.posted', $sort);
$expired = ($prefs['publish_expired_articles']) ? '' : " AND (".now('expires')." <= t.Expires OR t.Expires IS NULL) ";
$rs = startRows("SELECT d.name, d.email, d.web, d.message, d.discussid, UNIX_TIMESTAMP(d.Posted) AS time,
t.ID AS thisid, UNIX_TIMESTAMP(t.Posted) AS posted, t.Title AS title, t.Section AS section, t.url_title
FROM ".safe_pfx('txp_discuss')." AS d INNER JOIN ".safe_pfx('textpattern')." AS t ON d.parentid = t.ID
WHERE t.Status >= ".STATUS_LIVE.$expired." AND d.visible = ".VISIBLE."
ORDER BY ".doSlash($sort)."
LIMIT ".intval($offset).", ".intval($limit));
if ($rs) {
$out = array();
$old_article = $thisarticle;
while ($c = nextRow($rs)) {
if ($form === '' && $thing === null) {
$out[] = href(
txpspecialchars($c['name']).' ('.escape_title($c['title']).')',
permlinkurl($c).'#c'.$c['discussid']
);
} else {
$thiscomment['name'] = $c['name'];
$thiscomment['email'] = $c['email'];
$thiscomment['web'] = $c['web'];
$thiscomment['message'] = $c['message'];
$thiscomment['discussid'] = $c['discussid'];
$thiscomment['time'] = $c['time'];
// Allow permlink guesstimation in permlinkurl(), elsewhere.
$thisarticle['thisid'] = $c['thisid'];
$thisarticle['posted'] = $c['posted'];
$thisarticle['title'] = $c['title'];
$thisarticle['section'] = $c['section'];
$thisarticle['url_title'] = $c['url_title'];
if ($thing === null && $form !== '') {
$out[] = parse_form($form);
} else {
$out[] = parse($thing);
}
}
}
if ($out) {
unset($GLOBALS['thiscomment']);
$thisarticle = $old_article;
return doLabel($label, $labeltag).doWrap($out, $wraptag, $break, $class);
}
}
return '';
}
// -------------------------------------------------------------
function related_articles($atts, $thing = null)
{
global $thisarticle, $prefs;
assert_article();
$atts = lAtts(array(
'break' => br,
'class' => __FUNCTION__,
'form' => '',
'label' => '',
'labeltag' => '',
'limit' => 10,
'offset' => 0,
'match' => 'Category1,Category2',
'no_widow' => @$prefs['title_no_widow'],
'section' => '',
'sort' => 'Posted DESC',
'wraptag' => '',
), $atts);
$match = array_intersect(do_list_unique(strtolower($atts['match'])), array_merge(array('category1', 'category2', 'author', 'keywords'), getCustomFields()));
$categories = $cats = array();
foreach ($match as $cf) {
switch ($cf) {
case 'category1':
case 'category2':
if (!empty($thisarticle[$cf])) {
$cats[] = $thisarticle[$cf];
}
$categories[] = ucwords($cf);
break;
case 'author':
$atts['author'] = $thisarticle['authorid'];
break;
default:
if (empty($thisarticle[$cf])) {
return;
}
$atts[$cf] = $thisarticle[$cf];
break;
}
}
if (!empty($cats)) {
$atts['category'] = implode(',', $cats);
} elseif ($categories) {
return;
}
$atts['match'] = implode(',', $categories);
$atts['exclude'] = $thisarticle['thisid'];
if ($atts['form'] === '' && $thing === null) {
$thing = '';
}
unset($atts['no_widow']);
return article_custom($atts, $thing);
}
// -------------------------------------------------------------
function popup($atts)
{
global $s, $c, $permlink_mode;
extract(lAtts(array(
'label' => gTxt('browse'),
'wraptag' => '',
'class' => '',
'section' => '',
'this_section' => 0,
'type' => 'category',
), $atts));
$type = substr($type, 0, 1);
if ($type == 's') {
$rs = safe_rows_start("name, title", 'txp_section', "name != 'default' ORDER BY name");
} else {
$rs = safe_rows_start("name, title", 'txp_category', "type = 'article' AND name != 'root' ORDER BY name");
}
if ($rs) {
$out = array();
$current = ($type == 's') ? $s : $c;
$sel = '';
$selected = false;
while ($a = nextRow($rs)) {
extract($a);
if ($name == $current) {
$sel = ' selected="selected"';
$selected = true;
}
$out[] = '';
$sel = '';
}
if ($out) {
$section = ($this_section) ? ($s == 'default' ? '' : $s) : $section;
$out = n.'';
if ($label) {
$out = $label.br.$out;
}
if ($wraptag) {
$out = doTag($out, $wraptag, $class);
}
if (($type == 's' || $permlink_mode == 'messy')) {
$action = hu;
$his = ($section !== '') ? n.hInput('s', $section) : '';
} else {
// Clean URLs for category popup.
$action = pagelinkurl(array('s' => $section));
$his = '';
}
return '
';
}
}
}
// -------------------------------------------------------------
// Output href list of site categories.
function category_list($atts, $thing = null)
{
global $s, $c, $thiscategory;
extract(lAtts(array(
'active_class' => '',
'break' => br,
'categories' => '',
'class' => __FUNCTION__,
'exclude' => '',
'form' => '',
'html_id' => '',
'label' => '',
'labeltag' => '',
'parent' => '',
'section' => '',
'children' => '1',
'sort' => '',
'this_section' => 0,
'type' => 'article',
'wraptag' => '',
'limit' => '',
'offset' => '',
), $atts));
$sort = doSlash($sort);
$sql_limit = '';
if ($limit !== '' || $offset) {
$sql_limit = " LIMIT ".intval($offset).", ".($limit === '' ? PHP_INT_MAX : intval($limit));
}
if ($categories) {
$categories = do_list_unique($categories);
$categories = join("','", doSlash($categories));
$rs = safe_rows_start("name, title, description", 'txp_category',
"type = '".doSlash($type)."' AND name IN ('$categories') ORDER BY ".($sort ? $sort : "FIELD(name, '$categories')").$sql_limit);
} else {
if ($parent) {
$parents = join(',', quote_list(do_list_unique($parent)));
}
if ($children) {
$shallow = '';
} else {
// Descend only one level from either 'parent' or 'root', plus
// parent category.
$shallow = ($parent) ? "AND (parent IN ($parents) OR name IN ($parents))" : "AND parent = 'root'";
}
if ($exclude) {
$exclude = do_list_unique($exclude);
$exclude = join("','", doSlash($exclude));
$exclude = "AND name NOT IN ('$exclude')";
}
if ($parent) {
$qs = safe_rows("lft, rgt", 'txp_category', "type = '".doSlash($type)."' AND name IN ($parents)");
if ($qs) {
$between = array();
foreach ($qs as $a) {
extract($a);
$between[] = "(lft BETWEEN $lft AND $rgt)";
}
$rs = safe_rows_start("name, title, description", 'txp_category',
"(".join(" OR ", $between).") AND type = '".doSlash($type)."' AND name != 'default' $exclude $shallow ORDER BY ".($sort ? $sort : "lft ASC").$sql_limit);
} else {
$rs = array();
}
} else {
$rs = safe_rows_start("name, title, description", 'txp_category',
"type = '".doSlash($type)."' AND name NOT IN ('default','root') $exclude $shallow ORDER BY ".($sort ? $sort : "name ASC").$sql_limit);
}
}
if ($rs) {
$out = array();
$count = 0;
$last = numRows($rs);
if (isset($thiscategory)) {
$old_category = $thiscategory;
}
while ($a = nextRow($rs)) {
++$count;
extract($a);
if ($name) {
$section = ($this_section) ? ($s == 'default' ? '' : $s) : $section;
if ($form === '' && $thing === null) {
$out[] = tag(txpspecialchars($title), 'a',
(($active_class and (0 == strcasecmp($c, $name))) ? ' class="'.txpspecialchars($active_class).'"' : '').
' href="'.pagelinkurl(array('s' => $section, 'c' => $name, 'context' => $type)).'"'
);
} else {
$thiscategory = array('name' => $name, 'title' => $title, 'type' => $type, 'description' => $description);
$thiscategory['is_first'] = ($count == 1);
$thiscategory['is_last'] = ($count == $last);
if (isset($atts['section'])) {
$thiscategory['section'] = $section;
}
if ($thing === null && $form !== '') {
$out[] = parse_form($form);
} else {
$out[] = parse($thing);
}
}
}
}
$thiscategory = (isset($old_category) ? $old_category : null);
if ($out) {
return doLabel($label, $labeltag).doWrap($out, $wraptag, $break, $class, '', '', '', $html_id);
}
}
return '';
}
// -------------------------------------------------------------
// Output href list of site sections.
function section_list($atts, $thing = null)
{
global $sitename, $s, $thissection;
extract(lAtts(array(
'active_class' => '',
'break' => br,
'class' => __FUNCTION__,
'default_title' => $sitename,
'exclude' => '',
'form' => '',
'html_id' => '',
'include_default' => '',
'label' => '',
'labeltag' => '',
'sections' => '',
'sort' => '',
'wraptag' => '',
'offset' => '',
'limit' => '',
), $atts));
$sql_limit = '';
$sql_sort = doSlash($sort);
$sql = array();
$sql[] = 1;
if ($limit !== '' || $offset) {
$sql_limit = " LIMIT ".intval($offset).", ".($limit === '' ? PHP_INT_MAX : intval($limit));
}
if ($sections) {
if ($include_default) {
$sections .= ', default';
}
$sections = join(',', quote_list(do_list_unique($sections)));
$sql[] = "name IN ($sections)";
if (!$sql_sort) {
$sql_sort = "FIELD(name, $sections)";
}
} else {
if ($exclude) {
$exclude = join(',', quote_list(do_list_unique($exclude)));
$sql[] = "name NOT IN ($exclude)";
}
if (!$include_default) {
$sql[] = "name != 'default'";
}
if (!$sql_sort) {
$sql_sort = "name ASC";
}
}
if ($include_default) {
$sql_sort = "name != 'default', ".$sql_sort;
}
$rs = safe_rows_start(
"name, title, description",
'txp_section',
join(" AND ", $sql)." ORDER BY ".$sql_sort.$sql_limit
);
if ($rs && $last = numRows($rs)) {
$out = array();
$count = 0;
if (isset($thissection)) {
$old_section = $thissection;
}
while ($a = nextRow($rs)) {
++$count;
extract($a);
if ($name == 'default') {
$title = $default_title;
}
if ($form === '' && $thing === null) {
$url = pagelinkurl(array('s' => $name));
$out[] = tag(txpspecialchars($title), 'a',
(($active_class and (0 == strcasecmp($s, $name))) ? ' class="'.txpspecialchars($active_class).'"' : '').
' href="'.$url.'"'
);
} else {
$thissection = array(
'name' => $name,
'title' => $title,
'description' => $description,
'is_first' => ($count == 1),
'is_last' => ($count == $last),
);
if ($thing === null && $form !== '') {
$out[] = parse_form($form);
} else {
$out[] = parse($thing);
}
}
}
$thissection = isset($old_section) ? $old_section : null;
if ($out) {
return doLabel($label, $labeltag).doWrap($out, $wraptag, $break, $class, '', '', '', $html_id);
}
}
return '';
}
// -------------------------------------------------------------
// Input form for search queries.
function search_input($atts)
{
global $q, $permlink_mode, $doctype;
extract(lAtts(array(
'form' => 'search_input',
'wraptag' => 'p',
'class' => __FUNCTION__,
'size' => '15',
'html_id' => '',
'label' => gTxt('search'),
'button' => '',
'section' => '',
'match' => 'exact',
), $atts));
if ($form and !array_diff_key($atts, array('form' => true))) {
$rs = fetch_form($form);
if ($rs) {
return parse($rs);
}
}
$h5 = ($doctype == 'html5');
$sub = (!empty($button)) ? '' : '';
$id = (!empty($html_id)) ? ' id="'.txpspecialchars($html_id).'"' : '';
$out = fInput($h5 ? 'search' : 'text', 'q', $q, '', '', '', $size, '', '', false, $h5);
$out = (!empty($label)) ? txpspecialchars($label).br.$out.$sub : $out.$sub;
$out = ($match === 'exact') ? $out : fInput('hidden', 'm', txpspecialchars($match)).$out;
$out = ($wraptag) ? doTag($out, $wraptag, $class) : $out;
if (!$section) {
return '';
}
if ($permlink_mode != 'messy') {
return '';
}
return '';
}
// -------------------------------------------------------------
function search_term($atts)
{
global $q;
if (empty($q)) {
return '';
}
extract(lAtts(array(
'escape' => 'html', // Deprecated in 4.5.0.
), $atts));
if (isset($atts['escape'])) {
trigger_error(gTxt('deprecated_attribute', array('{name}' => 'escape')), E_USER_NOTICE);
}
// TODO: Remove deprecated attribute 'escape'.
return ($escape == 'html' ? txpspecialchars($q) : $q);
}
// -------------------------------------------------------------
// Link to next article, if it exists.
function link_to_next($atts, $thing = null)
{
global $thisarticle;
assert_article();
extract(lAtts(array(
'showalways' => 0,
), $atts));
if (is_array($thisarticle)) {
if (!isset($thisarticle['next'])) {
$thisarticle = $thisarticle + getNextPrev();
}
if ($thisarticle['next'] !== false) {
$url = permlinkurl($thisarticle['next']);
if ($thing) {
$thing = parse($thing);
$next_title = escape_title($thisarticle['next']['title']);
return href(
$thing,
$url,
($next_title != $thing ? ' title="'.$next_title.'"' : '').
' rel="next"'
);
}
return $url;
}
}
return ($showalways) ? parse($thing) : '';
}
// -------------------------------------------------------------
// Link to previous article, if it exists.
function link_to_prev($atts, $thing = null)
{
global $thisarticle;
assert_article();
extract(lAtts(array(
'showalways' => 0,
), $atts));
if (is_array($thisarticle)) {
if (!isset($thisarticle['prev'])) {
$thisarticle = $thisarticle + getNextPrev();
}
if ($thisarticle['prev'] !== false) {
$url = permlinkurl($thisarticle['prev']);
if ($thing) {
$thing = parse($thing);
$prev_title = escape_title($thisarticle['prev']['title']);
return href(
$thing,
$url,
($prev_title != $thing ? ' title="'.$prev_title.'"' : '').
' rel="prev"'
);
}
return $url;
}
}
return ($showalways) ? parse($thing) : '';
}
// -------------------------------------------------------------
function next_title()
{
global $thisarticle;
assert_article();
if (!is_array($thisarticle)) {
return '';
}
if (!isset($thisarticle['next'])) {
$thisarticle = $thisarticle + getNextPrev();
}
if ($thisarticle['next'] !== false) {
return escape_title($thisarticle['next']['title']);
} else {
return '';
}
}
// -------------------------------------------------------------
function prev_title()
{
global $thisarticle;
assert_article();
if (!is_array($thisarticle)) {
return '';
}
if (!isset($thisarticle['prev'])) {
$thisarticle = $thisarticle + getNextPrev();
}
if ($thisarticle['prev'] !== false) {
return escape_title($thisarticle['prev']['title']);
} else {
return '';
}
}
// -------------------------------------------------------------
function site_name()
{
global $sitename;
return txpspecialchars($sitename);
}
// -------------------------------------------------------------
function site_slogan()
{
global $site_slogan;
return txpspecialchars($site_slogan);
}
// -------------------------------------------------------------
function link_to_home($atts, $thing = null)
{
extract(lAtts(array(
'class' => false,
), $atts));
if ($thing) {
$class = ($class) ? ' class="'.txpspecialchars($class).'"' : '';
return href(
parse($thing),
hu,
$class.
' rel="home"'
);
}
return hu;
}
// -------------------------------------------------------------
function newer($atts, $thing = null)
{
global $thispage, $pretext, $m;
extract(lAtts(array(
'showalways' => 0,
'title' => '',
'escape' => 'html',
), $atts));
$numPages = $thispage['numPages'];
$pg = $thispage['pg'];
if ($numPages > 1 and $pg > 1 and $pg <= $numPages) {
$nextpg = ($pg - 1 == 1) ? '' : ($pg - 1);
// Author URLs should use RealName, rather than username.
if (!empty($pretext['author'])) {
$author = get_author_name($pretext['author']);
} else {
$author = '';
}
$url = pagelinkurl(array(
'month' => @$pretext['month'],
'pg' => $nextpg,
's' => @$pretext['s'],
'c' => @$pretext['c'],
'context' => @$pretext['context'],
'q' => @$pretext['q'],
'm' => @$m,
'author' => $author,
));
if ($thing) {
if ($escape == 'html') {
$title = escape_title($title);
}
return href(
parse($thing),
$url,
(empty($title) ? '' : ' title="'.$title.'"')
);
}
return $url;
}
return ($showalways) ? parse($thing) : '';
}
// -------------------------------------------------------------
function older($atts, $thing = null)
{
global $thispage, $pretext, $m;
extract(lAtts(array(
'showalways' => 0,
'title' => '',
'escape' => 'html',
), $atts));
$numPages = $thispage['numPages'];
$pg = $thispage['pg'];
if ($numPages > 1 and $pg > 0 and $pg < $numPages) {
$nextpg = $pg + 1;
// Author URLs should use RealName, rather than username.
if (!empty($pretext['author'])) {
$author = get_author_name($pretext['author']);
} else {
$author = '';
}
$url = pagelinkurl(array(
'month' => @$pretext['month'],
'pg' => $nextpg,
's' => @$pretext['s'],
'c' => @$pretext['c'],
'context' => @$pretext['context'],
'q' => @$pretext['q'],
'm' => @$m,
'author' => $author,
));
if ($thing) {
if ($escape == 'html') {
$title = escape_title($title);
}
return href(
parse($thing),
$url,
(empty($title) ? '' : ' title="'.$title.'"')
);
}
return $url;
}
return ($showalways) ? parse($thing) : '';
}
// -------------------------------------------------------------
function text($atts)
{
extract(lAtts(array(
'item' => '',
'escape' => 'html',
), $atts, false));
if (!$item) {
return;
}
unset(
$atts['item'],
$atts['escape']
);
$tags = array();
foreach ($atts as $name => $value) {
$tags['{'.$name.'}'] = $value;
}
return gTxt($item, $tags, $escape);
}
// -------------------------------------------------------------
function article_id()
{
global $thisarticle;
assert_article();
return $thisarticle['thisid'];
}
// -------------------------------------------------------------
function article_url_title()
{
global $thisarticle;
assert_article();
return $thisarticle['url_title'];
}
// -------------------------------------------------------------
function if_article_id($atts, $thing)
{
global $thisarticle, $pretext;
assert_article();
extract(lAtts(array(
'id' => $pretext['id'],
), $atts));
if ($id) {
return parse($thing, in_list($thisarticle['thisid'], $id));
}
}
// -------------------------------------------------------------
function posted($atts)
{
global $thisarticle, $id, $c, $pg, $dateformat, $archive_dateformat;
assert_article();
extract(lAtts(array(
'class' => '',
'format' => '',
'gmt' => '',
'lang' => '',
'wraptag' => '',
), $atts));
if ($format) {
$out = safe_strftime($format, $thisarticle['posted'], $gmt, $lang);
} else {
if ($id or $c or $pg) {
$out = safe_strftime($archive_dateformat, $thisarticle['posted'], $gmt, $lang);
} else {
$out = safe_strftime($dateformat, $thisarticle['posted'], $gmt, $lang);
}
}
return ($wraptag) ? doTag($out, $wraptag, $class) : $out;
}
// -------------------------------------------------------------
function expires($atts)
{
global $thisarticle, $id, $c, $pg, $dateformat, $archive_dateformat;
assert_article();
if ($thisarticle['expires'] == 0) {
return;
}
extract(lAtts(array(
'class' => '',
'format' => '',
'gmt' => '',
'lang' => '',
'wraptag' => '',
), $atts));
if ($format) {
$out = safe_strftime($format, $thisarticle['expires'], $gmt, $lang);
} else {
if ($id or $c or $pg) {
$out = safe_strftime($archive_dateformat, $thisarticle['expires'], $gmt, $lang);
} else {
$out = safe_strftime($dateformat, $thisarticle['expires'], $gmt, $lang);
}
}
return ($wraptag) ? doTag($out, $wraptag, $class) : $out;
}
// -------------------------------------------------------------
function if_expires($atts, $thing)
{
global $thisarticle;
assert_article();
return parse($thing, !empty($thisarticle['expires']));
}
// -------------------------------------------------------------
function if_expired($atts, $thing)
{
global $thisarticle;
assert_article();
return parse($thing,
!empty($thisarticle['expires']) && ($thisarticle['expires'] <= time()));
}
// -------------------------------------------------------------
function modified($atts)
{
global $thisarticle, $id, $c, $pg, $dateformat, $archive_dateformat;
assert_article();
extract(lAtts(array(
'class' => '',
'format' => '',
'gmt' => '',
'lang' => '',
'wraptag' => '',
), $atts));
if ($format) {
$out = safe_strftime($format, $thisarticle['modified'], $gmt, $lang);
} else {
if ($id or $c or $pg) {
$out = safe_strftime($archive_dateformat, $thisarticle['modified'], $gmt, $lang);
} else {
$out = safe_strftime($dateformat, $thisarticle['modified'], $gmt, $lang);
}
}
return ($wraptag) ? doTag($out, $wraptag, $class) : $out;
}
// -------------------------------------------------------------
function comments_count()
{
global $thisarticle;
assert_article();
return $thisarticle['comments_count'];
}
// -------------------------------------------------------------
function comments_invite($atts)
{
global $thisarticle, $is_article_list;
assert_article();
extract($thisarticle);
global $comments_mode;
if (!$comments_invite) {
$comments_invite = get_pref('comments_default_invite');
}
extract(lAtts(array(
'class' => __FUNCTION__,
'showcount' => true,
'textonly' => false,
'showalways' => false, // FIXME in crockery. This is only for BC.
'wraptag' => '',
), $atts));
$invite_return = '';
if (($annotate or $comments_count) && ($showalways or $is_article_list)) {
$comments_invite = txpspecialchars($comments_invite);
$ccount = ($comments_count && $showcount) ? ' ['.$comments_count.']' : '';
if ($textonly) {
$invite_return = $comments_invite.$ccount;
} else {
if (!$comments_mode) {
$invite_return = doTag($comments_invite, 'a', $class, ' href="'.permlinkurl($thisarticle).'#'.gTxt('comment').'" ').$ccount;
} else {
$invite_return = "'.$comments_invite.' '.$ccount;
}
}
if ($wraptag) {
$invite_return = doTag($invite_return, $wraptag, $class);
}
}
return $invite_return;
}
// -------------------------------------------------------------
function popup_comments($atts, $thing = null)
{
extract(lAtts(array(
'form' => 'comments_display'
), $atts));
$rs = safe_row(
"*, UNIX_TIMESTAMP(Posted) AS uPosted, UNIX_TIMESTAMP(LastMod) AS uLastMod, UNIX_TIMESTAMP(Expires) AS uExpires",
'textpattern',
"ID=".intval(gps('parentid'))." AND Status >= 4"
);
if ($rs) {
populateArticleData($rs);
return ($thing === null ? parse_form($form) : parse($thing));
}
return '';
}
// -------------------------------------------------------------
function comments_form($atts, $thing = null)
{
global $thisarticle, $has_comments_preview;
global $thiscommentsform; // TODO: Remove any uses of $thiscommentsform when removing deprecated attributes from below.
// deprecated attributes since TXP 4.6. Most of these (except msgstyle)
// were moved to the tags that occur within a comments_form, although
// some of the names changed.
$deprecated = array('isize', 'msgrows', 'msgcols', 'msgstyle',
'previewlabel', 'submitlabel', 'rememberlabel', 'forgetlabel');
foreach ($deprecated as $att) {
if (isset($atts[$att])) {
trigger_error(gTxt('deprecated_attribute', array('{name}' => $att)), E_USER_NOTICE);
}
}
$atts = lAtts(array(
'class' => __FUNCTION__,
'form' => 'comment_form',
'isize' => '25',
'msgcols' => '25',
'msgrows' => '5',
'msgstyle' => '',
'show_preview' => empty($has_comments_preview),
'wraptag' => '',
'previewlabel' => gTxt('preview'),
'submitlabel' => gTxt('submit'),
'rememberlabel' => gTxt('remember'),
'forgetlabel' => gTxt('forget'),
), $atts);
extract($atts);
$thiscommentsform = array_intersect_key($atts, array_flip($deprecated));
assert_article();
extract($thisarticle);
$out = '';
$ip = serverset('REMOTE_ADDR');
$blacklisted = is_blacklisted($ip);
if (!checkCommentsAllowed($thisid)) {
$out = graf(gTxt("comments_closed"), ' id="comments_closed"');
} elseif ($blacklisted) {
$out = graf(gTxt('your_ip_is_blacklisted_by'.' '.$blacklisted), ' id="comments_blacklisted"');
} elseif (gps('commented') !== '') {
$out = gTxt("comment_posted");
if (gps('commented') === '0') {
$out .= " ".gTxt("comment_moderated");
}
$out = graf($out, ' id="txpCommentInputForm"');
} else {
// Display a comment preview if required.
if (ps('preview') and $show_preview) {
$out = comments_preview(array());
}
extract(doDeEnt(psa(array(
'parentid',
'backpage',
))));
// If the form fields are filled (anything other than blank), pages really
// should not be saved by a public cache (rfc2616/14.9.1).
if (pcs('name') || pcs('email') || pcs('web')) {
header('Cache-Control: private');
}
$url = $GLOBALS['pretext']['request_uri'];
// Experimental clean URLs with only 404-error-document on Apache possibly
// requires messy URLs for POST requests.
if (defined('PARTLY_MESSY') and (PARTLY_MESSY)) {
$url = hu.'?id='.intval($parentid);
}
$out .= '';
}
return (!$wraptag ? $out : doTag($out, $wraptag, $class));
}
// -------------------------------------------------------------
function comment_name_input($atts)
{
global $prefs, $thiscommentsform;
extract(lAtts(array(
'size' => $thiscommentsform['isize']
), $atts));
$namewarn = false;
$name = pcs('name');
$h5 = ($prefs['doctype'] == 'html5');
if (ps('preview')) {
$comment = getComment();
$name = $comment['name'];
$namewarn = ($prefs['comments_require_name'] && !$name);
}
return fInput('text', 'name', $name, 'comment_name_input'.($namewarn ? ' comments_error' : ''), '', '', $size, '', 'name', false, $h5 && $prefs['comments_require_name']);
}
// -------------------------------------------------------------
function comment_email_input($atts)
{
global $prefs, $thiscommentsform;
extract(lAtts(array(
'size' => $thiscommentsform['isize']
), $atts));
$emailwarn = false;
$email = clean_url(pcs('email'));
$h5 = ($prefs['doctype'] == 'html5');
if (ps('preview')) {
$comment = getComment();
$email = $comment['email'];
$emailwarn = ($prefs['comments_require_email'] && !$email);
}
return fInput($h5 ? 'email' : 'text', 'email', $email, 'comment_email_input'.($emailwarn ? ' comments_error' : ''), '', '', $size, '', 'email', false, $h5 && $prefs['comments_require_email']);
}
// -------------------------------------------------------------
function comment_web_input($atts)
{
global $prefs, $thiscommentsform;
extract(lAtts(array(
'size' => $thiscommentsform['isize']
), $atts));
$web = clean_url(pcs('web'));
$h5 = ($prefs['doctype'] == 'html5');
if (ps('preview')) {
$comment = getComment();
$web = $comment['web'];
}
return fInput($h5 ? 'text' : 'text', 'web', $web, 'comment_web_input', '', '', $size, '', 'web', false, false); /* TODO: maybe use type = 'url' once browsers are less strict */
}
// -------------------------------------------------------------
function comment_message_input($atts)
{
global $prefs, $thiscommentsform;
extract(lAtts(array(
'rows' => $thiscommentsform['msgrows'],
'cols' => $thiscommentsform['msgcols']
), $atts));
$style = $thiscommentsform['msgstyle'];
$commentwarn = false;
$n_message = 'message';
$formnonce = '';
$message = '';
if (ps('preview')) {
$comment = getComment();
$message = $comment['message'];
$split = rand(1, 31);
$nonce = getNextNonce();
$secret = getNextSecret();
safe_insert('txp_discuss_nonce', "issue_time = NOW(), nonce = '".doSlash($nonce)."', secret = '".doSlash($secret)."'");
$n_message = md5('message'.$secret);
$formnonce = n.hInput(substr($nonce, 0, $split), substr($nonce, $split));
$commentwarn = (!trim($message));
}
$required = ($prefs['doctype'] == 'html5') ? ' required' : '';
$cols = ($cols and is_numeric($cols)) ? ' cols="'.intval($cols).'"' : '';
$rows = ($rows and is_numeric($rows)) ? ' rows="'.intval($rows).'"' : '';
$style = ($style ? ' style="'.$style.'"' : '');
return ''.
callback_event('comment.form').
$formnonce;
}
// -------------------------------------------------------------
function comment_remember($atts)
{
global $thiscommentsform;
extract(lAtts(array(
'rememberlabel' => $thiscommentsform['rememberlabel'],
'forgetlabel' => $thiscommentsform['forgetlabel']
), $atts));
extract(doDeEnt(psa(array(
'checkbox_type',
'remember',
'forget'
))));
if (!ps('preview')) {
$rememberCookie = cs('txp_remember');
if ($rememberCookie === '') {
$checkbox_type = 'remember';
$remember = 1;
} elseif ($rememberCookie == 1) {
$checkbox_type = 'forget';
} else {
$checkbox_type = 'remember';
}
}
if ($checkbox_type == 'forget') {
// Inhibit default remember.
if ($forget == 1) {
destroyCookies();
}
$checkbox = checkbox('forget', 1, $forget, '', 'forget').' '.tag(txpspecialchars($forgetlabel), 'label', ' for="forget"');
} else {
// Inhibit default remember.
if ($remember != 1) {
destroyCookies();
}
$checkbox = checkbox('remember', 1, $remember, '', 'remember').' '.tag(txpspecialchars($rememberlabel), 'label', ' for="remember"');
}
$checkbox .= ' '.hInput('checkbox_type', $checkbox_type);
return $checkbox;
}
// -------------------------------------------------------------
function comment_preview($atts)
{
global $thiscommentsform;
extract(lAtts(array(
'label' => $thiscommentsform['previewlabel']
), $atts));
return fInput('submit', 'preview', $label, 'button', '', '', '', '', 'txpCommentPreview', false);
}
// -------------------------------------------------------------
function comment_submit($atts)
{
global $thiscommentsform;
extract(lAtts(array(
'label' => $thiscommentsform['submitlabel']
), $atts));
// If all fields check out, the submit button is active/clickable.
if (ps('preview')) {
return fInput('submit', 'submit', $label, 'button', '', '', '', '', 'txpCommentSubmit', false);
} else {
return fInput('submit', 'submit', $label, 'button disabled', '', '', '', '', 'txpCommentSubmit', true);
}
}
// -------------------------------------------------------------
function comments_error($atts)
{
extract(lAtts(array(
'break' => 'br',
'class' => __FUNCTION__,
'wraptag' => 'div',
), $atts));
$evaluator = & get_comment_evaluator();
$errors = $evaluator->get_result_message();
if ($errors) {
return doWrap($errors, $wraptag, $break, $class);
}
}
// -------------------------------------------------------------
function if_comments_error($atts, $thing)
{
$evaluator = & get_comment_evaluator();
return parse($thing, (count($evaluator->get_result_message()) > 0));
}
/**
* Renders a heading for comments.
*
* @param array $atts
* @param string $thing
* @return string
* @deprecated in 4.0.0
*/
function comments_annotateinvite($atts, $thing)
{
trigger_error(gTxt('deprecated_tag'), E_USER_NOTICE);
global $thisarticle, $pretext;
extract(lAtts(array(
'class' => __FUNCTION__,
'wraptag' => 'h3',
), $atts));
assert_article();
extract($thisarticle);
extract(safe_row(
"Annotate, AnnotateInvite, UNIX_TIMESTAMP(Posted) AS uPosted",
'textpattern',
"ID = ".intval($thisid)
));
if (!$thing) {
$thing = $AnnotateInvite;
}
return (!$Annotate) ? '' : doTag($thing, $wraptag, $class, ' id="'.gTxt('comment').'"');
}
// -------------------------------------------------------------
function comments($atts, $thing = null)
{
global $thisarticle, $prefs;
extract($prefs);
extract(lAtts(array(
'form' => 'comments',
'wraptag' => ($comments_are_ol ? 'ol' : ''),
'break' => ($comments_are_ol ? 'li' : 'div'),
'class' => __FUNCTION__,
'breakclass' => '', // Deprecated in 4.6.0
'limit' => 0,
'offset' => 0,
'sort' => 'posted ASC',
), $atts));
assert_article();
if (isset($atts['breakclass'])) {
trigger_error(gTxt('deprecated_attribute', array('{name}' => 'breakclass')), E_USER_NOTICE);
}
extract($thisarticle);
if (!$comments_count) {
return '';
}
$qparts = array(
"parentid = ".intval($thisid)." AND visible = ".VISIBLE,
"ORDER BY ".doSlash($sort),
($limit) ? "LIMIT ".intval($offset).", ".intval($limit) : '',
);
$rs = safe_rows_start("*, UNIX_TIMESTAMP(posted) AS time", 'txp_discuss', join(' ', $qparts));
$out = '';
if ($rs) {
$comments = array();
while ($vars = nextRow($rs)) {
$GLOBALS['thiscomment'] = $vars;
$comments[] = ($thing === null ? parse_form($form) : parse($thing)).n;
unset($GLOBALS['thiscomment']);
}
$out .= doWrap($comments, $wraptag, $break, $class, $breakclass);
}
return $out;
}
// -------------------------------------------------------------
function comments_preview($atts, $thing = null)
{
global $has_comments_preview;
if (!ps('preview')) {
return;
}
extract(lAtts(array(
'form' => 'comments',
'wraptag' => '',
'class' => __FUNCTION__,
), $atts));
assert_article();
$preview = psa(array('name', 'email', 'web', 'message', 'parentid', 'remember'));
$preview['time'] = time();
$preview['discussid'] = 0;
$preview['name'] = strip_tags($preview['name']);
$preview['email'] = clean_url($preview['email']);
if ($preview['message'] == '') {
$in = getComment();
$preview['message'] = $in['message'];
}
// It is called 'message', not 'novel'!
$preview['message'] = markup_comment(substr(trim($preview['message']), 0, 65535));
$preview['web'] = clean_url($preview['web']);
$GLOBALS['thiscomment'] = $preview;
$comments = ($thing === null ? parse_form($form) : parse($thing)).n;
unset($GLOBALS['thiscomment']);
$out = doTag($comments, $wraptag, $class);
// Set a flag to tell the comments_form tag that it doesn't have to show
// a preview.
$has_comments_preview = true;
return $out;
}
// -------------------------------------------------------------
function if_comments_preview($atts, $thing)
{
return parse($thing, ps('preview') && checkCommentsAllowed(gps('parentid')));
}
// -------------------------------------------------------------
function comment_permlink($atts, $thing)
{
global $thisarticle, $thiscomment;
assert_article();
assert_comment();
extract($thiscomment);
extract(lAtts(array(
'anchor' => empty($thiscomment['has_anchor_tag']),
), $atts));
$dlink = permlinkurl($thisarticle).'#c'.$discussid;
$thing = parse($thing);
$name = ($anchor ? ' id="c'.$discussid.'"' : '');
return tag($thing, 'a', ' href="'.$dlink.'"'.$name);
}
// -------------------------------------------------------------
function comment_id()
{
global $thiscomment;
assert_comment();
return $thiscomment['discussid'];
}
// -------------------------------------------------------------
function comment_name($atts)
{
global $thiscomment, $prefs;
assert_comment();
extract($prefs);
extract($thiscomment);
extract(lAtts(array(
'link' => 1,
), $atts));
$name = txpspecialchars($name);
if ($link) {
$web = comment_web();
$nofollow = (@$comment_nofollow ? ' rel="nofollow"' : '');
if (!empty($web)) {
return href($name, $web, $nofollow);
}
if ($email && !$never_display_email) {
return href($name, eE('mailto:'.$email), $nofollow);
}
}
return $name;
}
// -------------------------------------------------------------
function comment_email()
{
global $thiscomment;
assert_comment();
return txpspecialchars($thiscomment['email']);
}
// -------------------------------------------------------------
function comment_web()
{
global $thiscomment;
assert_comment();
if (preg_match('/^\S/', $thiscomment['web'])) {
// Prepend default protocol 'http' for all non-local URLs.
if (!preg_match('!^https?://|^#|^/[^/]!', $thiscomment['web'])) {
$thiscomment['web'] = 'http://'.$thiscomment['web'];
}
return txpspecialchars($thiscomment['web']);
}
return '';
}
// -------------------------------------------------------------
function comment_time($atts)
{
global $thiscomment, $comments_dateformat;
assert_comment();
extract(lAtts(array(
'format' => $comments_dateformat,
'gmt' => '',
'lang' => '',
), $atts));
return safe_strftime($format, $thiscomment['time'], $gmt, $lang);
}
// -------------------------------------------------------------
function comment_message()
{
global $thiscomment;
assert_comment();
return $thiscomment['message'];
}
// -------------------------------------------------------------
function comment_anchor()
{
global $thiscomment;
assert_comment();
$thiscomment['has_anchor_tag'] = 1;
return '';
}
// -------------------------------------------------------------
function author($atts)
{
global $thisarticle, $thisauthor, $s, $author;
extract(lAtts(array(
'escape' => 'html',
'link' => 0,
'title' => 1,
'section' => '',
'this_section' => 0,
'format' => '', // empty, link, or url
), $atts));
// Synonym.
if ($format === 'link') {
$link = 1;
}
if ($thisauthor) {
$realname = $thisauthor['realname'];
$name = $thisauthor['name'];
} elseif ($author) {
$realname = get_author_name($author);
$name = $author;
} else {
assert_article();
$realname = get_author_name($thisarticle['authorid']);
$name = $thisarticle['authorid'];
}
if ($title) {
$display_name = $realname;
} else {
$display_name = $name;
}
$display_name = ($escape === 'html') ? txpspecialchars($display_name) : $display_name;
if ($this_section && $s != 'default') {
$section = $s;
}
$href = pagelinkurl(array(
's' => $section,
'author' => $realname,
));
if ($format === 'url') {
return $href;
}
if ($link) {
return href($display_name, $href, ' rel="author"');
}
return $display_name;
}
// -------------------------------------------------------------
function author_email($atts)
{
global $thisarticle, $thisauthor;
extract(lAtts(array(
'escape' => 'html',
'link' => '',
), $atts));
if ($thisauthor) {
$email = get_author_email($thisauthor['name']);
} else {
assert_article();
$email = get_author_email($thisarticle['authorid']);
}
if ($escape == 'html') {
$display_email = txpspecialchars($email);
} else {
$display_email = $email;
}
if ($link) {
return email(array(
'email' => $email,
'linktext' => $display_email,
));
}
return $display_email;
}
// -------------------------------------------------------------
function if_author($atts, $thing)
{
global $author, $context, $thisauthor;
extract(lAtts(array(
'type' => 'article',
'name' => '',
), $atts));
if ($thisauthor) {
return parse($thing, $name === '' || in_list($thisauthor['name'], $name));
}
$theType = ($type) ? $type == $context : true;
if ($name) {
return parse($thing, ($theType && in_list($author, $name)));
}
return parse($thing, ($theType && (string) $author !== ''));
}
// -------------------------------------------------------------
function if_article_author($atts, $thing)
{
global $thisarticle;
assert_article();
extract(lAtts(array(
'name' => '',
), $atts));
$author = $thisarticle['authorid'];
if ($name) {
return parse($thing, in_list($author, $name));
}
return parse($thing, (string) $author !== '');
}
// -------------------------------------------------------------
function body()
{
global $thisarticle, $is_article_body;
assert_article();
$was_article_body = $is_article_body;
$is_article_body = 1;
$out = parse($thisarticle['body']);
$is_article_body = $was_article_body;
return $out;
}
// -------------------------------------------------------------
function title($atts)
{
global $thisarticle, $prefs;
assert_article();
extract(lAtts(array(
'no_widow' => @$prefs['title_no_widow'],
), $atts));
$t = escape_title($thisarticle['title']);
if ($no_widow) {
$t = noWidow($t);
}
return $t;
}
// -------------------------------------------------------------
function excerpt()
{
global $thisarticle, $is_article_body;
assert_article();
$was_article_body = $is_article_body;
$is_article_body = 1;
$out = parse($thisarticle['excerpt']);
$is_article_body = $was_article_body;
return $out;
}
// -------------------------------------------------------------
function category1($atts, $thing = null)
{
global $thisarticle, $s, $permlink_mode;
assert_article();
extract(lAtts(array(
'class' => '',
'link' => 0,
'title' => 0,
'section' => '',
'this_section' => 0,
'wraptag' => '',
), $atts));
if ($thisarticle['category1']) {
$section = ($this_section) ? ($s == 'default' ? '' : $s) : $section;
$category = $thisarticle['category1'];
$label = txpspecialchars(($title) ? fetch_category_title($category) : $category);
if ($thing) {
$out = href(
parse($thing),
pagelinkurl(array('s' => $section, 'c' => $category)),
(($class and !$wraptag) ? ' class="'.txpspecialchars($class).'"' : '').
($title ? ' title="'.$label.'"' : '').
($permlink_mode != 'messy' ? ' rel="category tag"' : '')
);
} elseif ($link) {
$out = href(
$label,
pagelinkurl(array('s' => $section, 'c' => $category)),
($permlink_mode != 'messy' ? ' rel="category tag"' : '')
);
} else {
$out = $label;
}
return doTag($out, $wraptag, $class);
}
}
// -------------------------------------------------------------
function category2($atts, $thing = null)
{
global $thisarticle, $s, $permlink_mode;
assert_article();
extract(lAtts(array(
'class' => '',
'link' => 0,
'title' => 0,
'section' => '',
'this_section' => 0,
'wraptag' => '',
), $atts));
if ($thisarticle['category2']) {
$section = ($this_section) ? ($s == 'default' ? '' : $s) : $section;
$category = $thisarticle['category2'];
$label = txpspecialchars(($title) ? fetch_category_title($category) : $category);
if ($thing) {
$out = href(
parse($thing),
pagelinkurl(array('s' => $section, 'c' => $category)),
(($class and !$wraptag) ? ' class="'.txpspecialchars($class).'"' : '').
($title ? ' title="'.$label.'"' : '').
($permlink_mode != 'messy' ? ' rel="category tag"' : '')
);
} elseif ($link) {
$out = href(
$label,
pagelinkurl(array('s' => $section, 'c' => $category)),
($permlink_mode != 'messy' ? ' rel="category tag"' : '')
);
} else {
$out = $label;
}
return doTag($out, $wraptag, $class);
}
}
// -------------------------------------------------------------
function category($atts, $thing = null)
{
global $s, $c, $thiscategory, $context;
extract(lAtts(array(
'class' => '',
'link' => 0,
'name' => '',
'section' => $s,
'this_section' => 0,
'title' => 0,
'type' => 'article',
'url' => 0,
'wraptag' => '',
), $atts));
if ($name) {
$category = $name;
} elseif (!empty($thiscategory['name'])) {
$category = $thiscategory['name'];
$type = $thiscategory['type'];
} else {
$category = $c;
if (!isset($atts['type'])) {
$type = $context;
}
}
if ($category) {
if ($this_section) {
$section = ($s == 'default' ? '' : $s);
} elseif (isset($thiscategory['section'])) {
$section = $thiscategory['section'];
}
$label = txpspecialchars(($title) ? fetch_category_title($category, $type) : $category);
$href = pagelinkurl(array('s' => $section, 'c' => $category, 'context' => $type));
if ($thing) {
$out = href(
parse($thing),
$href,
(($class and !$wraptag) ? ' class="'.txpspecialchars($class).'"' : '').
($title ? ' title="'.$label.'"' : '')
);
} elseif ($link) {
$out = href(
$label,
$href,
($class and !$wraptag) ? ' class="'.txpspecialchars($class).'"' : ''
);
} elseif ($url) {
$out = $href;
} else {
$out = $label;
}
return doTag($out, $wraptag, $class);
}
}
// -------------------------------------------------------------
function section($atts, $thing = null)
{
global $thisarticle, $s, $thissection;
extract(lAtts(array(
'class' => '',
'link' => 0,
'name' => '',
'title' => 0,
'url' => 0,
'wraptag' => '',
), $atts));
if ($name) {
$sec = $name;
} elseif (!empty($thissection['name'])) {
$sec = $thissection['name'];
} elseif (!empty($thisarticle['section'])) {
$sec = $thisarticle['section'];
} else {
$sec = $s;
}
if ($sec) {
$label = txpspecialchars(($title) ? fetch_section_title($sec) : $sec);
$href = pagelinkurl(array('s' => $sec));
if ($thing) {
$out = href(
parse($thing),
$href,
(($class and !$wraptag) ? ' class="'.txpspecialchars($class).'"' : '').
($title ? ' title="'.$label.'"' : '')
);
} elseif ($link) {
$out = href(
$label,
$href,
($class and !$wraptag) ? ' class="'.txpspecialchars($class).'"' : ''
);
} elseif ($url) {
$out = $href;
} else {
$out = $label;
}
return doTag($out, $wraptag, $class);
}
}
// -------------------------------------------------------------
function keywords()
{
global $thisarticle;
assert_article();
trigger_error(gTxt('deprecated_tag'), E_USER_NOTICE);
return txpspecialchars($thisarticle['keywords']);
}
// -------------------------------------------------------------
function if_keywords($atts, $thing = null)
{
global $thisarticle;
assert_article();
extract(lAtts(array(
'keywords' => '',
), $atts));
$condition = empty($keywords)
? $thisarticle['keywords']
: array_intersect(do_list($keywords), do_list($thisarticle['keywords']));
return parse($thing, !empty($condition));
}
// -------------------------------------------------------------
function if_article_image($atts, $thing = '')
{
global $thisarticle;
assert_article();
return parse($thing, !empty($thisarticle['article_image']));
}
// -------------------------------------------------------------
function article_image($atts)
{
global $thisarticle;
assert_article();
extract(lAtts(array(
'class' => '',
'escape' => 'html',
'html_id' => '',
'style' => '',
'width' => '',
'height' => '',
'thumbnail' => 0,
'wraptag' => '',
), $atts));
if ($thisarticle['article_image']) {
$image = $thisarticle['article_image'];
} else {
return;
}
if (intval($image)) {
$rs = safe_row("*", 'txp_image', "id = ".intval($image));
if ($rs) {
$width = ($width == '') ? (($thumbnail) ? $rs['thumb_w'] : $rs['w']) : $width;
$height = ($height == '') ? (($thumbnail) ? $rs['thumb_h'] : $rs['h']) : $height;
if ($thumbnail) {
if ($rs['thumbnail']) {
extract($rs);
if ($escape == 'html') {
$alt = txpspecialchars($alt);
$caption = txpspecialchars($caption);
}
$out = '';
} else {
return '';
}
} else {
extract($rs);
if ($escape == 'html') {
$alt = txpspecialchars($alt);
$caption = txpspecialchars($caption);
}
$out = '';
}
} else {
trigger_error(gTxt('unknown_image'));
return;
}
} else {
$out = '';
}
return ($wraptag) ? doTag($out, $wraptag, $class, '', $html_id) : $out;
}
// -------------------------------------------------------------
function search_result_title($atts)
{
return permlink($atts, '');
}
// -------------------------------------------------------------
function search_result_excerpt($atts)
{
global $thisarticle, $pretext;
assert_article();
extract(lAtts(array(
'break' => ' …',
'hilight' => 'strong',
'limit' => 5,
), $atts));
$m = $pretext['m'];
$q = $pretext['q'];
$quoted = ($q[0] === '"') && ($q[strlen($q) - 1] === '"');
$q = $quoted ? trim(trim($q, '"')) : trim($q);
$result = preg_replace('/\s+/', ' ', strip_tags(str_replace('><', '> <', $thisarticle['body'])));
if ($quoted || empty($m) || $m === 'exact') {
$regex_search = '/(?:\G|\s).{0,50}'.preg_quote($q, '/').'.{0,50}(?:\s|$)/iu';
$regex_hilite = '/('.preg_quote($q, '/').')/i';
} else {
$regex_search = '/(?:\G|\s).{0,50}('.preg_replace('/\s+/', '|', preg_quote($q, '/')).').{0,50}(?:\s|$)/iu';
$regex_hilite = '/('.preg_replace('/\s+/', '|', preg_quote($q, '/')).')/i';
}
preg_match_all($regex_search, $result, $concat);
$concat = $concat[0];
for ($i = 0, $r = array(); $i < min($limit, count($concat)); $i++) {
$r[] = trim($concat[$i]);
}
$concat = join($break.n, $r);
$concat = preg_replace('/^[^>]+>/U', '', $concat);
// TODO:
$concat = preg_replace($regex_hilite, "<$hilight>$1$hilight>", $concat);
return ($concat) ? trim($break.$concat.$break) : '';
}
// -------------------------------------------------------------
function search_result_url($atts)
{
global $thisarticle;
assert_article();
$l = permlinkurl($thisarticle);
return permlink($atts, $l);
}
// -------------------------------------------------------------
function search_result_date($atts)
{
assert_article();
return posted($atts);
}
// -------------------------------------------------------------
function search_result_count($atts)
{
global $thispage;
$t = @$thispage['grand_total'];
extract(lAtts(array(
'text' => ($t == 1 ? gTxt('article_found') : gTxt('articles_found')),
), $atts));
return $t.($text ? ' '.$text : '');
}
// -------------------------------------------------------------
function image_index($atts)
{
global $s, $c, $p, $path_to_site;
extract(lAtts(array(
'label' => '',
'break' => br,
'wraptag' => '',
'class' => __FUNCTION__,
'labeltag' => '',
'c' => $c, // Keep the option to override categories due to backward compatibility.
'category' => $c,
'limit' => 0,
'offset' => 0,
'sort' => 'name ASC',
), $atts));
if (isset($atts['c'])) {
trigger_error(gTxt('deprecated_attribute', array('{name}' => 'c')), E_USER_NOTICE);
}
if (isset($atts['category'])) {
// Override the global.
$c = $category;
}
$qparts = array(
"category = '".doSlash($c)."' AND thumbnail = 1",
"ORDER BY ".doSlash($sort),
($limit) ? "LIMIT ".intval($offset).", ".intval($limit) : '',
);
$rs = safe_rows_start("*", 'txp_image', join(' ', $qparts));
if ($rs) {
$out = array();
while ($a = nextRow($rs)) {
extract($a);
$dims = ($thumb_h ? " height=\"$thumb_h\"" : '').($thumb_w ? " width=\"$thumb_w\"" : '');
$url = pagelinkurl(array(
'c' => $c,
'context' => 'image',
's' => $s,
'p' => $id,
));
$out[] = href(
'',
$url
);
}
if (count($out)) {
return doLabel($label, $labeltag).doWrap($out, $wraptag, $break, $class);
}
}
return '';
}
// -------------------------------------------------------------
function image_display($atts)
{
if (is_array($atts)) {
extract($atts);
}
global $s, $c, $p;
if ($p) {
$rs = safe_row("*", 'txp_image', "id=".intval($p)." LIMIT 1");
if ($rs) {
extract($rs);
return '';
}
}
}
// -------------------------------------------------------------
function images($atts, $thing = null)
{
global $s, $c, $context, $p, $path_to_site, $thisimage, $thisarticle, $thispage, $pretext;
extract(lAtts(array(
'name' => '',
'id' => '',
'category' => '',
'author' => '',
'realname' => '',
'extension' => '',
'thumbnail' => '',
'auto_detect' => 'article, category, author',
'label' => '',
'break' => br,
'wraptag' => '',
'class' => __FUNCTION__,
'html_id' => '',
'labeltag' => '',
'form' => '',
'pageby' => '',
'limit' => 0,
'offset' => 0,
'sort' => 'name ASC',
), $atts));
$safe_sort = doSlash($sort);
$where = array();
$has_content = $thing || $form;
$filters = isset($atts['id']) || isset($atts['name']) || isset($atts['category']) || isset($atts['author']) || isset($atts['realname']) || isset($atts['extension']) || $thumbnail === '1' || $thumbnail === '0';
$context_list = (empty($auto_detect) || $filters) ? array() : do_list_unique($auto_detect);
$pageby = ($pageby == 'limit') ? $limit : $pageby;
if ($name) {
$where[] = "name IN ('".join("','", doSlash(do_list_unique($name)))."')";
}
if ($category) {
$where[] = "category IN ('".join("','", doSlash(do_list_unique($category)))."')";
}
if ($id) {
$where[] = "id IN ('".join("','", doSlash(do_list_unique($id)))."')";
}
if ($author) {
$where[] = "author IN ('".join("','", doSlash(do_list_unique($author)))."')";
}
if ($realname) {
$authorlist = safe_column("name", 'txp_users', "RealName IN ('".join("','", doArray(doSlash(do_list_unique($realname)), 'urldecode'))."')");
if ($authorlist) {
$where[] = "author IN ('".join("','", doSlash($authorlist))."')";
}
}
if ($extension) {
$where[] = "ext IN ('".join("','", doSlash(do_list_unique($extension)))."')";
}
if ($thumbnail === '0' || $thumbnail === '1') {
$where[] = "thumbnail = $thumbnail";
}
// If no images are selected, try...
if (!$where && !$filters) {
foreach ($context_list as $ctxt) {
switch ($ctxt) {
case 'article':
// ...the article image field.
if ($thisarticle && !empty($thisarticle['article_image'])) {
$items = do_list_unique($thisarticle['article_image']);
foreach ($items as &$item) {
if (is_numeric($item)) {
$item = intval($item);
} else {
return article_image(compact('class', 'html_id', 'wraptag'));
}
}
$items = join(",", $items);
// Note: This clause will squash duplicate ids.
$where[] = "id IN ($items)";
// Order of ids in article image field overrides default 'sort' attribute.
if (empty($atts['sort'])) {
$safe_sort = "FIELD(id, $items)";
}
}
break;
case 'category':
// ...the global category in the URL.
if ($context == 'image' && !empty($c)) {
$where[] = "category = '".doSlash($c)."'";
}
break;
case 'author':
// ...the global author in the URL.
if ($context == 'image' && !empty($pretext['author'])) {
$where[] = "author = '".doSlash($pretext['author'])."'";
}
break;
}
// Only one context can be processed.
if ($where) {
break;
}
}
}
// Order of ids in 'id' attribute overrides default 'sort' attribute.
if (empty($atts['sort']) && $id !== '') {
$safe_sort = "FIELD(id, ".join(',', doSlash(do_list_unique($id))).")";
}
// If nothing matches, output nothing.
if (!$where && $filters) {
return '';
}
// If nothing matches, start with all images.
if (!$where) {
$where[] = "1 = 1";
}
$where = join(" AND ", $where);
// Set up paging if required.
if ($limit && $pageby) {
$grand_total = safe_count('txp_image', $where);
$total = $grand_total - $offset;
$numPages = ($pageby > 0) ? ceil($total / $pageby) : 1;
$pg = (!$pretext['pg']) ? 1 : $pretext['pg'];
$pgoffset = $offset + (($pg - 1) * $pageby);
// Send paging info to txp:newer and txp:older.
$pageout['pg'] = $pg;
$pageout['numPages'] = $numPages;
$pageout['s'] = $s;
$pageout['c'] = $c;
$pageout['context'] = 'image';
$pageout['grand_total'] = $grand_total;
$pageout['total'] = $total;
if (empty($thispage)) {
$thispage = $pageout;
}
} else {
$pgoffset = $offset;
}
$qparts = array(
$where,
"ORDER BY ".$safe_sort,
($limit) ? "LIMIT ".intval($pgoffset).", ".intval($limit) : '',
);
$rs = safe_rows_start("*", 'txp_image', join(' ', $qparts));
if ($rs) {
$out = array();
$count = 0;
$last = numRows($rs);
if (isset($thisimage)) {
$old_image = $thisimage;
}
while ($a = nextRow($rs)) {
++$count;
$thisimage = image_format_info($a);
$thisimage['is_first'] = ($count == 1);
$thisimage['is_last'] = ($count == $last);
if (!$has_content) {
$url = pagelinkurl(array(
'c' => $thisimage['category'],
'context' => 'image',
's' => $s,
'p' => $thisimage['id'],
));
$src = image_url(array('thumbnail' => '1'));
$thing = href(
'',
$url
);
}
$out[] = ($thing) ? parse($thing) : parse_form($form);
}
$thisimage = (isset($old_image) ? $old_image : null);
if ($out) {
return doLabel($label, $labeltag).doWrap($out, $wraptag, $break, $class, '', '', '', $html_id);
}
}
return '';
}
// -------------------------------------------------------------
function image_info($atts)
{
global $thisimage;
extract(lAtts(array(
'name' => '',
'id' => '',
'type' => 'caption',
'escape' => 'html',
'wraptag' => '',
'class' => '',
'break' => '',
'breakclass' => '', // Deprecated in 4.6.0.
), $atts));
if (isset($atts['breakclass'])) {
trigger_error(gTxt('deprecated_attribute', array('{name}' => 'breakclass')), E_USER_NOTICE);
}
$validItems = array('id', 'name', 'category', 'category_title', 'alt', 'caption', 'ext', 'author', 'w', 'h', 'thumb_w', 'thumb_h', 'date');
$type = do_list($type);
$from_form = false;
if ($id) {
$thisimage = imageFetchInfo('id = '.intval($id));
} elseif ($name) {
$thisimage = imageFetchInfo("name = '".doSlash($name)."'");
} else {
assert_image();
$from_form = true;
}
$out = array();
if ($thisimage) {
$thisimage['category_title'] = fetch_category_title($thisimage['category'], 'image');
foreach ($type as $item) {
if (in_array($item, $validItems)) {
if (isset($thisimage[$item])) {
$out[] = ($escape == 'html') ?
txpspecialchars($thisimage[$item]) : $thisimage[$item];
}
}
}
if (!$from_form) {
$thisimage = '';
}
}
return doWrap($out, $wraptag, $break, $class, $breakclass);
}
// -------------------------------------------------------------
function image_url($atts, $thing = null)
{
global $thisimage;
extract(lAtts(array(
'name' => '',
'id' => '',
'thumbnail' => 0,
'link' => 'auto',
), $atts));
$from_form = false;
if ($id) {
$thisimage = imageFetchInfo('id = '.intval($id));
} elseif ($name) {
$thisimage = imageFetchInfo("name = '".doSlash($name)."'");
} else {
assert_image();
$from_form = true;
}
if ($thisimage) {
$url = imagesrcurl($thisimage['id'], $thisimage['ext'], $thumbnail);
$link = ($link == 'auto') ? (($thing) ? 1 : 0) : $link;
$out = ($thing) ? parse($thing) : $url;
$out = ($link) ? href($out, $url) : $out;
if (!$from_form) {
$thisimage = '';
}
return $out;
}
return '';
}
// -------------------------------------------------------------
function image_author($atts)
{
global $thisimage, $s;
assert_image();
extract(lAtts(array(
'class' => '',
'link' => 0,
'title' => 1,
'section' => '',
'this_section' => '',
'wraptag' => '',
), $atts));
if ($thisimage['author']) {
$author_name = get_author_name($thisimage['author']);
$display_name = txpspecialchars(($title) ? $author_name : $thisimage['author']);
$section = ($this_section) ? ($s == 'default' ? '' : $s) : $section;
$author = ($link)
? href($display_name, pagelinkurl(array('s' => $section, 'author' => $author_name, 'context' => 'image')))
: $display_name;
return ($wraptag) ? doTag($author, $wraptag, $class) : $author;
}
}
// -------------------------------------------------------------
function image_date($atts)
{
global $thisimage;
extract(lAtts(array(
'name' => '',
'id' => '',
'format' => '',
), $atts));
$from_form = false;
if ($id) {
$thisimage = imageFetchInfo('id = '.intval($id));
} elseif ($name) {
$thisimage = imageFetchInfo("name = '".doSlash($name)."'");
} else {
assert_image();
$from_form = true;
}
if (isset($thisimage['date'])) {
// Not a typo: use fileDownloadFormatTime() since it's fit for purpose.
$out = fileDownloadFormatTime(array(
'ftime' => $thisimage['date'],
'format' => $format,
));
if (!$from_form) {
$thisimage = '';
}
return $out;
}
}
// -------------------------------------------------------------
function if_thumbnail($atts, $thing)
{
global $thisimage;
assert_image();
return parse($thing, ($thisimage['thumbnail'] == 1));
}
// -------------------------------------------------------------
function if_comments($atts, $thing)
{
global $thisarticle;
assert_article();
return parse($thing, ($thisarticle['comments_count'] > 0));
}
// -------------------------------------------------------------
function if_comments_allowed($atts, $thing)
{
global $thisarticle;
assert_article();
return parse($thing, checkCommentsAllowed($thisarticle['thisid']));
}
// -------------------------------------------------------------
function if_comments_disallowed($atts, $thing)
{
global $thisarticle;
assert_article();
return parse($thing, !checkCommentsAllowed($thisarticle['thisid']));
}
// -------------------------------------------------------------
function if_individual_article($atts, $thing)
{
global $is_article_list;
return parse($thing, ($is_article_list == false));
}
// -------------------------------------------------------------
function if_article_list($atts, $thing)
{
global $is_article_list;
return parse($thing, ($is_article_list == true));
}
/**
* Returns article keywords.
*
* @param array $atts Tag attributes
* @return string
*/
function meta_keywords($atts)
{
global $id_keywords;
extract(lAtts(array(
'escape' => 'html',
'format' => 'meta', // or empty for raw value
'separator' => '',
), $atts));
$out = '';
if ($id_keywords) {
$content = ($escape === 'html') ? txpspecialchars($id_keywords) : $id_keywords;
if ($separator !== '') {
$content = implode($separator, do_list($content));
}
if ($format === 'meta') {
// Can't use tag_void() since it escapes its content.
$out = '';
} else {
$out = $content;
}
}
return $out;
}
/**
* Returns article, section or category meta description info.
*
* @param array $atts Tag attributes
* @return string
*/
function meta_description($atts)
{
global $thisarticle, $thiscategory, $thissection, $s, $c, $context;
extract(lAtts(array(
'escape' => 'html',
'format' => 'meta', // or empty for raw value
'type' => null,
), $atts));
$out = '';
$content = getMetaDescription($type);
if ($content) {
$content = ($escape === 'html' ? txpspecialchars($content) : $content);
if ($format === 'meta') {
$out = '';
} else {
$out = $content;
}
}
return $out;
}
/**
* Determines if there is meta description content in the given context.
*
* @param array $atts Tag attributes
* @param string $thing Tag container content
* @return string
*/
function if_description($atts, $thing = null)
{
global $thisarticle, $thiscategory, $thissection, $s, $c, $context;
extract(lAtts(array(
'type' => null,
), $atts));
$content = getMetaDescription($type);
return parse($thing, !empty($content));
}
// -------------------------------------------------------------
function meta_author($atts)
{
global $id_author;
extract(lAtts(array(
'escape' => 'html',
'format' => 'meta', // or empty for raw value
'title' => 0,
), $atts));
$out = '';
if ($id_author) {
$display_name = ($title) ? get_author_name($id_author) : $id_author;
$display_name = ($escape === 'html') ? txpspecialchars($display_name) : $display_name;
if ($format === 'meta') {
// Can't use tag_void() since it escapes its content.
$out = '';
} else {
$out = $display_name;
}
}
return $out;
}
// -------------------------------------------------------------
function permlink($atts, $thing = null)
{
global $thisarticle;
extract(lAtts(array(
'class' => '',
'id' => '',
'style' => '',
'title' => '',
), $atts));
if (!$id) {
assert_article();
}
$url = ($id) ? permlinkurl_id($id) : permlinkurl($thisarticle);
if ($url) {
if ($thing === null) {
return $url;
}
return tag(parse($thing), 'a', ' rel="bookmark" href="'.$url.'"'.
($title ? ' title="'.txpspecialchars($title).'"' : '').
($style ? ' style="'.txpspecialchars($style).'"' : '').
($class ? ' class="'.txpspecialchars($class).'"' : '')
);
}
}
// -------------------------------------------------------------
function lang()
{
return txpspecialchars(LANG);
}
/**
* Formats article permanent links.
*
* @param int $ID
* @param string $Section
* @return string
* @deprecated in 4.0.0
*/
function formatPermLink($ID, $Section)
{
trigger_error(gTxt('deprecated_tag'), E_USER_NOTICE);
return permlinkurl_id($ID);
}
/**
* Formats comments invite link.
*
* @param string $AnnotateInvite
* @param string $Section
* @param int $ID
* @return string
* @deprecated in 4.0.0
*/
function formatCommentsInvite($AnnotateInvite, $Section, $ID)
{
trigger_error(gTxt('deprecated_tag'), E_USER_NOTICE);
global $comments_mode;
$dc = safe_count('txp_discuss', "parentid = ".intval($ID)." AND visible = ".VISIBLE);
$ccount = ($dc) ? '['.$dc.']' : '';
if (!$comments_mode) {
return ''.$AnnotateInvite.''.$ccount;
} else {
return "".$AnnotateInvite.' '.$ccount;
}
}
/**
* Formats article permanent link.
*
* @param string $text
* @param string $plink
* @param string $Title
* @param string $url_title
* @return string
* @deprecated in 4.0.0
*/
function doPermlink($text, $plink, $Title, $url_title)
{
trigger_error(gTxt('deprecated_tag'), E_USER_NOTICE);
global $url_mode;
$Title = ($url_title) ? $url_title : stripSpace($Title);
$Title = ($url_mode) ? $Title : '';
return preg_replace("/<(txp:permlink)>(.*)<\/\\1>/sU",
"$2", $text);
}
/**
* Formats article link.
*
* @param int $ID
* @param string $Title
* @param string $url_title
* @param string $Section
* @return string
* @deprecated in 4.0.0
*/
function doArticleHref($ID, $Title, $url_title, $Section)
{
trigger_error(gTxt('deprecated_tag'), E_USER_NOTICE);
$conTitle = ($url_title) ? $url_title : stripSpace($Title);
return ($GLOBALS['url_mode'])
? tag($Title, 'a', ' href="'.hu.$Section.'/'.$ID.'/'.$conTitle.'"')
: tag($Title, 'a', ' href="'.hu.'index.php?id='.$ID.'"');
}
// -------------------------------------------------------------
function breadcrumb($atts)
{
global $pretext, $sitename;
extract(lAtts(array(
'wraptag' => 'p',
'sep' => ' » ', // Deprecated in 4.3.0.
'separator' => ' » ',
'link' => 1,
'label' => $sitename,
'title' => '',
'class' => '',
'linkclass' => '',
), $atts));
if (isset($atts['sep'])) {
$separator = $sep;
trigger_error(gTxt('deprecated_attribute', array('{name}' => 'sep')), E_USER_NOTICE);
}
// For BC, get rid of in crockery.
if ($link == 'y') {
$linked = true;
} elseif ($link == 'n') {
$linked = false;
} else {
$linked = $link;
}
$label = txpspecialchars($label);
if ($linked) {
$label = doTag($label, 'a', $linkclass, ' href="'.hu.'"');
}
$content = array();
extract($pretext);
if (!empty($s) && $s != 'default') {
$section_title = ($title) ? fetch_section_title($s) : $s;
$section_title_html = escape_title($section_title);
$content[] = ($linked)
? (doTag($section_title_html, 'a', $linkclass, ' href="'.pagelinkurl(array('s' => $s)).'"'))
: $section_title_html;
}
$category = empty($c) ? '' : $c;
foreach (getTreePath($category, 'article') as $cat) {
if ($cat['name'] != 'root') {
$category_title_html = $title ? escape_title($cat['title']) : $cat['name'];
$content[] = ($linked)
? doTag($category_title_html, 'a', $linkclass, ' href="'.pagelinkurl(array('c' => $cat['name'])).'"')
: $category_title_html;
}
}
// Add the label at the end, to prevent breadcrumb for homepage.
if ($content) {
$content = array_merge(array($label), $content);
return doTag(join($separator, $content), $wraptag, $class);
}
}
//------------------------------------------------------------------------
function if_excerpt($atts, $thing)
{
global $thisarticle;
assert_article();
return parse($thing, trim($thisarticle['excerpt']) !== '');
}
// -------------------------------------------------------------
// Searches use default page. This tag allows you to use different templates if searching
// -------------------------------------------------------------
function if_search($atts, $thing)
{
global $pretext;
return parse($thing, !empty($pretext['q']));
}
// -------------------------------------------------------------
function if_search_results($atts, $thing)
{
global $thispage, $pretext;
if (empty($pretext['q'])) {
return '';
}
extract(lAtts(array(
'min' => 1,
'max' => 0,
), $atts));
$results = (int) $thispage['grand_total'];
return parse($thing, $results >= $min && (!$max || $results <= $max));
}
// -------------------------------------------------------------
function if_category($atts, $thing)
{
global $c, $context;
extract(lAtts(array(
'type' => 'article',
'name' => false,
), $atts));
$theType = ($type) ? $type == $context : true;
if ($name === false) {
return parse($thing, ($theType && !empty($c)));
} else {
return parse($thing, ($theType && in_list($c, $name)));
}
}
// -------------------------------------------------------------
function if_article_category($atts, $thing)
{
global $thisarticle;
assert_article();
extract(lAtts(array(
'name' => '',
'number' => '',
), $atts));
$cats = array();
if ($number) {
if (!empty($thisarticle['category'.$number])) {
$cats = array($thisarticle['category'.$number]);
}
} else {
if (!empty($thisarticle['category1'])) {
$cats[] = $thisarticle['category1'];
}
if (!empty($thisarticle['category2'])) {
$cats[] = $thisarticle['category2'];
}
$cats = array_unique($cats);
}
if ($name) {
return parse($thing, array_intersect(do_list($name), $cats));
} else {
return parse($thing, ($cats));
}
}
// -------------------------------------------------------------
function if_first_category($atts, $thing)
{
global $thiscategory;
assert_category();
return parse($thing, !empty($thiscategory['is_first']));
}
// -------------------------------------------------------------
function if_last_category($atts, $thing)
{
global $thiscategory;
assert_category();
return parse($thing, !empty($thiscategory['is_last']));
}
// -------------------------------------------------------------
function if_section($atts, $thing)
{
global $pretext;
extract($pretext);
extract(lAtts(array(
'name' => false,
), $atts));
$section = ($s == 'default' ? '' : $s);
if ($section) {
return parse($thing, $name === false or in_list($section, $name));
} else {
return parse($thing, $name !== false and (in_list('', $name) or in_list('default', $name)));
}
}
// -------------------------------------------------------------
function if_article_section($atts, $thing)
{
global $thisarticle;
assert_article();
extract(lAtts(array(
'name' => '',
), $atts));
$section = $thisarticle['section'];
return parse($thing, in_list($section, $name));
}
// -------------------------------------------------------------
function if_first_section($atts, $thing)
{
global $thissection;
assert_section();
return parse($thing, !empty($thissection['is_first']));
}
// -------------------------------------------------------------
function if_last_section($atts, $thing)
{
global $thissection;
assert_section();
return parse($thing, !empty($thissection['is_last']));
}
// -------------------------------------------------------------
function php($atts, $thing)
{
global $is_article_body, $thisarticle, $prefs;
if (assert_array($prefs) === false) {
return '';
}
ob_start();
if (empty($is_article_body)) {
if (!empty($prefs['allow_page_php_scripting'])) {
eval($thing);
} else {
trigger_error(gTxt('php_code_disabled_page'));
}
} else {
if (!empty($prefs['allow_article_php_scripting'])) {
if (has_privs('article.php', $thisarticle['authorid'])) {
eval($thing);
} else {
trigger_error(gTxt('php_code_forbidden_user'));
}
} else {
trigger_error(gTxt('php_code_disabled_article'));
}
}
return ob_get_clean();
}
// -------------------------------------------------------------
function custom_field($atts)
{
global $is_article_body, $thisarticle;
assert_article();
extract(lAtts(array(
'name' => get_pref('custom_1_set'),
'escape' => 'html',
'default' => '',
), $atts));
$name = strtolower($name);
if (!isset($thisarticle[$name])) {
trigger_error(gTxt('field_not_found', array('{name}' => $name)), E_USER_NOTICE);
return '';
}
if ($thisarticle[$name] !== '') {
$out = $thisarticle[$name];
} else {
$out = $default;
}
$was_article_body = $is_article_body;
$is_article_body = 1;
$out = ($escape == 'html' ? txpspecialchars($out) : parse($out));
$is_article_body = $was_article_body;
return $out;
}
// -------------------------------------------------------------
function if_custom_field($atts, $thing)
{
global $thisarticle;
assert_article();
extract(lAtts(array(
'name' => get_pref('custom_1_set'),
'value' => null,
'val' => null, // Deprecated in 4.3.0.
'match' => 'exact',
'separator' => '',
), $atts));
if (isset($atts['val'])) {
$value = $val;
trigger_error(gTxt('deprecated_attribute', array('{name}' => 'val')), E_USER_NOTICE);
}
$name = strtolower($name);
if (!isset($thisarticle[$name])) {
trigger_error(gTxt('field_not_found', array('{name}' => $name)), E_USER_NOTICE);
return '';
}
if ($value !== null) {
switch ($match) {
case '':
case 'exact':
$cond = ($thisarticle[$name] == $value);
break;
case 'any':
$values = do_list($value);
$cond = false;
$cf_contents = ($separator) ? do_list($thisarticle[$name], $separator) : $thisarticle[$name];
foreach ($values as $term) {
if ($term == '') {
continue;
}
$cond = is_array($cf_contents) ? in_array($term, $cf_contents) : ((strpos($cf_contents, $term) !== false) ? true : false);
// Short circuit if a match is found.
if ($cond) {
break;
}
}
break;
case 'all':
$values = do_list($value);
$num_values = count($values);
$term_count = 0;
$cf_contents = ($separator) ? do_list($thisarticle[$name], $separator) : $thisarticle[$name];
foreach ($values as $term) {
if ($term == '') {
continue;
}
$term_count += is_array($cf_contents) ? in_array($term, $cf_contents) : ((strpos($cf_contents, $term) !== false) ? true : false);
}
$cond = ($term_count == $num_values) ? true : false;
break;
case 'pattern':
// Cannot guarantee that a fixed delimiter won't break preg_match
// (and preg_quote doesn't help) so dynamically assign the delimiter
// based on the first entry in $dlmPool that is NOT in the value
// attribute. This minimises (does not eliminate) the possibility
// of a TXP-initiated preg_match error, while still preserving
// errors outside TXP's control (e.g. mangled user-submitted
// PCRE pattern).
$dlmPool = array('/', '@', '#', '~', '`', '|', '!', '%');
$dlm = array_merge(array_diff($dlmPool, preg_split('//', $value, -1)));
$dlm = (count($dlm) > 0) ? $dlm[0].$value.$dlm[0] : $value;
$cond = preg_match($dlm, $thisarticle[$name]);
break;
default:
trigger_error(gTxt('invalid_attribute_value', array('{name}' => 'value')), E_USER_NOTICE);
$cond = false;
}
} else {
$cond = ($thisarticle[$name] !== '');
}
return parse($thing, !empty($cond));
}
// -------------------------------------------------------------
function site_url()
{
return hu;
}
// -------------------------------------------------------------
function error_message()
{
global $txp_error_message;
return $txp_error_message;
}
// -------------------------------------------------------------
function error_status()
{
global $txp_error_status;
return $txp_error_status;
}
// -------------------------------------------------------------
function if_status($atts, $thing)
{
global $pretext, $txp_error_code;
extract(lAtts(array(
'status' => '200',
), $atts));
$page_status = $txp_error_code
? $txp_error_code
: $pretext['status'];
return parse($thing, $status == $page_status);
}
// -------------------------------------------------------------
function page_url($atts)
{
global $pretext;
extract(lAtts(array(
'type' => 'request_uri',
), $atts));
if ($type == 'pg' and $pretext['pg'] == '') {
return '1';
}
return @txpspecialchars($pretext[$type]);
}
// -------------------------------------------------------------
function if_different($atts, $thing)
{
static $last;
$key = md5($thing);
$out = parse($thing, 1);
if (empty($last[$key]) or $out != $last[$key]) {
return $last[$key] = $out;
} else {
return parse($thing, 0);
}
}
// -------------------------------------------------------------
function if_first_article($atts, $thing)
{
global $thisarticle;
assert_article();
return parse($thing, !empty($thisarticle['is_first']));
}
// -------------------------------------------------------------
function if_last_article($atts, $thing)
{
global $thisarticle;
assert_article();
return parse($thing, !empty($thisarticle['is_last']));
}
// -------------------------------------------------------------
function if_plugin($atts, $thing)
{
global $plugins, $plugins_ver;
extract(lAtts(array(
'name' => '',
'ver' => '', // Deprecated in 4.3.0.
'version' => '',
), $atts));
if (isset($atts['ver'])) {
$version = $ver;
trigger_error(gTxt('deprecated_attribute', array('{name}' => 'ver')), E_USER_NOTICE);
}
return parse($thing, @in_array($name, $plugins) and (!$version or version_compare($plugins_ver[$name], $version) >= 0));
}
// -------------------------------------------------------------
function file_download_list($atts, $thing = null)
{
global $s, $c, $context, $thisfile, $thispage, $pretext;
extract(lAtts(array(
'break' => br,
'category' => '',
'author' => '',
'realname' => '',
'auto_detect' => 'category, author',
'class' => __FUNCTION__,
'form' => 'files',
'id' => '',
'label' => '',
'labeltag' => '',
'pageby' => '',
'limit' => 10,
'offset' => 0,
'sort' => 'filename asc',
'wraptag' => '',
'status' => STATUS_LIVE,
), $atts));
if (!is_numeric($status)) {
$status = getStatusNum($status);
}
// Note: status treated slightly differently.
$where = $statwhere = array();
$filters = isset($atts['id']) || isset($atts['category']) || isset($atts['author']) || isset($atts['realname']) || isset($atts['status']);
$context_list = (empty($auto_detect) || $filters) ? array() : do_list_unique($auto_detect);
$pageby = ($pageby == 'limit') ? $limit : $pageby;
if ($category) {
$where[] = "category IN ('".join("','", doSlash(do_list_unique($category)))."')";
}
$ids = array_map('intval', do_list_unique($id));
if ($id) {
$where[] = "id IN ('".join("','", $ids)."')";
}
if ($status) {
$statwhere[] = "status = '".doSlash($status)."'";
}
if ($author) {
$where[] = "author IN ('".join("','", doSlash(do_list_unique($author)))."')";
}
if ($realname) {
$authorlist = safe_column("name", 'txp_users', "RealName IN ('".join("','", doArray(doSlash(do_list_unique($realname)), 'urldecode'))."')");
if ($authorlist) {
$where[] = "author IN ('".join("','", doSlash($authorlist))."')";
}
}
// If no files are selected, try...
if (!$where && !$filters) {
foreach ($context_list as $ctxt) {
switch ($ctxt) {
case 'category':
// ...the global category in the URL.
if ($context == 'file' && !empty($c)) {
$where[] = "category = '".doSlash($c)."'";
}
break;
case 'author':
// ...the global author in the URL.
if ($context == 'file' && !empty($pretext['author'])) {
$where[] = "author = '".doSlash($pretext['author'])."'";
}
break;
}
// Only one context can be processed.
if ($where) {
break;
}
}
}
if (!$where && !$statwhere && $filters) {
// If nothing matches, output nothing.
return '';
}
$where[] = "created <= ".now('created');
$where = join(" AND ", array_merge($where, $statwhere));
// Set up paging if required.
if ($limit && $pageby) {
$grand_total = safe_count('txp_file', $where);
$total = $grand_total - $offset;
$numPages = ($pageby > 0) ? ceil($total/$pageby) : 1;
$pg = (!$pretext['pg']) ? 1 : $pretext['pg'];
$pgoffset = $offset + (($pg - 1) * $pageby);
// Send paging info to txp:newer and txp:older.
$pageout['pg'] = $pg;
$pageout['numPages'] = $numPages;
$pageout['s'] = $s;
$pageout['c'] = $c;
$pageout['context'] = 'file';
$pageout['grand_total'] = $grand_total;
$pageout['total'] = $total;
if (empty($thispage)) {
$thispage = $pageout;
}
} else {
$pgoffset = $offset;
}
// Preserve order of custom file ids unless 'sort' attribute is set.
if (!empty($atts['id']) && empty($atts['sort'])) {
$safe_sort = "FIELD(id, ".join(',', $ids).")";
} else {
$safe_sort = doSlash($sort);
}
$qparts = array(
"ORDER BY ".$safe_sort,
($limit) ? "LIMIT ".intval($pgoffset).", ".intval($limit) : '',
);
$rs = safe_rows_start("*", 'txp_file', $where.' '.join(' ', $qparts));
if ($rs) {
$count = 0;
$last = numRows($rs);
$out = array();
while ($a = nextRow($rs)) {
++$count;
$thisfile = file_download_format_info($a);
$thisfile['is_first'] = ($count == 1);
$thisfile['is_last'] = ($count == $last);
$out[] = ($thing) ? parse($thing) : parse_form($form);
$thisfile = '';
}
if ($out) {
return doLabel($label, $labeltag).doWrap($out, $wraptag, $break, $class);
}
}
return '';
}
// -------------------------------------------------------------
function file_download($atts, $thing = null)
{
global $thisfile;
extract(lAtts(array(
'filename' => '',
'form' => 'files',
'id' => '',
), $atts));
$from_form = false;
if ($id) {
$thisfile = fileDownloadFetchInfo('id = '.intval($id).' and created <= '.now('created'));
} elseif ($filename) {
$thisfile = fileDownloadFetchInfo("filename = '".doSlash($filename)."' and created <= ".now('created'));
} else {
assert_file();
$from_form = true;
}
if ($thisfile) {
$out = ($thing) ? parse($thing) : parse_form($form);
// Cleanup: this wasn't called from a form, so we don't want this
// value remaining.
if (!$from_form) {
$thisfile = '';
}
return $out;
}
}
// -------------------------------------------------------------
function file_download_link($atts, $thing = null)
{
global $thisfile;
extract(lAtts(array(
'filename' => '',
'id' => '',
), $atts));
$from_form = false;
if ($id) {
$thisfile = fileDownloadFetchInfo('id = '.intval($id).' and created <= '.now('created'));
} elseif ($filename) {
$thisfile = fileDownloadFetchInfo("filename = '".doSlash($filename)."' and created <= ".now('created'));
} else {
assert_file();
$from_form = true;
}
if ($thisfile) {
$url = filedownloadurl($thisfile['id'], $thisfile['filename']);
$out = ($thing) ? href(parse($thing), $url) : $url;
// Cleanup: this wasn't called from a form, so we don't want this
// value remaining
if (!$from_form) {
$thisfile = '';
}
return $out;
}
}
// -------------------------------------------------------------
function file_download_size($atts)
{
global $thisfile;
assert_file();
extract(lAtts(array(
'decimals' => 2,
'format' => '',
), $atts));
if (is_numeric($decimals) and $decimals >= 0) {
$decimals = intval($decimals);
} else {
$decimals = 2;
}
if (isset($thisfile['size'])) {
$format_unit = strtolower(substr($format, 0, 1));
return format_filesize($thisfile['size'], $decimals, $format_unit);
} else {
return '';
}
}
// -------------------------------------------------------------
function file_download_created($atts)
{
global $thisfile;
assert_file();
extract(lAtts(array(
'format' => '',
), $atts));
if ($thisfile['created']) {
return fileDownloadFormatTime(array(
'ftime' => $thisfile['created'],
'format' => $format,
));
}
}
// -------------------------------------------------------------
function file_download_modified($atts)
{
global $thisfile;
assert_file();
extract(lAtts(array(
'format' => '',
), $atts));
if ($thisfile['modified']) {
return fileDownloadFormatTime(array(
'ftime' => $thisfile['modified'],
'format' => $format,
));
}
}
// -------------------------------------------------------------
function file_download_id()
{
global $thisfile;
assert_file();
return $thisfile['id'];
}
// -------------------------------------------------------------
function file_download_name($atts)
{
global $thisfile;
assert_file();
extract(lAtts(array(
'title' => 0,
), $atts));
return ($title) ? $thisfile['title'] : $thisfile['filename'];
}
// -------------------------------------------------------------
function file_download_category($atts)
{
global $thisfile;
assert_file();
extract(lAtts(array(
'class' => '',
'title' => 0,
'wraptag' => '',
), $atts));
if ($thisfile['category']) {
$category = ($title)
? fetch_category_title($thisfile['category'], 'file')
: $thisfile['category'];
return ($wraptag) ? doTag($category, $wraptag, $class) : $category;
}
}
// -------------------------------------------------------------
function file_download_author($atts)
{
global $thisfile, $s;
assert_file();
extract(lAtts(array(
'class' => '',
'link' => 0,
'title' => 1,
'section' => '',
'this_section' => '',
'wraptag' => '',
), $atts));
if ($thisfile['author']) {
$author_name = get_author_name($thisfile['author']);
$display_name = txpspecialchars(($title) ? $author_name : $thisfile['author']);
$section = ($this_section) ? ($s == 'default' ? '' : $s) : $section;
$author = ($link)
? href($display_name, pagelinkurl(array('s' => $section, 'author' => $author_name, 'context' => 'file')))
: $display_name;
return ($wraptag) ? doTag($author, $wraptag, $class) : $author;
}
}
// -------------------------------------------------------------
function file_download_downloads()
{
global $thisfile;
assert_file();
return $thisfile['downloads'];
}
// -------------------------------------------------------------
function file_download_description($atts)
{
global $thisfile;
assert_file();
extract(lAtts(array(
'class' => '',
'escape' => 'html',
'wraptag' => '',
), $atts));
if ($thisfile['description']) {
$description = ($escape == 'html')
? txpspecialchars($thisfile['description'])
: $thisfile['description'];
return ($wraptag) ? doTag($description, $wraptag, $class) : $description;
}
}
// -------------------------------------------------------------
function hide()
{
return '';
}
// -------------------------------------------------------------
function rsd()
{
global $prefs;
trigger_error(gTxt('deprecated_tag'), E_USER_NOTICE);
return ($prefs['enable_xmlrpc_server']) ? '' : '';
}
// -------------------------------------------------------------
function variable($atts, $thing = null)
{
global $variable, $trace;
extract(lAtts(array(
'name' => '',
'value' => $thing !== null ? parse($thing) : null,
), $atts));
if (empty($name)) {
trigger_error(gTxt('variable_name_empty'));
return;
}
if (!isset($atts['value']) && is_null($thing)) {
if (isset($variable[$name])) {
return $variable[$name];
} else {
$trace->log("[: Unknown variable '$name']");
return '';
}
} else {
$variable[$name] = $value;
}
}
// -------------------------------------------------------------
function if_variable($atts, $thing = null)
{
global $variable;
extract(lAtts(array(
'name' => '',
'value' => '',
), $atts));
if (empty($name)) {
trigger_error(gTxt('variable_name_empty'));
return;
}
if (isset($variable[$name])) {
if (!isset($atts['value'])) {
$x = true;
} else {
$x = $variable[$name] == $value;
}
} else {
$x = false;
}
return parse($thing, $x);
}