function list_list($message = "", $post = '') { extract(get_prefs()); $lvars = array("page", "sort", "dir", "crit", 'method'); extract(gpsa($lvars)); global $statuses, $step; pagetop("Textpattern", $message); $total = getCount('textpattern', "1"); $limit = $article_list_pageby ? $article_list_pageby : 25; $numPages = ceil($total / $limit); $page = !$page ? 1 : $page; $offset = ($page - 1) * $limit; if (!$sort) { $sort = "Posted"; } if (!$dir) { $dir = "desc"; } if ($dir == "desc") { $linkdir = "asc"; } else { $linkdir = "desc"; } if ($crit) { $critsql = array('title_body' => "Title rlike '{$crit}' or Body rlike '{$crit}'", 'author' => "AuthorID rlike '{$crit}'", 'categories' => "Category1 rlike '{$crit}' or Category2 rlike '{$crit}'", 'section' => "Section rlike '{$crit}'", 'status' => "Status rlike '{$crit}'"); $criteria = $critsql[$method]; $limit = 500; } else { $criteria = 1; } $rs = safe_rows("*, unix_timestamp(Posted) as uPosted", "textpattern", "{$criteria} order by {$sort} {$dir} limit {$offset},{$limit}"); echo !$crit ? list_nav_form($page, $numPages, $sort, $dir) : '', list_searching_form($crit, $method); if ($rs) { echo '<form action="index.php" method="post" onsubmit="return verify(\'' . gTxt('are_you_sure') . '\')">', startTable('list'), '<tr>', column_head('posted', 'Posted', 'list', 1, $linkdir), column_head('title', 'Title', 'list', 1, $linkdir), $use_sections ? column_head('section', 'Section', 'list', 1, $linkdir) : '', $use_categories ? column_head('category1', 'Category1', 'list', 1, $linkdir) . column_head('category2', 'Category2', 'list', 1, $linkdir) : '', hCell(gTxt('Author')), column_head(gTxt('status'), 'Status', 'list', 1, $linkdir), td(), '</tr>'; foreach ($rs as $a) { extract($a); if ($use_categories == 1) { $cat1 = $Category1; $cat2 = $Category2; } $stat = !empty($Status) ? $statuses[$Status] : ''; if ($use_sections == 1) { $sect = $Section; } $adate = date("d M y", $uPosted + $timeoffset); $alink = eLink('article', 'edit', 'ID', $ID, $adate); $tlink = eLink('article', 'edit', 'ID', $ID, $Title); $modbox = fInput('checkbox', 'selected[]', $ID); echo "<tr>" . n, td($alink), td($tlink, 200), $use_sections ? td($sect, 75) : '', $use_categories ? td($cat1, 75) . td($cat2, 75) : '', td($AuthorID), td($stat, 45), td($modbox), '</tr>' . n; } echo tr(tda(list_multiedit_form(), ' colspan="8" style="text-align:right;border:0px"')); echo "</table></form>"; echo pageby_form('list', $article_list_pageby); unset($sort); } }
function list_list($message = '', $post = '') { global $statuses, $comments_disabled_after, $step, $txp_user, $article_list_pageby; pagetop(gTxt('tab_list'), $message); extract(gpsa(array('page', 'sort', 'dir', 'crit', 'search_method'))); $sesutats = array_flip($statuses); $dir = $dir == 'asc' ? 'asc' : 'desc'; switch ($sort) { case 'id': $sort_sql = 'ID ' . $dir; break; case 'expires': $sort_sql = 'Expires ' . $dir; break; case 'title': $sort_sql = 'Title ' . $dir . ', Posted desc'; break; case 'section': $sort_sql = 'Section ' . $dir . ', Posted desc'; break; case 'category1': $sort_sql = 'Category1 ' . $dir . ', Posted desc'; break; case 'category2': $sort_sql = 'Category2 ' . $dir . ', Posted desc'; break; case 'status': $sort_sql = 'Status ' . $dir . ', Posted desc'; break; case 'author': $sort_sql = 'AuthorID ' . $dir . ', Posted desc'; break; case 'comments': $sort_sql = 'comments_count ' . $dir . ', Posted desc'; break; case 'lastmod': $sort_sql = 'LastMod ' . $dir . ', Posted desc'; break; default: $sort = 'posted'; $sort_sql = 'Posted ' . $dir; break; } $switch_dir = $dir == 'desc' ? 'asc' : 'desc'; $criteria = 1; if ($search_method and $crit) { $crit_escaped = doSlash($crit); $critsql = array('id' => "ID in ('" . join("','", do_list($crit_escaped)) . "')", 'title_body_excerpt' => "Title rlike '{$crit_escaped}' or Body rlike '{$crit_escaped}' or Excerpt rlike '{$crit_escaped}'", 'section' => "Section rlike '{$crit_escaped}'", 'keywords' => "FIND_IN_SET('" . $crit_escaped . "',Keywords)", 'categories' => "Category1 rlike '{$crit_escaped}' or Category2 rlike '{$crit_escaped}'", 'status' => "Status = '" . @$sesutats[gTxt($crit_escaped)] . "'", 'author' => "AuthorID rlike '{$crit_escaped}'", 'article_image' => "Image in ('" . join("','", do_list($crit_escaped)) . "')", 'posted' => "Posted like '{$crit_escaped}%'", 'lastmod' => "LastMod like '{$crit_escaped}%'"); if (array_key_exists($search_method, $critsql)) { $criteria = $critsql[$search_method]; $limit = 500; } else { $search_method = ''; $crit = ''; } } else { $search_method = ''; $crit = ''; } $total = safe_count('textpattern', "{$criteria}"); if ($total < 1) { if ($criteria != 1) { echo n . list_search_form($crit, $search_method) . n . graf(gTxt('no_results_found'), ' class="indicator"'); } else { echo graf(gTxt('no_articles_recorded'), ' class="indicator"'); } return; } $limit = max($article_list_pageby, 15); list($page, $offset, $numPages) = pager($total, $limit, $page); echo n . list_search_form($crit, $search_method); $rs = safe_rows_start('*, unix_timestamp(Posted) as posted, unix_timestamp(LastMod) as lastmod, unix_timestamp(Expires) as expires', 'textpattern', "{$criteria} order by {$sort_sql} limit {$offset}, {$limit}"); if ($rs) { $total_comments = array(); // fetch true comment count, not the public comment count // maybe we should have another row in the db? $rs2 = safe_rows_start('parentid, count(*) as num', 'txp_discuss', "1 group by parentid order by parentid"); if ($rs2) { while ($a = nextRow($rs2)) { $pid = $a['parentid']; $num = $a['num']; $total_comments[$pid] = $num; } } echo n . n . '<form name="longform" method="post" action="index.php" onsubmit="return verify(\'' . gTxt('are_you_sure') . '\')">' . n . startTable('list', '', '', '', '90%') . n . tr(n . column_head('ID', 'id', 'list', true, $switch_dir, $crit, $search_method, 'id' == $sort ? $dir : '') . column_head('posted', 'posted', 'list', true, $switch_dir, $crit, $search_method, 'posted' == $sort ? $dir : '') . column_head('article_modified', 'lastmod', 'list', true, $switch_dir, $crit, $search_method, ('lastmod' == $sort ? "{$dir} " : '') . 'articles_detail') . column_head('expires', 'expires', 'list', true, $switch_dir, $crit, $search_method, ('expires' == $sort ? "{$dir} " : '') . 'articles_detail') . column_head('title', 'title', 'list', true, $switch_dir, $crit, $search_method, 'title' == $sort ? $dir : '') . column_head('section', 'section', 'list', true, $switch_dir, $crit, $search_method, 'section' == $sort ? $dir : '') . column_head('category1', 'category1', 'list', true, $switch_dir, $crit, $search_method, ('category1' == $sort ? "{$dir} " : '') . 'articles_detail') . column_head('category2', 'category2', 'list', true, $switch_dir, $crit, $search_method, ('category2' == $sort ? "{$dir} " : '') . 'articles_detail') . column_head('status', 'status', 'list', true, $switch_dir, $crit, $search_method, 'status' == $sort ? $dir : '') . column_head('author', 'author', 'list', true, $switch_dir, $crit, $search_method, 'author' == $sort ? $dir : '') . column_head('comments', 'comments', 'list', true, $switch_dir, $crit, $search_method, ('comments' == $sort ? "{$dir} " : '') . 'articles_detail') . hCell()); include_once txpath . '/publish/taghandlers.php'; while ($a = nextRow($rs)) { extract($a); if (empty($Title)) { $Title = '<em>' . eLink('article', 'edit', 'ID', $ID, gTxt('untitled')) . '</em>'; } else { $Title = eLink('article', 'edit', 'ID', $ID, $Title); } $Category1 = $Category1 ? '<span title="' . htmlspecialchars(fetch_category_title($Category1)) . '">' . $Category1 . '</span>' : ''; $Category2 = $Category2 ? '<span title="' . htmlspecialchars(fetch_category_title($Category2)) . '">' . $Category2 . '</span>' : ''; $view_url = permlinkurl($a); if ($Status != 4 and $Status != 5) { $view_url .= (strpos($view_url, '?') === FALSE ? '?' : '&') . 'txpreview=' . intval($ID) . '.' . time(); } $manage = n . '<ul class="articles_detail">' . n . t . '<li>' . eLink('article', 'edit', 'ID', $ID, gTxt('edit')) . '</li>' . n . t . '<li><a href="' . $view_url . '" class="article-view">' . gTxt('view') . '</a></li>' . n . '</ul>'; $Status = !empty($Status) ? $statuses[$Status] : ''; $comments = gTxt('none'); if (isset($total_comments[$ID]) and $total_comments[$ID] > 0) { $comments = href(gTxt('manage'), 'index.php?event=discuss' . a . 'step=list' . a . 'search_method=parent' . a . 'crit=' . $ID) . ' (' . $total_comments[$ID] . ')'; } $comment_status = $Annotate ? gTxt('on') : gTxt('off'); if ($comments_disabled_after) { $lifespan = $comments_disabled_after * 86400; $time_since = time() - $posted; if ($time_since > $lifespan) { $comment_status = gTxt('expired'); } } $comments = n . '<ul>' . n . t . '<li>' . $comment_status . '</li>' . n . t . '<li>' . $comments . '</li>' . n . '</ul>'; echo n . n . tr(n . td(eLink('article', 'edit', 'ID', $ID, $ID) . $manage) . td(gTime($posted), '', $posted < time() ? '' : 'unpublished') . td(gTime($lastmod), '', "articles_detail") . td($expires ? gTime($expires) : '', '', 'articles_detail') . td($Title) . td('<span title="' . htmlspecialchars(fetch_section_title($Section)) . '">' . $Section . '</span>', 75) . td($Category1, 100, "articles_detail") . td($Category2, 100, "articles_detail") . td($a['Status'] < 4 ? $Status : '<a href="' . permlinkurl($a) . '">' . $Status . '</a>', 50) . td('<span title="' . htmlspecialchars(get_author_name($AuthorID)) . '">' . htmlspecialchars($AuthorID) . '</span>') . td($comments, 50, "articles_detail") . td(($a['Status'] >= 4 and has_privs('article.edit.published') or $a['Status'] >= 4 and $AuthorID == $txp_user and has_privs('article.edit.own.published') or $a['Status'] < 4 and has_privs('article.edit') or $a['Status'] < 4 and $AuthorID == $txp_user and has_privs('article.edit.own')) ? fInput('checkbox', 'selected[]', $ID) : ' ')); } echo n . n . tr(tda(toggle_box('articles_detail'), ' colspan="2" style="text-align: left; border: none;"') . tda(select_buttons() . list_multiedit_form($page, $sort, $dir, $crit, $search_method), ' colspan="9" style="text-align: right; border: none;"')) . n . endTable() . n . '</form>' . n . nav_form('list', $page, $numPages, $sort, $dir, $crit, $search_method, $total, $limit) . n . pageby_form('list', $article_list_pageby); } }
/** * The main panel listing all articles. * * @param string|array $message The activity message * @param string $post Not used */ function list_list($message = '', $post = '') { global $statuses, $use_comments, $comments_disabled_after, $step, $txp_user, $article_list_pageby, $event; pagetop(gTxt('tab_list'), $message); extract(gpsa(array('page', 'sort', 'dir', 'crit', 'search_method'))); if ($sort === '') { $sort = get_pref('article_sort_column', 'posted'); } else { if (!in_array($sort, array('id', 'title', 'expires', 'section', 'category1', 'category2', 'status', 'author', 'comments', 'lastmod'))) { $sort = 'posted'; } set_pref('article_sort_column', $sort, 'list', 2, '', 0, PREF_PRIVATE); } if ($dir === '') { $dir = get_pref('article_sort_dir', 'desc'); } else { $dir = $dir == 'asc' ? "asc" : "desc"; set_pref('article_sort_dir', $dir, 'list', 2, '', 0, PREF_PRIVATE); } $sesutats = array_flip($statuses); switch ($sort) { case 'id': $sort_sql = "textpattern.ID {$dir}"; break; case 'title': $sort_sql = "textpattern.Title {$dir}, textpattern.Posted DESC"; break; case 'expires': $sort_sql = "textpattern.Expires {$dir}"; break; case 'section': $sort_sql = "section.title {$dir}, textpattern.Posted DESC"; break; case 'category1': $sort_sql = "category1.title {$dir}, textpattern.Posted DESC"; break; case 'category2': $sort_sql = "category2.title {$dir}, textpattern.Posted DESC"; break; case 'status': $sort_sql = "textpattern.Status {$dir}, textpattern.Posted DESC"; break; case 'author': $sort_sql = "user.RealName {$dir}, textpattern.Posted DESC"; break; case 'comments': $sort_sql = "textpattern.comments_count {$dir}, textpattern.Posted DESC"; break; case 'lastmod': $sort_sql = "textpattern.LastMod {$dir}, textpattern.Posted DESC"; break; default: $sort = 'posted'; $sort_sql = "textpattern.Posted {$dir}"; break; } $switch_dir = $dir == 'desc' ? 'asc' : 'desc'; $search = new Filter($event, array('id' => array('column' => 'textpattern.ID', 'label' => gTxt('ID'), 'type' => 'integer'), 'title_body_excerpt' => array('column' => array('textpattern.Title', 'textpattern.Body', 'textpattern.Excerpt'), 'label' => gTxt('title_body_excerpt')), 'section' => array('column' => array('textpattern.Section', 'section.title'), 'label' => gTxt('section')), 'keywords' => array('column' => 'textpattern.Keywords', 'label' => gTxt('keywords'), 'type' => 'find_in_set'), 'categories' => array('column' => array('textpattern.Category1', 'textpattern.Category2', 'category1.title', 'category2.title'), 'label' => gTxt('categories')), 'status' => array('column' => array('textpattern.Status'), 'label' => gTxt('status'), 'type' => 'boolean'), 'author' => array('column' => array('textpattern.AuthorID', 'user.RealName'), 'label' => gTxt('author')), 'article_image' => array('column' => array('textpattern.Image'), 'label' => gTxt('article_image'), 'type' => 'integer'), 'posted' => array('column' => array('textpattern.Posted'), 'label' => gTxt('posted')), 'lastmod' => array('column' => array('textpattern.LastMod'), 'label' => gTxt('article_modified')))); $search->setAliases('status', $statuses); list($criteria, $crit, $search_method) = $search->getFilter(array('id' => array('can_list' => true), 'article_image' => array('can_list' => true), 'title_body_excerpt' => array('always_like' => true))); $search_render_options = array('placeholder' => 'search_articles'); $sql_from = safe_pfx('textpattern') . " textpattern\n LEFT JOIN " . safe_pfx('txp_category') . " category1 ON category1.name = textpattern.Category1 AND category1.type = 'article'\n LEFT JOIN " . safe_pfx('txp_category') . " category2 ON category2.name = textpattern.Category2 AND category2.type = 'article'\n LEFT JOIN " . safe_pfx('txp_section') . " section ON section.name = textpattern.Section\n LEFT JOIN " . safe_pfx('txp_users') . " user ON user.name = textpattern.AuthorID"; if ($criteria === 1) { $total = safe_count('textpattern', $criteria); } else { $total = getThing("SELECT COUNT(*) FROM {$sql_from} WHERE {$criteria}"); } echo n . tag(hed(gTxt('tab_list'), 1, array('class' => 'txp-heading')), 'div', array('class' => 'txp-layout-2col-cell-1')); $searchBlock = n . tag($search->renderForm('list', $search_render_options), 'div', array('class' => 'txp-layout-2col-cell-2', 'id' => $event . '_control')); $createBlock = array(); if (has_privs('article.edit')) { $createBlock[] = n . tag(sLink('article', '', gTxt('add_new_article'), 'txp-button'), 'div', array('class' => 'txp-control-panel')); } $contentBlockStart = n . tag_start('div', array('class' => 'txp-layout-1col', 'id' => $event . '_container')); $createBlock = implode(n, $createBlock); if ($total < 1) { if ($criteria != 1) { echo $searchBlock . $contentBlockStart . $createBlock . graf(span(null, array('class' => 'ui-icon ui-icon-info')) . ' ' . gTxt('no_results_found'), array('class' => 'alert-block information')); } else { echo $contentBlockStart . $createBlock . graf(span(null, array('class' => 'ui-icon ui-icon-info')) . ' ' . gTxt('no_articles_recorded'), array('class' => 'alert-block information')); } echo n . tag_end('div'); return; } $limit = max($article_list_pageby, 15); list($page, $offset, $numPages) = pager($total, $limit, $page); echo $searchBlock . $contentBlockStart . $createBlock; $rs = safe_query("SELECT\n textpattern.ID, textpattern.Title, textpattern.url_title, textpattern.Section,\n textpattern.Category1, textpattern.Category2,\n textpattern.Status, textpattern.Annotate, textpattern.AuthorID,\n UNIX_TIMESTAMP(textpattern.Posted) AS posted,\n UNIX_TIMESTAMP(textpattern.LastMod) AS lastmod,\n UNIX_TIMESTAMP(textpattern.Expires) AS expires,\n category1.title AS category1_title,\n category2.title AS category2_title,\n section.title AS section_title,\n user.RealName AS RealName,\n (SELECT COUNT(*) FROM " . safe_pfx('txp_discuss') . " WHERE parentid = textpattern.ID) AS total_comments\n FROM {$sql_from} WHERE {$criteria} ORDER BY {$sort_sql} LIMIT {$offset}, {$limit}"); if ($rs) { $show_authors = !has_single_author('textpattern', 'AuthorID'); echo n . tag(toggle_box('articles_detail'), 'div', array('class' => 'txp-list-options')) . n . tag_start('form', array('class' => 'multi_edit_form', 'id' => 'articles_form', 'name' => 'longform', 'method' => 'post', 'action' => 'index.php')) . n . tag_start('div', array('class' => 'txp-listtables')) . n . tag_start('table', array('class' => 'txp-list')) . n . tag_start('thead') . tr(hCell(fInput('checkbox', 'select_all', 0, '', '', '', '', '', 'select_all'), '', ' class="txp-list-col-multi-edit" scope="col" title="' . gTxt('toggle_all_selected') . '"') . column_head('ID', 'id', 'list', true, $switch_dir, $crit, $search_method, ('id' == $sort ? "{$dir} " : '') . 'txp-list-col-id') . column_head('title', 'title', 'list', true, $switch_dir, $crit, $search_method, ('title' == $sort ? "{$dir} " : '') . 'txp-list-col-title') . column_head('posted', 'posted', 'list', true, $switch_dir, $crit, $search_method, ('posted' == $sort ? "{$dir} " : '') . 'txp-list-col-created date') . column_head('article_modified', 'lastmod', 'list', true, $switch_dir, $crit, $search_method, ('lastmod' == $sort ? "{$dir} " : '') . 'txp-list-col-lastmod date articles_detail') . column_head('expires', 'expires', 'list', true, $switch_dir, $crit, $search_method, ('expires' == $sort ? "{$dir} " : '') . 'txp-list-col-expires date articles_detail') . column_head('section', 'section', 'list', true, $switch_dir, $crit, $search_method, ('section' == $sort ? "{$dir} " : '') . 'txp-list-col-section') . column_head('category1', 'category1', 'list', true, $switch_dir, $crit, $search_method, ('category1' == $sort ? "{$dir} " : '') . 'txp-list-col-category1 category articles_detail') . column_head('category2', 'category2', 'list', true, $switch_dir, $crit, $search_method, ('category2' == $sort ? "{$dir} " : '') . 'txp-list-col-category2 category articles_detail') . column_head('status', 'status', 'list', true, $switch_dir, $crit, $search_method, ('status' == $sort ? "{$dir} " : '') . 'txp-list-col-status') . ($show_authors ? column_head('author', 'author', 'list', true, $switch_dir, $crit, $search_method, ('author' == $sort ? "{$dir} " : '') . 'txp-list-col-author name') : '') . ($use_comments == 1 ? column_head('comments', 'comments', 'list', true, $switch_dir, $crit, $search_method, ('comments' == $sort ? "{$dir} " : '') . 'txp-list-col-comments articles_detail') : '')) . n . tag_end('thead'); include_once txpath . '/publish/taghandlers.php'; echo n . tag_start('tbody'); $validator = new Validator(); while ($a = nextRow($rs)) { extract($a); if ($Title === '') { $Title = '<em>' . eLink('article', 'edit', 'ID', $ID, gTxt('untitled')) . '</em>'; } else { $Title = eLink('article', 'edit', 'ID', $ID, $Title); } // Valid section and categories? $validator->setConstraints(array(new SectionConstraint($Section))); $vs = $validator->validate() ? '' : ' error'; $validator->setConstraints(array(new CategoryConstraint($Category1, array('type' => 'article')))); $vc[1] = $validator->validate() ? '' : ' error'; $validator->setConstraints(array(new CategoryConstraint($Category2, array('type' => 'article')))); $vc[2] = $validator->validate() ? '' : ' error'; $Category1 = $Category1 ? span(txpspecialchars($category1_title), array('title' => $Category1)) : ''; $Category2 = $Category2 ? span(txpspecialchars($category2_title), array('title' => $Category2)) : ''; if ($Status != STATUS_LIVE and $Status != STATUS_STICKY) { $view_url = '?txpreview=' . intval($ID) . '.' . time(); } else { $view_url = permlinkurl($a); } if (isset($statuses[$Status])) { $Status = $statuses[$Status]; } $comments = '(' . $total_comments . ')'; if ($total_comments) { $comments = href($comments, array('event' => 'discuss', 'step' => 'list', 'search_method' => 'parent', 'crit' => $ID), array('title' => gTxt('manage'))); } $comment_status = $Annotate ? gTxt('on') : gTxt('off'); if ($comments_disabled_after) { $lifespan = $comments_disabled_after * 86400; $time_since = time() - $posted; if ($time_since > $lifespan) { $comment_status = gTxt('expired'); } } $comments = tag($comment_status, 'span', array('class' => 'comments-status')) . ' ' . tag($comments, 'span', array('class' => 'comments-manage')); echo tr(td(($a['Status'] >= STATUS_LIVE and has_privs('article.edit.published') or $a['Status'] >= STATUS_LIVE and $AuthorID === $txp_user and has_privs('article.edit.own.published') or $a['Status'] < STATUS_LIVE and has_privs('article.edit') or $a['Status'] < STATUS_LIVE and $AuthorID === $txp_user and has_privs('article.edit.own')) ? fInput('checkbox', 'selected[]', $ID, 'checkbox') : '', '', 'txp-list-col-multi-edit') . hCell(eLink('article', 'edit', 'ID', $ID, $ID) . sp . span(span('[', array('aria-hidden' => 'true')) . href(gTxt('view'), $view_url) . span(']', array('aria-hidden' => 'true')), array('class' => 'txp-option-link articles_detail')), '', ' class="txp-list-col-id" scope="row"') . td($Title, '', 'txp-list-col-title') . td(gTime($posted), '', 'txp-list-col-created date' . ($posted < time() ? '' : ' unpublished')) . td(gTime($lastmod), '', 'txp-list-col-lastmod date articles_detail' . ($posted === $lastmod ? ' not-modified' : '')) . td($expires ? gTime($expires) : '', '', 'txp-list-col-expires date articles_detail') . td(span(txpspecialchars($section_title), array('title' => $Section)), '', 'txp-list-col-section' . $vs) . td($Category1, '', 'txp-list-col-category1 category articles_detail' . $vc[1]) . td($Category2, '', 'txp-list-col-category2 category articles_detail' . $vc[2]) . td(href($Status, $view_url, join_atts(array('title' => gTxt('view')))), '', 'txp-list-col-status') . ($show_authors ? td(span(txpspecialchars($RealName), array('title' => $AuthorID)), '', 'txp-list-col-author name') : '') . ($use_comments ? td($comments, '', 'txp-list-col-comments articles_detail') : '')); } echo n . tag_end('tbody') . n . tag_end('table') . n . tag_end('div') . list_multiedit_form($page, $sort, $dir, $crit, $search_method) . tInput() . n . tag_end('form') . n . tag_start('div', array('class' => 'txp-navigation', 'id' => $event . '_navigation')) . pageby_form('list', $article_list_pageby) . nav_form('list', $page, $numPages, $sort, $dir, $crit, $search_method, $total, $limit) . n . tag_end('div'); } echo n . tag_end('div'); }
function list_list($message = '', $post = '') { global $statuses, $comments_disabled_after, $step, $txp_user, $article_list_pageby, $event; pagetop(gTxt('tab_list'), $message); extract(gpsa(array('page', 'sort', 'dir', 'crit', 'search_method'))); if ($sort === '') { $sort = get_pref('article_sort_column', 'posted'); } if ($dir === '') { $dir = get_pref('article_sort_dir', 'desc'); } $dir = $dir == 'asc' ? 'asc' : 'desc'; $sesutats = array_flip($statuses); switch ($sort) { case 'id': $sort_sql = 'ID ' . $dir; break; case 'title': $sort_sql = 'Title ' . $dir . ', Posted desc'; break; case 'expires': $sort_sql = 'Expires ' . $dir; break; case 'section': $sort_sql = 'Section ' . $dir . ', Posted desc'; break; case 'category1': $sort_sql = 'Category1 ' . $dir . ', Posted desc'; break; case 'category2': $sort_sql = 'Category2 ' . $dir . ', Posted desc'; break; case 'status': $sort_sql = 'Status ' . $dir . ', Posted desc'; break; case 'author': $sort_sql = 'AuthorID ' . $dir . ', Posted desc'; break; case 'comments': $sort_sql = 'comments_count ' . $dir . ', Posted desc'; break; case 'lastmod': $sort_sql = 'LastMod ' . $dir . ', Posted desc'; break; default: $sort = 'posted'; $sort_sql = 'Posted ' . $dir; break; } set_pref('article_sort_column', $sort, 'list', 2, '', 0, PREF_PRIVATE); set_pref('article_sort_dir', $dir, 'list', 2, '', 0, PREF_PRIVATE); $switch_dir = $dir == 'desc' ? 'asc' : 'desc'; $criteria = 1; if ($search_method and $crit != '') { $verbatim = preg_match('/^"(.*)"$/', $crit, $m); $crit_escaped = doSlash($verbatim ? $m[1] : str_replace(array('\\', '%', '_', '\''), array('\\\\', '\\%', '\\_', '\\\''), $crit)); $critsql = $verbatim ? array('id' => "ID in ('" . join("','", do_list($crit_escaped)) . "')", 'title_body_excerpt' => "Title = '{$crit_escaped}' or Body = '{$crit_escaped}' or Excerpt = '{$crit_escaped}'", 'section' => "Section = '{$crit_escaped}'", 'keywords' => "FIND_IN_SET('" . $crit_escaped . "',Keywords)", 'categories' => "Category1 = '{$crit_escaped}' or Category2 = '{$crit_escaped}'", 'status' => "Status = '" . @$sesutats[gTxt($crit_escaped)] . "'", 'author' => "AuthorID = '{$crit_escaped}'", 'article_image' => "Image in ('" . join("','", do_list($crit_escaped)) . "')", 'posted' => "Posted = '{$crit_escaped}'", 'lastmod' => "LastMod = '{$crit_escaped}'") : array('id' => "ID in ('" . join("','", do_list($crit_escaped)) . "')", 'title_body_excerpt' => "Title like '%{$crit_escaped}%' or Body like '%{$crit_escaped}%' or Excerpt like '%{$crit_escaped}%'", 'section' => "Section like '%{$crit_escaped}%'", 'keywords' => "FIND_IN_SET('" . $crit_escaped . "',Keywords)", 'categories' => "Category1 like '%{$crit_escaped}%' or Category2 like '%{$crit_escaped}%'", 'status' => "Status = '" . @$sesutats[gTxt($crit_escaped)] . "'", 'author' => "AuthorID like '%{$crit_escaped}%'", 'article_image' => "Image in ('" . join("','", do_list($crit_escaped)) . "')", 'posted' => "Posted like '{$crit_escaped}%'", 'lastmod' => "LastMod like '{$crit_escaped}%'"); if (array_key_exists($search_method, $critsql)) { $criteria = $critsql[$search_method]; $limit = 500; } else { $search_method = ''; $crit = ''; } } else { $search_method = ''; $crit = ''; } $criteria .= callback_event('admin_criteria', 'list_list', 0, $criteria); $total = safe_count('textpattern', "{$criteria}"); echo '<h1 class="txp-heading">' . gTxt('tab_list') . '</h1>'; echo '<div id="' . $event . '_control" class="txp-control-panel">'; if ($total < 1) { if ($criteria != 1) { echo n . list_search_form($crit, $search_method) . n . graf(gTxt('no_results_found'), ' class="indicator"') . '</div>'; } else { echo graf(gTxt('no_articles_recorded'), ' class="indicator"') . '</div>'; } return; } $limit = max($article_list_pageby, 15); list($page, $offset, $numPages) = pager($total, $limit, $page); echo n . list_search_form($crit, $search_method) . '</div>'; $rs = safe_rows_start('*, unix_timestamp(Posted) as posted, unix_timestamp(LastMod) as lastmod, unix_timestamp(Expires) as expires', 'textpattern', "{$criteria} order by {$sort_sql} limit {$offset}, {$limit}"); if ($rs) { $show_authors = !has_single_author('textpattern', 'AuthorID'); $total_comments = array(); // fetch true comment count, not the public comment count // maybe we should have another row in the db? $rs2 = safe_rows_start('parentid, count(*) as num', 'txp_discuss', "1 group by parentid order by parentid"); if ($rs2) { while ($a = nextRow($rs2)) { $pid = $a['parentid']; $num = $a['num']; $total_comments[$pid] = $num; } } echo n . '<div id="' . $event . '_container" class="txp-container">'; echo n . n . '<form name="longform" id="articles_form" class="multi_edit_form" method="post" action="index.php">' . n . '<div class="txp-listtables">' . n . startTable('', '', 'txp-list') . n . '<thead>' . n . tr(n . hCell(fInput('checkbox', 'select_all', 0, '', '', '', '', '', 'select_all'), '', ' title="' . gTxt('toggle_all_selected') . '" class="multi-edit"') . n . column_head('ID', 'id', 'list', true, $switch_dir, $crit, $search_method, ('id' == $sort ? "{$dir} " : '') . 'id actions') . column_head('title', 'title', 'list', true, $switch_dir, $crit, $search_method, ('title' == $sort ? "{$dir} " : '') . 'title') . column_head('posted', 'posted', 'list', true, $switch_dir, $crit, $search_method, ('posted' == $sort ? "{$dir} " : '') . 'date posted created') . column_head('article_modified', 'lastmod', 'list', true, $switch_dir, $crit, $search_method, ('lastmod' == $sort ? "{$dir} " : '') . 'articles_detail date modified') . column_head('expires', 'expires', 'list', true, $switch_dir, $crit, $search_method, ('expires' == $sort ? "{$dir} " : '') . 'articles_detail date expires') . column_head('section', 'section', 'list', true, $switch_dir, $crit, $search_method, ('section' == $sort ? "{$dir} " : '') . 'section') . column_head('category1', 'category1', 'list', true, $switch_dir, $crit, $search_method, ('category1' == $sort ? "{$dir} " : '') . 'articles_detail category category1') . column_head('category2', 'category2', 'list', true, $switch_dir, $crit, $search_method, ('category2' == $sort ? "{$dir} " : '') . 'articles_detail category category2') . column_head('status', 'status', 'list', true, $switch_dir, $crit, $search_method, ('status' == $sort ? "{$dir} " : '') . 'status') . ($show_authors ? column_head('author', 'author', 'list', true, $switch_dir, $crit, $search_method, ('author' == $sort ? "{$dir} " : '') . 'author') : '') . column_head('comments', 'comments', 'list', true, $switch_dir, $crit, $search_method, ('comments' == $sort ? "{$dir} " : '') . 'articles_detail comments')) . n . '</thead>'; include_once txpath . '/publish/taghandlers.php'; echo '<tbody>'; $validator = new Validator(); while ($a = nextRow($rs)) { extract($a); if (empty($Title)) { $Title = '<em>' . eLink('article', 'edit', 'ID', $ID, gTxt('untitled')) . '</em>'; } else { $Title = eLink('article', 'edit', 'ID', $ID, $Title); } // Valid section and categories? $validator->setConstraints(array(new SectionConstraint($Section))); $vs = $validator->validate() ? '' : ' error'; $validator->setConstraints(array(new CategoryConstraint($Category1, array('type' => 'article')))); $vc[1] = $validator->validate() ? '' : ' error'; $validator->setConstraints(array(new CategoryConstraint($Category2, array('type' => 'article')))); $vc[2] = $validator->validate() ? '' : ' error'; $Category1 = $Category1 ? '<span title="' . txpspecialchars(fetch_category_title($Category1)) . '">' . $Category1 . '</span>' : ''; $Category2 = $Category2 ? '<span title="' . txpspecialchars(fetch_category_title($Category2)) . '">' . $Category2 . '</span>' : ''; if ($Status != STATUS_LIVE and $Status != STATUS_STICKY) { $view_url = '?txpreview=' . intval($ID) . '.' . time(); } else { $view_url = permlinkurl($a); } $Status = !empty($Status) ? $statuses[$Status] : ''; $comments = '(0)'; if (isset($total_comments[$ID]) and $total_comments[$ID] > 0) { $comments = href('(' . $total_comments[$ID] . ')', 'index.php?event=discuss' . a . 'step=list' . a . 'search_method=parent' . a . 'crit=' . $ID, ' title="' . gTxt('manage') . '"'); } $comment_status = $Annotate ? gTxt('on') : gTxt('off'); if ($comments_disabled_after) { $lifespan = $comments_disabled_after * 86400; $time_since = time() - $posted; if ($time_since > $lifespan) { $comment_status = gTxt('expired'); } } $comments = n . '<span class="comments-status">' . $comment_status . '</span> <span class="comments-manage">' . $comments . '</span>'; echo n . n . tr(n . td(($a['Status'] >= STATUS_LIVE and has_privs('article.edit.published') or $a['Status'] >= STATUS_LIVE and $AuthorID == $txp_user and has_privs('article.edit.own.published') or $a['Status'] < STATUS_LIVE and has_privs('article.edit') or $a['Status'] < STATUS_LIVE and $AuthorID == $txp_user and has_privs('article.edit.own')) ? fInput('checkbox', 'selected[]', $ID, 'checkbox') : ' ', '', 'multi-edit') . n . td(eLink('article', 'edit', 'ID', $ID, $ID) . sp . '<span class="articles_detail">[<a href="' . $view_url . '">' . gTxt('view') . '</a>]</span>', '', 'id') . td($Title, '', 'title') . td(gTime($posted), '', ($posted < time() ? '' : 'unpublished ') . 'date posted created') . td(gTime($lastmod), '', "articles_detail date modified") . td($expires ? gTime($expires) : '', '', 'articles_detail date expires') . td('<span title="' . txpspecialchars(fetch_section_title($Section)) . '">' . $Section . '</span>', '', 'section' . $vs) . td($Category1, '', "articles_detail category category1" . $vc[1]) . td($Category2, '', "articles_detail category category2" . $vc[2]) . td('<a href="' . $view_url . '" title="' . gTxt('view') . '">' . $Status . '</a>', '', 'status') . ($show_authors ? td('<span title="' . txpspecialchars(get_author_name($AuthorID)) . '">' . txpspecialchars($AuthorID) . '</span>', '', 'author') : '') . td($comments, '', "articles_detail comments")); } echo '</tbody>', n, endTable(), n, '</div>', n, list_multiedit_form($page, $sort, $dir, $crit, $search_method), n, tInput(), n, '</form>', n, graf(toggle_box('articles_detail'), ' class="detail-toggle"'), n, '<div id="' . $event . '_navigation" class="txp-navigation">', n, nav_form('list', $page, $numPages, $sort, $dir, $crit, $search_method, $total, $limit), n, pageby_form('list', $article_list_pageby), n, '</div>', n, '</div>'; } }
/** * Outputs the main panel listing all articles. * * @param string|array $message The activity message * @param string $post Not used */ function list_list($message = '', $post = '') { global $statuses, $use_comments, $comments_disabled_after, $step, $txp_user, $article_list_pageby, $event; pagetop(gTxt('tab_list'), $message); extract(gpsa(array('page', 'sort', 'dir', 'crit', 'search_method'))); if ($sort === '') { $sort = get_pref('article_sort_column', 'posted'); } if ($dir === '') { $dir = get_pref('article_sort_dir', 'desc'); } $dir = $dir == 'asc' ? 'asc' : 'desc'; $sesutats = array_flip($statuses); switch ($sort) { case 'id': $sort_sql = 'textpattern.ID ' . $dir; break; case 'title': $sort_sql = 'textpattern.Title ' . $dir . ', textpattern.Posted desc'; break; case 'expires': $sort_sql = 'textpattern.Expires ' . $dir; break; case 'section': $sort_sql = 'section.title ' . $dir . ', textpattern.Posted desc'; break; case 'category1': $sort_sql = 'category1.title ' . $dir . ', textpattern.Posted desc'; break; case 'category2': $sort_sql = 'category2.title ' . $dir . ', textpattern.Posted desc'; break; case 'status': $sort_sql = 'textpattern.Status ' . $dir . ', textpattern.Posted desc'; break; case 'author': $sort_sql = 'user.RealName ' . $dir . ', textpattern.Posted desc'; break; case 'comments': $sort_sql = 'textpattern.comments_count ' . $dir . ', textpattern.Posted desc'; break; case 'lastmod': $sort_sql = 'textpattern.LastMod ' . $dir . ', textpattern.Posted desc'; break; default: $sort = 'posted'; $sort_sql = 'textpattern.Posted ' . $dir; break; } set_pref('article_sort_column', $sort, 'list', 2, '', 0, PREF_PRIVATE); set_pref('article_sort_dir', $dir, 'list', 2, '', 0, PREF_PRIVATE); $switch_dir = $dir == 'desc' ? 'asc' : 'desc'; $criteria = 1; if ($search_method and $crit != '') { $verbatim = preg_match('/^"(.*)"$/', $crit, $m); $crit_escaped = $verbatim ? doSlash($m[1]) : doLike($crit); $critsql = $verbatim ? array('id' => "textpattern.ID in ('" . join("','", do_list($crit_escaped)) . "')", 'title_body_excerpt' => "textpattern.Title = '{$crit_escaped}' or textpattern.Body = '{$crit_escaped}' or textpattern.Excerpt = '{$crit_escaped}'", 'section' => "textpattern.Section = '{$crit_escaped}' or section.title = '{$crit_escaped}'", 'keywords' => "FIND_IN_SET('" . $crit_escaped . "',textpattern.Keywords)", 'categories' => "textpattern.Category1 = '{$crit_escaped}' or textpattern.Category2 = '{$crit_escaped}' or category1.title = '{$crit_escaped}' or category2.title = '{$crit_escaped}'", 'status' => "textpattern.Status = '" . @$sesutats[gTxt($crit_escaped)] . "'", 'author' => "textpattern.AuthorID = '{$crit_escaped}' or user.RealName = '{$crit_escaped}'", 'article_image' => "textpattern.Image in ('" . join("','", do_list($crit_escaped)) . "')", 'posted' => "textpattern.Posted = '{$crit_escaped}'", 'lastmod' => "textpattern.LastMod = '{$crit_escaped}'") : array('id' => "textpattern.ID in ('" . join("','", do_list($crit_escaped)) . "')", 'title_body_excerpt' => "textpattern.Title like '%{$crit_escaped}%' or textpattern.Body like '%{$crit_escaped}%' or textpattern.Excerpt like '%{$crit_escaped}%'", 'section' => "textpattern.Section like '%{$crit_escaped}%' or section.title like '%{$crit_escaped}%'", 'keywords' => "FIND_IN_SET('" . $crit_escaped . "',textpattern.Keywords)", 'categories' => "textpattern.Category1 like '%{$crit_escaped}%' or textpattern.Category2 like '%{$crit_escaped}%' or category1.title like '%{$crit_escaped}%' or category2.title like '%{$crit_escaped}%'", 'status' => "textpattern.Status = '" . @$sesutats[gTxt($crit_escaped)] . "'", 'author' => "textpattern.AuthorID like '%{$crit_escaped}%' or user.RealName like '%{$crit_escaped}%'", 'article_image' => "textpattern.Image in ('" . join("','", do_list($crit_escaped)) . "')", 'posted' => "textpattern.Posted like '{$crit_escaped}%'", 'lastmod' => "textpattern.LastMod like '{$crit_escaped}%'"); if (array_key_exists($search_method, $critsql)) { $criteria = $critsql[$search_method]; $limit = 500; } else { $search_method = ''; $crit = ''; } } else { $search_method = ''; $crit = ''; } $criteria .= callback_event('admin_criteria', 'list_list', 0, $criteria); $sql_from = safe_pfx('textpattern') . " textpattern\n left join " . safe_pfx('txp_category') . " category1 on category1.name = textpattern.Category1 and category1.type = 'article'\n left join " . safe_pfx('txp_category') . " category2 on category2.name = textpattern.Category2 and category2.type = 'article'\n left join " . safe_pfx('txp_section') . " section on section.name = textpattern.Section\n left join " . safe_pfx('txp_users') . " user on user.name = textpattern.AuthorID"; if ($criteria === 1) { $total = safe_count('textpattern', $criteria); } else { $total = getThing('select count(*) from ' . $sql_from . ' where ' . $criteria); } echo hed(gTxt('tab_list'), 1, array('class' => 'txp-heading')); echo n . '<div id="' . $event . '_control" class="txp-control-panel">'; if ($total < 1) { if ($criteria != 1) { echo list_search_form($crit, $search_method) . graf(gTxt('no_results_found'), ' class="indicator"') . '</div>'; } else { echo graf(gTxt('no_articles_recorded'), ' class="indicator"') . '</div>'; } return; } $limit = max($article_list_pageby, 15); list($page, $offset, $numPages) = pager($total, $limit, $page); echo list_search_form($crit, $search_method) . '</div>'; $rs = safe_query("select\n textpattern.ID, textpattern.Title, textpattern.url_title, textpattern.Section,\n textpattern.Category1, textpattern.Category2,\n textpattern.Status, textpattern.Annotate, textpattern.AuthorID,\n unix_timestamp(textpattern.Posted) as posted,\n unix_timestamp(textpattern.LastMod) as lastmod,\n unix_timestamp(textpattern.Expires) as expires,\n category1.title as category1_title,\n category2.title as category2_title,\n section.title as section_title,\n user.RealName as RealName,\n (select count(*) from " . safe_pfx('txp_discuss') . " where parentid = textpattern.ID) as total_comments\n from {$sql_from} where {$criteria} order by {$sort_sql} limit {$offset}, {$limit}"); if ($rs) { $show_authors = !has_single_author('textpattern', 'AuthorID'); echo n . tag_start('div', array('id' => $event . '_container', 'class' => 'txp-container')) . n . tag_start('form', array('action' => 'index.php', 'id' => 'articles_form', 'class' => 'multi_edit_form', 'method' => 'post', 'name' => 'longform')) . n . tag_start('div', array('class' => 'txp-listtables')) . n . tag_start('table', array('class' => 'txp-list')) . n . tag_start('thead') . tr(hCell(fInput('checkbox', 'select_all', 0, '', '', '', '', '', 'select_all'), '', ' scope="col" title="' . gTxt('toggle_all_selected') . '" class="txp-list-col-multi-edit"') . column_head('ID', 'id', 'list', true, $switch_dir, $crit, $search_method, ('id' == $sort ? "{$dir} " : '') . 'txp-list-col-id') . column_head('title', 'title', 'list', true, $switch_dir, $crit, $search_method, ('title' == $sort ? "{$dir} " : '') . 'txp-list-col-title') . column_head('posted', 'posted', 'list', true, $switch_dir, $crit, $search_method, ('posted' == $sort ? "{$dir} " : '') . 'txp-list-col-created date') . column_head('article_modified', 'lastmod', 'list', true, $switch_dir, $crit, $search_method, ('lastmod' == $sort ? "{$dir} " : '') . 'txp-list-col-lastmod date articles_detail') . column_head('expires', 'expires', 'list', true, $switch_dir, $crit, $search_method, ('expires' == $sort ? "{$dir} " : '') . 'txp-list-col-expires date articles_detail') . column_head('section', 'section', 'list', true, $switch_dir, $crit, $search_method, ('section' == $sort ? "{$dir} " : '') . 'txp-list-col-section') . column_head('category1', 'category1', 'list', true, $switch_dir, $crit, $search_method, ('category1' == $sort ? "{$dir} " : '') . 'txp-list-col-category1 category articles_detail') . column_head('category2', 'category2', 'list', true, $switch_dir, $crit, $search_method, ('category2' == $sort ? "{$dir} " : '') . 'txp-list-col-category2 category articles_detail') . column_head('status', 'status', 'list', true, $switch_dir, $crit, $search_method, ('status' == $sort ? "{$dir} " : '') . 'txp-list-col-status') . ($show_authors ? column_head('author', 'author', 'list', true, $switch_dir, $crit, $search_method, ('author' == $sort ? "{$dir} " : '') . 'txp-list-col-author name') : '') . ($use_comments == 1 ? column_head('comments', 'comments', 'list', true, $switch_dir, $crit, $search_method, ('comments' == $sort ? "{$dir} " : '') . 'txp-list-col-comments articles_detail') : '')) . n . tag_end('thead'); include_once txpath . '/publish/taghandlers.php'; echo n . tag_start('tbody'); $validator = new Validator(); while ($a = nextRow($rs)) { extract($a); if ($Title === '') { $Title = '<em>' . eLink('article', 'edit', 'ID', $ID, gTxt('untitled')) . '</em>'; } else { $Title = eLink('article', 'edit', 'ID', $ID, $Title); } // Valid section and categories? $validator->setConstraints(array(new SectionConstraint($Section))); $vs = $validator->validate() ? '' : ' error'; $validator->setConstraints(array(new CategoryConstraint($Category1, array('type' => 'article')))); $vc[1] = $validator->validate() ? '' : ' error'; $validator->setConstraints(array(new CategoryConstraint($Category2, array('type' => 'article')))); $vc[2] = $validator->validate() ? '' : ' error'; $Category1 = $Category1 ? span(txpspecialchars($category1_title), array('title' => $Category1)) : ''; $Category2 = $Category2 ? span(txpspecialchars($category2_title), array('title' => $Category2)) : ''; if ($Status != STATUS_LIVE and $Status != STATUS_STICKY) { $view_url = '?txpreview=' . intval($ID) . '.' . time(); } else { $view_url = permlinkurl($a); } if (isset($statuses[$Status])) { $Status = $statuses[$Status]; } $comments = '(' . $total_comments . ')'; if ($total_comments) { $comments = href($comments, array('event' => 'discuss', 'step' => 'list', 'search_method' => 'parent', 'crit' => $ID), array('title' => gTxt('manage'))); } $comment_status = $Annotate ? gTxt('on') : gTxt('off'); if ($comments_disabled_after) { $lifespan = $comments_disabled_after * 86400; $time_since = time() - $posted; if ($time_since > $lifespan) { $comment_status = gTxt('expired'); } } $comments = tag($comment_status, 'span', array('class' => 'comments-status')) . ' ' . tag($comments, 'span', array('class' => 'comments-manage')); echo tr(td(($a['Status'] >= STATUS_LIVE and has_privs('article.edit.published') or $a['Status'] >= STATUS_LIVE and $AuthorID === $txp_user and has_privs('article.edit.own.published') or $a['Status'] < STATUS_LIVE and has_privs('article.edit') or $a['Status'] < STATUS_LIVE and $AuthorID === $txp_user and has_privs('article.edit.own')) ? fInput('checkbox', 'selected[]', $ID, 'checkbox') : '', '', 'txp-list-col-multi-edit') . hCell(eLink('article', 'edit', 'ID', $ID, $ID) . tag(sp . tag('[', 'span', array('aria-hidden' => 'true')) . href(gTxt('view'), $view_url) . tag(']', 'span', array('aria-hidden' => 'true')), 'span', array('class' => 'articles_detail')), '', ' scope="row" class="txp-list-col-id"') . td($Title, '', 'txp-list-col-title') . td(gTime($posted), '', 'txp-list-col-created date' . ($posted < time() ? '' : ' unpublished')) . td(gTime($lastmod), '', 'txp-list-col-lastmod date articles_detail' . ($posted === $lastmod ? ' not-modified' : '')) . td($expires ? gTime($expires) : '', '', 'txp-list-col-expires date articles_detail') . td(span(txpspecialchars($section_title), array('title' => $Section)), '', 'txp-list-col-section' . $vs) . td($Category1, '', 'txp-list-col-category1 category articles_detail' . $vc[1]) . td($Category2, '', 'txp-list-col-category2 category articles_detail' . $vc[2]) . td(href($Status, $view_url, join_atts(array('title' => gTxt('view')))), '', 'txp-list-col-status') . ($show_authors ? td(span(txpspecialchars($RealName), array('title' => $AuthorID)), '', 'txp-list-col-author name') : '') . ($use_comments ? td($comments, '', 'txp-list-col-comments articles_detail') : '')); } echo n . tag_end('tbody') . n . tag_end('table') . n . tag_end('div') . list_multiedit_form($page, $sort, $dir, $crit, $search_method) . tInput() . n . tag_end('form') . graf(toggle_box('articles_detail'), array('class' => 'detail-toggle')) . n . tag_start('div', array('id' => $event . '_navigation', 'class' => 'txp-navigation')) . pageby_form('list', $article_list_pageby) . nav_form('list', $page, $numPages, $sort, $dir, $crit, $search_method, $total, $limit) . n . tag_end('div') . n . tag_end('div'); } }