function file_list($message = '') { global $file_base_path, $file_statuses, $file_list_pageby, $txp_user, $event; pagetop(gTxt('tab_file'), $message); extract(gpsa(array('page', 'sort', 'dir', 'crit', 'search_method'))); if ($sort === '') { $sort = get_pref('file_sort_column', 'filename'); } if ($dir === '') { $dir = get_pref('file_sort_dir', 'asc'); } if ($dir === 'desc') { $dir = 'desc'; } else { $dir = 'asc'; } echo hed(gTxt('tab_file'), 1, array('class' => 'txp-heading')) . n . tag_start('div', array('id' => $event . '_control', 'class' => 'txp-control-panel')); if (!is_dir($file_base_path) || !is_writeable($file_base_path)) { echo graf(span(null, array('class' => 'ui-icon ui-icon-alert')) . ' ' . gTxt('file_dir_not_writeable', array('{filedir}' => $file_base_path)), array('class' => 'alert-block warning')); } elseif (has_privs('file.edit.own')) { $existing_files = get_filenames(); if ($existing_files) { echo form(eInput('file') . sInput('file_create') . graf(tag(gTxt('existing_file'), 'label', array('for' => 'file-existing')) . sp . selectInput('filename', $existing_files, '', 1, '', 'file-existing') . sp . fInput('submit', '', gTxt('Create')), array('class' => 'existing-file')), '', '', 'post', '', '', 'assign_file'); } echo file_upload_form(gTxt('upload_file'), 'upload', 'file_insert'); } switch ($sort) { case 'id': $sort_sql = 'txp_file.id ' . $dir; break; case 'description': $sort_sql = 'txp_file.description ' . $dir . ', txp_file.filename desc'; break; case 'category': $sort_sql = 'txp_category.title ' . $dir . ', txp_file.filename desc'; break; case 'title': $sort_sql = 'txp_file.title ' . $dir . ', txp_file.filename desc'; break; case 'downloads': $sort_sql = 'txp_file.downloads ' . $dir . ', txp_file.filename desc'; break; case 'author': $sort_sql = 'txp_users.RealName ' . $dir . ', txp_file.id asc'; break; default: $sort = 'filename'; $sort_sql = 'txp_file.filename ' . $dir; break; } set_pref('file_sort_column', $sort, 'file', PREF_HIDDEN, '', 0, PREF_PRIVATE); set_pref('file_sort_dir', $dir, 'file', PREF_HIDDEN, '', 0, PREF_PRIVATE); if ($dir == 'desc') { $switch_dir = 'asc'; } else { $switch_dir = 'desc'; } $criteria = 1; if ($search_method && $crit !== '') { $verbatim = preg_match('/^"(.*)"$/', $crit, $m); $crit_escaped = $verbatim ? doSlash($m[1]) : doLike($crit); $critsql = $verbatim ? array('id' => "txp_file.id in ('" . join("','", do_list($crit_escaped)) . "')", 'filename' => "txp_file.filename = '{$crit_escaped}'", 'title' => "txp_file.title = '{$crit_escaped}'", 'description' => "txp_file.description = '{$crit_escaped}'", 'category' => "txp_file.category = '{$crit_escaped}' or txp_category.title = '{$crit_escaped}'", 'author' => "txp_file.author = '{$crit_escaped}' or txp_users.RealName = '{$crit_escaped}'") : array('id' => "txp_file.id in ('" . join("','", do_list($crit_escaped)) . "')", 'filename' => "txp_file.filename like '%{$crit_escaped}%'", 'title' => "txp_file.title like '%{$crit_escaped}%'", 'description' => "txp_file.description like '%{$crit_escaped}%'", 'category' => "txp_file.category like '%{$crit_escaped}%' or txp_category.title like '%{$crit_escaped}%'", 'author' => "txp_file.author like '%{$crit_escaped}%' or txp_users.RealName 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', 'file_list', 0, $criteria); $sql_from = safe_pfx_j('txp_file') . "\n left join " . safe_pfx_j('txp_category') . " on txp_category.name = txp_file.category and txp_category.type = 'file'\n left join " . safe_pfx_j('txp_users') . " on txp_users.name = txp_file.author"; if ($criteria === 1) { $total = safe_count('txp_file', $criteria); } else { $total = getThing('select count(*) from ' . $sql_from . ' where ' . $criteria); } if ($total < 1) { if ($criteria != 1) { echo file_search_form($crit, $search_method) . graf(gTxt('no_results_found'), ' class="indicator"') . '</div>'; } else { echo graf(gTxt('no_files_recorded'), ' class="indicator"') . '</div>'; } return; } $limit = max($file_list_pageby, 15); list($page, $offset, $numPages) = pager($total, $limit, $page); echo file_search_form($crit, $search_method) . '</div>'; $rs = safe_query("select\n txp_file.id,\n txp_file.filename,\n txp_file.title,\n txp_file.category,\n txp_file.description,\n txp_file.downloads,\n txp_file.status,\n txp_file.author,\n txp_users.RealName as realname,\n txp_category.Title as category_title\n from {$sql_from} where {$criteria} order by {$sort_sql} limit {$offset}, {$limit}"); if ($rs && numRows($rs)) { $show_authors = !has_single_author('txp_file'); echo n . tag_start('div', array('id' => $event . '_container', 'class' => 'txp-container')) . n . tag_start('form', array('action' => 'index.php', 'id' => 'files_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', 'file', true, $switch_dir, $crit, $search_method, ('id' == $sort ? "{$dir} " : '') . 'txp-list-col-id') . column_head('file_name', 'filename', 'file', true, $switch_dir, $crit, $search_method, ('filename' == $sort ? "{$dir} " : '') . 'txp-list-col-filename') . column_head('title', 'title', 'file', true, $switch_dir, $crit, $search_method, ('title' == $sort ? "{$dir} " : '') . 'txp-list-col-title') . column_head('description', 'description', 'file', true, $switch_dir, $crit, $search_method, ('description' == $sort ? "{$dir} " : '') . 'txp-list-col-description files_detail') . column_head('file_category', 'category', 'file', true, $switch_dir, $crit, $search_method, ('category' == $sort ? "{$dir} " : '') . 'txp-list-col-category category') . hCell(gTxt('tags'), '', ' scope="col" class="txp-list-col-tag-build files_detail"') . hCell(gTxt('status'), '', ' scope="col" class="txp-list-col-status"') . hCell(gTxt('condition'), '', ' scope="col" class="txp-list-col-condition"') . column_head('downloads', 'downloads', 'file', true, $switch_dir, $crit, $search_method, ('downloads' == $sort ? "{$dir} " : '') . 'txp-list-col-downloads') . ($show_authors ? column_head('author', 'author', 'file', true, $switch_dir, $crit, $search_method, ('author' == $sort ? "{$dir} " : '') . 'txp-list-col-author name') : '')) . n . tag_end('thead') . n . tag_start('tbody'); $validator = new Validator(); while ($a = nextRow($rs)) { extract($a); $filename = sanitizeForFile($filename); $edit_url = array('event' => 'file', 'step' => 'file_edit', 'id' => $id, 'sort' => $sort, 'dir' => $dir, 'page' => $page, 'search_method' => $search_method, 'crit' => $crit); $tag_url = array('event' => 'tag', 'tag_name' => 'file_download_link', 'id' => $id, 'description' => $description, 'filename' => $filename); $file_exists = file_exists(build_file_path($file_base_path, $filename)); $can_edit = has_privs('file.edit') || $author === $txp_user && has_privs('file.edit.own'); $validator->setConstraints(array(new CategoryConstraint($category, array('type' => 'file')))); if ($validator->validate()) { $vc = ''; } else { $vc = ' error'; } if ($file_exists) { $downloads = make_download_link($id, $downloads, $filename); $condition = span(gTxt('file_status_ok'), array('class' => 'success')); } else { $condition = span(gTxt('file_status_missing'), array('class' => 'error')); } if ($category) { $category = span(txpspecialchars($category_title), array('title' => $category)); } if ($can_edit) { $name = href(txpspecialchars($filename), $edit_url, array('title' => gTxt('edit'))); } else { $name = txpspecialchars($filename); } if ($can_edit) { $id_column = href($id, $edit_url, array('title' => gTxt('edit'))); $multi_edit = fInput('checkbox', 'selected[]', $id); } else { $id_column = $id; $multi_edit = ''; } if ($file_exists) { $id_column .= sp . span('[', array('aria-hidden' => 'true')) . make_download_link($id, gTxt('download'), $filename) . span(']', array('aria-hidden' => 'true')); } if (isset($file_statuses[$status])) { $status = $file_statuses[$status]; } else { $status = span(gTxt('none'), array('class' => 'error')); } echo tr(td($multi_edit, '', 'txp-list-col-multi-edit') . hCell($id_column, '', array('scope' => 'row', 'class' => 'txp-list-col-id')) . td($name, '', 'txp-list-col-filename') . td(txpspecialchars($title), '', 'txp-list-col-title') . td(txpspecialchars($description), '', 'txp-list-col-description files_detail') . td($category, '', 'txp-list-col-category category' . $vc) . td(href('Textile', $tag_url + array('type' => 'textile'), ' target="_blank" onclick="popWin(this.href); return false;"') . sp . span('|', array('role' => 'separator')) . sp . href('Textpattern', $tag_url + array('type' => 'textpattern'), ' target="_blank" onclick="popWin(this.href); return false;"') . sp . span('|', array('role' => 'separator')) . sp . href('HTML', $tag_url + array('type' => 'html'), ' target="_blank" onclick="popWin(this.href); return false;"'), '', 'txp-list-col-tag-build files_detail') . td($status, '', 'txp-list-col-status') . td($condition, '', 'txp-list-col-condition') . td($downloads, '', 'txp-list-col-downloads') . ($show_authors ? td(span(txpspecialchars($realname), array('title' => $author)), '', 'txp-list-col-author name') : '')); } echo n . tag_end('tbody') . n . tag_end('table') . n . tag_end('div') . file_multiedit_form($page, $sort, $dir, $crit, $search_method) . tInput() . n . tag_end('form') . graf(toggle_box('files_detail'), array('class' => 'detail-toggle')) . n . tag_start('div', array('id' => $event . '_navigation', 'class' => 'txp-navigation')) . pageby_form('file', $file_list_pageby) . nav_form('file', $page, $numPages, $sort, $dir, $crit, $search_method, $total, $limit) . n . tag_end('div') . n . tag_end('div'); } }
function link_list($message = '') { global $event, $step, $link_list_pageby, $txp_user; pagetop(gTxt('tab_link'), $message); extract(gpsa(array('page', 'sort', 'dir', 'crit', 'search_method'))); if ($sort === '') { $sort = get_pref('link_sort_column', 'name'); } if ($dir === '') { $dir = get_pref('link_sort_dir', 'asc'); } $dir = $dir == 'desc' ? 'desc' : 'asc'; switch ($sort) { case 'id': $sort_sql = 'id ' . $dir; break; case 'description': $sort_sql = 'description ' . $dir . ', id asc'; break; case 'url': $sort_sql = 'url ' . $dir . ', id asc'; break; case 'category': $sort_sql = 'category ' . $dir . ', id asc'; break; case 'date': $sort_sql = 'date ' . $dir . ', id asc'; break; case 'author': $sort_sql = 'author ' . $dir . ', id asc'; break; default: $sort = 'name'; $sort_sql = 'linksort ' . $dir . ', id asc'; break; } set_pref('link_sort_column', $sort, 'link', 2, '', 0, PREF_PRIVATE); set_pref('link_sort_dir', $dir, 'link', 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)) . "')", 'name' => "linkname = '{$crit_escaped}'", 'description' => "description = '{$crit_escaped}'", 'url' => "url = '{$crit_escaped}'", 'category' => "category = '{$crit_escaped}'", 'author' => "author = '{$crit_escaped}'") : array('id' => "ID in ('" . join("','", do_list($crit_escaped)) . "')", 'name' => "linkname like '%{$crit_escaped}%'", 'description' => "description like '%{$crit_escaped}%'", 'url' => "url like '%{$crit_escaped}%'", 'category' => "category like '%{$crit_escaped}%'", 'author' => "author like '%{$crit_escaped}%'"); if (array_key_exists($search_method, $critsql)) { $criteria = $critsql[$search_method]; } else { $search_method = ''; $crit = ''; } } else { $search_method = ''; $crit = ''; } $criteria .= callback_event('admin_criteria', 'link_list', 0, $criteria); $total = getCount('txp_link', $criteria); echo '<h1 class="txp-heading">' . gTxt('tab_link') . '</h1>'; echo '<div id="' . $event . '_control" class="txp-control-panel">'; if (has_privs('link.edit')) { echo graf(sLink('link', 'link_edit', gTxt('add_new_link')), ' class="txp-buttons"'); } if ($total < 1) { if ($criteria != 1) { echo n . link_search_form($crit, $search_method) . n . graf(gTxt('no_results_found'), ' class="indicator"') . '</div>'; } else { echo n . graf(gTxt('no_links_recorded'), ' class="indicator"') . '</div>'; } return; } $limit = max($link_list_pageby, 15); list($page, $offset, $numPages) = pager($total, $limit, $page); echo link_search_form($crit, $search_method) . '</div>'; $rs = safe_rows_start('*, unix_timestamp(date) as uDate', 'txp_link', "{$criteria} order by {$sort_sql} limit {$offset}, {$limit}"); if ($rs) { $show_authors = !has_single_author('txp_link'); echo n . '<div id="' . $event . '_container" class="txp-container">'; echo n . n . '<form action="index.php" id="links_form" class="multi_edit_form" method="post" name="longform">', 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', 'link', true, $switch_dir, $crit, $search_method, ('id' == $sort ? "{$dir} " : '') . 'id') . n . column_head('link_name', 'name', 'link', true, $switch_dir, $crit, $search_method, ('name' == $sort ? "{$dir} " : '') . 'name') . n . column_head('description', 'description', 'link', true, $switch_dir, $crit, $search_method, ('description' == $sort ? "{$dir} " : '') . 'links_detail description') . n . column_head('link_category', 'category', 'link', true, $switch_dir, $crit, $search_method, ('category' == $sort ? "{$dir} " : '') . 'category') . n . column_head('url', 'url', 'link', true, $switch_dir, $crit, $search_method, ('url' == $sort ? "{$dir} " : '') . 'url') . n . column_head('date', 'date', 'link', true, $switch_dir, $crit, $search_method, ('date' == $sort ? "{$dir} " : '') . 'links_detail date created') . ($show_authors ? n . column_head('author', 'author', 'link', true, $switch_dir, $crit, $search_method, ('author' == $sort ? "{$dir} " : '') . 'author') : '')) . n . '</thead>'; echo '<tbody>'; $validator = new Validator(); while ($a = nextRow($rs)) { extract($a, EXTR_PREFIX_ALL, 'link'); $edit_url = '?event=link' . a . 'step=link_edit' . a . 'id=' . $link_id . a . 'sort=' . $sort . a . 'dir=' . $dir . a . 'page=' . $page . a . 'search_method=' . $search_method . a . 'crit=' . $crit; $validator->setConstraints(array(new CategoryConstraint($link_category, array('type' => 'link')))); $vc = $validator->validate() ? '' : ' error'; $can_edit = has_privs('link.edit') || $link_author == $txp_user && has_privs('link.edit.own'); $view_url = txpspecialchars($link_url); echo tr(n . td(fInput('checkbox', 'selected[]', $link_id), '', 'multi-edit') . n . td($can_edit ? href($link_id, $edit_url, ' title="' . gTxt('edit') . '"') : $link_id, '', 'id') . td($can_edit ? href(txpspecialchars($link_linkname), $edit_url, ' title="' . gTxt('edit') . '"') : txpspecialchars($link_linkname), '', 'name') . td(txpspecialchars($link_description), '', 'links_detail description') . td('<span title="' . txpspecialchars(fetch_category_title($link_category, 'link')) . '">' . $link_category . '</span>', '', 'category' . $vc) . td('<a rel="external" target="_blank" href="' . $view_url . '">' . $view_url . '</a>', '', 'url') . td(gTime($link_uDate), '', 'links_detail date created') . ($show_authors ? td('<span title="' . txpspecialchars(get_author_name($link_author)) . '">' . txpspecialchars($link_author) . '</span>', '', 'author') : '')); } echo '</tbody>', n, endTable(), n, '</div>', n, link_multiedit_form($page, $sort, $dir, $crit, $search_method), n, tInput(), n, '</form>', n, graf(toggle_box('links_detail'), ' class="detail-toggle"'), n, '<div id="' . $event . '_navigation" class="txp-navigation">', n, nav_form('link', $page, $numPages, $sort, $dir, $crit, $search_method, $total, $limit), n, pageby_form('link', $link_list_pageby), n, '</div>', n, '</div>'; } }
function image_list($message = '') { global $txpcfg, $extensions, $img_dir, $file_max_upload_size, $image_list_pageby, $txp_user, $event; pagetop(gTxt('tab_image'), $message); extract($txpcfg); extract(gpsa(array('page', 'sort', 'dir', 'crit', 'search_method'))); if ($sort === '') { $sort = get_pref('image_sort_column', 'id'); } if ($dir === '') { $dir = get_pref('image_sort_dir', 'desc'); } $dir = $dir == 'asc' ? 'asc' : 'desc'; echo hed(gTxt('tab_image'), 1, array('class' => 'txp-heading')); echo n . '<div id="' . $event . '_control" class="txp-control-panel">'; if (!is_dir(IMPATH) or !is_writeable(IMPATH)) { echo graf(span(null, array('class' => 'ui-icon ui-icon-alert')) . ' ' . gTxt('img_dir_not_writeable', array('{imgdir}' => IMPATH)), array('class' => 'alert-block warning')); } elseif (has_privs('image.edit.own')) { echo upload_form(gTxt('upload_image'), 'upload_image', 'image_insert', 'image', '', $file_max_upload_size); } switch ($sort) { case 'name': $sort_sql = 'name ' . $dir; break; case 'thumbnail': $sort_sql = 'thumbnail ' . $dir . ', id asc'; break; case 'category': $sort_sql = 'category ' . $dir . ', id asc'; break; case 'date': $sort_sql = 'date ' . $dir . ', id asc'; break; case 'author': $sort_sql = 'author ' . $dir . ', id asc'; break; default: $sort = 'id'; $sort_sql = 'id ' . $dir; break; } set_pref('image_sort_column', $sort, 'image', 2, '', 0, PREF_PRIVATE); set_pref('image_sort_dir', $dir, 'image', 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' => "ID in ('" . join("','", do_list($crit_escaped)) . "')", 'name' => "name = '{$crit_escaped}'", 'category' => "category = '{$crit_escaped}'", 'author' => "author = '{$crit_escaped}'", 'alt' => "alt = '{$crit_escaped}'", 'caption' => "caption = '{$crit_escaped}'") : array('id' => "ID in ('" . join("','", do_list($crit_escaped)) . "')", 'name' => "name like '%{$crit_escaped}%'", 'category' => "category like '%{$crit_escaped}%'", 'author' => "author like '%{$crit_escaped}%'", 'alt' => "alt like '%{$crit_escaped}%'", 'caption' => "caption 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', 'image_list', 0, $criteria); $total = safe_count('txp_image', "{$criteria}"); if ($total < 1) { if ($criteria != 1) { echo n . image_search_form($crit, $search_method) . graf(gTxt('no_results_found'), ' class="indicator"') . '</div>'; } else { echo graf(gTxt('no_images_recorded'), ' class="indicator"') . '</div>'; } return; } $limit = max($image_list_pageby, 15); list($page, $offset, $numPages) = pager($total, $limit, $page); echo image_search_form($crit, $search_method); $rs = safe_rows_start('*, unix_timestamp(date) as uDate', 'txp_image', "{$criteria} order by {$sort_sql} limit {$offset}, {$limit}\n "); echo pluggable_ui('image_ui', 'extend_controls', '', $rs); echo '</div>'; // End txp-control-panel. if ($rs) { $show_authors = !has_single_author('txp_image'); echo n . tag_start('div', array('id' => $event . '_container', 'class' => 'txp-container')) . n . tag_start('form', array('action' => 'index.php', 'id' => 'images_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', 'image', true, $switch_dir, $crit, $search_method, ('id' == $sort ? "{$dir} " : '') . 'txp-list-col-id') . column_head('name', 'name', 'image', true, $switch_dir, $crit, $search_method, ('name' == $sort ? "{$dir} " : '') . 'txp-list-col-name') . column_head('date', 'date', 'image', true, $switch_dir, $crit, $search_method, ('date' == $sort ? "{$dir} " : '') . 'txp-list-col-created date images_detail') . column_head('thumbnail', 'thumbnail', 'image', true, $switch_dir, $crit, $search_method, ('thumbnail' == $sort ? "{$dir} " : '') . 'txp-list-col-thumbnail') . hCell(gTxt('tags'), '', ' scope="col" class="txp-list-col-tag-build images_detail"') . column_head('image_category', 'category', 'image', true, $switch_dir, $crit, $search_method, ('category' == $sort ? "{$dir} " : '') . 'txp-list-col-category category') . ($show_authors ? column_head('author', 'author', 'image', true, $switch_dir, $crit, $search_method, ('author' == $sort ? "{$dir} " : '') . 'txp-list-col-author name') : '')) . n . tag_end('thead') . n . tag_start('tbody'); $validator = new Validator(); while ($a = nextRow($rs)) { extract($a); $edit_url = array('event' => 'image', 'step' => 'image_edit', 'id' => $id, 'sort' => $sort, 'dir' => $dir, 'page' => $page, 'search_method' => $search_method, 'crit' => $crit); $name = empty($name) ? gTxt('unnamed') : txpspecialchars($name); if ($thumbnail) { if ($ext != '.swf') { $thumbnail = '<img class="content-image" src="' . imagesrcurl($id, $ext, true) . "?{$uDate}" . '" alt="" ' . "title='{$id}{$ext} ({$w} × {$h})'" . ($thumb_w ? " width='{$thumb_w}' height='{$thumb_h}'" : '') . ' />'; } else { $thumbnail = ''; } } else { $thumbnail = gTxt('no'); } if ($ext != '.swf') { $tag_url = '?event=tag' . a . 'tag_name=image' . a . 'id=' . $id . a . 'ext=' . $ext . a . 'w=' . $w . a . 'h=' . $h . a . 'alt=' . urlencode($alt) . a . 'caption=' . urlencode($caption); $tagbuilder = href('Textile', $tag_url . a . 'type=textile', ' target="_blank" onclick="popWin(this.href); return false;"') . sp . span('|', array('role' => 'separator')) . sp . href('Textpattern', $tag_url . a . 'type=textpattern', ' target="_blank" onclick="popWin(this.href); return false;"') . sp . span('|', array('role' => 'separator')) . sp . href('HTML', $tag_url . a . 'type=html', ' target="_blank" onclick="popWin(this.href); return false;"'); } else { $tagbuilder = sp; } $validator->setConstraints(array(new CategoryConstraint($category, array('type' => 'image')))); $vc = $validator->validate() ? '' : ' error'; $category = $category ? span($category, array('title' => fetch_category_title($category, 'image'))) : ''; $can_edit = has_privs('image.edit') || $author === $txp_user && has_privs('image.edit.own'); echo tr(td($can_edit ? fInput('checkbox', 'selected[]', $id) : ' ', '', 'txp-list-col-multi-edit') . hCell(($can_edit ? href($id, $edit_url, array('title' => gTxt('edit'))) : $id) . sp . span(span('[', array('aria-hidden' => 'true')) . href(gTxt('view'), imagesrcurl($id, $ext)) . span(']', array('aria-hidden' => 'true')), array('class' => 'images_detail')), '', ' scope="row" class="txp-list-col-id"') . td($can_edit ? href($name, $edit_url, ' title="' . gTxt('edit') . '"') : $name, '', 'txp-list-col-name') . td(gTime($uDate), '', 'txp-list-col-created date images_detail') . td(pluggable_ui('image_ui', 'thumbnail', $can_edit ? href($thumbnail, $edit_url) : $thumbnail, $a), '', 'txp-list-col-thumbnail') . td($tagbuilder, '', 'txp-list-col-tag-build images_detail') . td($category, '', 'txp-list-col-category category' . $vc) . ($show_authors ? td(span(txpspecialchars($author), array('title' => get_author_name($author))), '', 'txp-list-col-author name') : '')); } echo n . tag_end('tbody') . n . tag_end('table') . n . tag_end('div') . image_multiedit_form($page, $sort, $dir, $crit, $search_method) . tInput() . n . tag_end('form') . graf(toggle_box('images_detail'), array('class' => 'detail-toggle')) . n . tag_start('div', array('id' => $event . '_navigation', 'class' => 'txp-navigation')) . pageby_form('image', $image_list_pageby) . nav_form('image', $page, $numPages, $sort, $dir, $crit, $search_method, $total, $limit) . n . tag_end('div') . n . tag_end('div'); } }
/** * Renders article editor form. * * @param string|array $message The activity message * @param bool $concurrent Treat as a concurrent save * @param bool $refresh_partials Whether refresh partial contents */ function article_edit($message = '', $concurrent = false, $refresh_partials = false) { global $vars, $txp_user, $prefs, $event, $view; extract($prefs); /* $partials is an array of: $key => array ( 'mode' => {PARTIAL_STATIC | PARTIAL_VOLATILE | PARTIAL_VOLATILE_VALUE}, 'selector' => $DOM_selector, 'cb' => $callback_function, 'html' => $return_value_of_callback_function (need not be intialised here) ) */ $partials = array('html_title' => array('mode' => PARTIAL_VOLATILE, 'selector' => 'title', 'cb' => 'article_partial_html_title'), 'sLastMod' => array('mode' => PARTIAL_VOLATILE_VALUE, 'selector' => '[name=sLastMod]', 'cb' => 'article_partial_value'), 'sPosted' => array('mode' => PARTIAL_VOLATILE_VALUE, 'selector' => '[name=sPosted]', 'cb' => 'article_partial_value'), 'sidehelp' => array('mode' => PARTIAL_VOLATILE, 'selector' => '#textfilter_group', 'cb' => 'article_partial_sidehelp'), 'url_title' => array('mode' => PARTIAL_STATIC, 'selector' => 'p.url-title', 'cb' => 'article_partial_url_title'), 'url_title_value' => array('mode' => PARTIAL_VOLATILE_VALUE, 'selector' => '#url-title', 'cb' => 'article_partial_url_title_value'), 'description' => array('mode' => PARTIAL_STATIC, 'selector' => 'p.description', 'cb' => 'article_partial_description'), 'description_value' => array('mode' => PARTIAL_VOLATILE_VALUE, 'selector' => '#description', 'cb' => 'article_partial_description_value'), 'keywords' => array('mode' => PARTIAL_STATIC, 'selector' => 'p.keywords', 'cb' => 'article_partial_keywords'), 'keywords_value' => array('mode' => PARTIAL_VOLATILE_VALUE, 'selector' => '#keywords', 'cb' => 'article_partial_keywords_value'), 'image' => array('mode' => PARTIAL_STATIC, 'selector' => '#image_group', 'cb' => 'article_partial_image'), 'custom_fields' => array('mode' => PARTIAL_STATIC, 'selector' => '#custom_field_group', 'cb' => 'article_partial_custom_fields'), 'recent_articles' => array('mode' => PARTIAL_VOLATILE, 'selector' => '#recent_group .recent', 'cb' => 'article_partial_recent_articles'), 'title' => array('mode' => PARTIAL_STATIC, 'selector' => 'p.title', 'cb' => 'article_partial_title'), 'title_value' => array('mode' => PARTIAL_VOLATILE_VALUE, 'selector' => '#title', 'cb' => 'article_partial_title_value'), 'article_clone' => array('mode' => PARTIAL_VOLATILE, 'selector' => '#article_partial_article_clone', 'cb' => 'article_partial_article_clone'), 'article_view' => array('mode' => PARTIAL_VOLATILE, 'selector' => '#article_partial_article_view', 'cb' => 'article_partial_article_view'), 'body' => array('mode' => PARTIAL_STATIC, 'selector' => 'p.body', 'cb' => 'article_partial_body'), 'excerpt' => array('mode' => PARTIAL_STATIC, 'selector' => 'p.excerpt', 'cb' => 'article_partial_excerpt'), 'author' => array('mode' => PARTIAL_VOLATILE, 'selector' => 'p.author', 'cb' => 'article_partial_author'), 'view_modes' => array('mode' => PARTIAL_VOLATILE, 'selector' => '#view_modes', 'cb' => 'article_partial_view_modes'), 'article_nav' => array('mode' => PARTIAL_VOLATILE, 'selector' => 'p.nav-tertiary', 'cb' => 'article_partial_article_nav'), 'status' => array('mode' => PARTIAL_VOLATILE, 'selector' => '#write-status', 'cb' => 'article_partial_status'), 'categories' => array('mode' => PARTIAL_STATIC, 'selector' => '#categories_group', 'cb' => 'article_partial_categories'), 'section' => array('mode' => PARTIAL_STATIC, 'selector' => 'p.section', 'cb' => 'article_partial_section'), 'comments' => array('mode' => PARTIAL_VOLATILE, 'selector' => '#write-comments', 'cb' => 'article_partial_comments'), 'posted' => array('mode' => PARTIAL_VOLATILE, 'selector' => '#write-timestamp', 'cb' => 'article_partial_posted'), 'expires' => array('mode' => PARTIAL_VOLATILE, 'selector' => '#write-expires', 'cb' => 'article_partial_expires')); // Add partials for custom fields (and their values which is redundant by // design, for plugins). global $cfs; foreach ($cfs as $k => $v) { $partials["custom_field_{$k}"] = array('mode' => PARTIAL_STATIC, 'selector' => "p.custom-field.custom-{$k}", 'cb' => 'article_partial_custom_field'); $partials["custom_{$k}"] = array('mode' => PARTIAL_STATIC, 'selector' => "#custom-{$k}", 'cb' => 'article_partial_value'); } extract(gpsa(array('view', 'from_view', 'step'))); // Newly-saved article. if (!empty($GLOBALS['ID'])) { $ID = $GLOBALS['ID']; $step = 'edit'; } else { $ID = gps('ID'); } // Switch to 'text' view upon page load and after article post. if (!$view || gps('save') || gps('publish')) { $view = 'text'; } if (!$step) { $step = "create"; } if ($step == "edit" && $view == "text" && !empty($ID) && $from_view != 'preview' && $from_view != 'html' && !$concurrent) { $pull = true; // It's an existing article - off we go to the database. $ID = assert_int($ID); $rs = safe_row("*, unix_timestamp(Posted) as sPosted,\n unix_timestamp(Expires) as sExpires,\n unix_timestamp(LastMod) as sLastMod", "textpattern", "ID={$ID}"); if (empty($rs)) { return; } $rs['reset_time'] = $rs['publish_now'] = false; } else { $pull = false; // Assume they came from post. if ($from_view == 'preview' or $from_view == 'html') { $store_out = array(); $store = unserialize(base64_decode(ps('store'))); foreach ($vars as $var) { if (isset($store[$var])) { $store_out[$var] = $store[$var]; } } } else { $store_out = gpsa($vars); if ($concurrent) { $store_out['sLastMod'] = safe_field('unix_timestamp(LastMod) as sLastMod', 'textpattern', 'ID=' . $ID); } } // Use preferred Textfilter as default and fallback. $hasfilter = new Textpattern_Textfilter_Constraint(null); $validator = new Validator(); foreach (array('textile_body', 'textile_excerpt') as $k) { $hasfilter->setValue($store_out[$k]); $validator->setConstraints($hasfilter); if (!$validator->validate()) { $store_out[$k] = $use_textile; } } $rs = textile_main_fields($store_out); if (!empty($rs['exp_year'])) { if (empty($rs['exp_month'])) { $rs['exp_month'] = 1; } if (empty($rs['exp_day'])) { $rs['exp_day'] = 1; } if (empty($rs['exp_hour'])) { $rs['exp_hour'] = 0; } if (empty($rs['exp_minute'])) { $rs['exp_minute'] = 0; } if (empty($rs['exp_second'])) { $rs['exp_second'] = 0; } $rs['sExpires'] = safe_strtotime($rs['exp_year'] . '-' . $rs['exp_month'] . '-' . $rs['exp_day'] . ' ' . $rs['exp_hour'] . ':' . $rs['exp_minute'] . ':' . $rs['exp_second']); } if (!empty($rs['year'])) { $rs['sPosted'] = safe_strtotime($rs['year'] . '-' . $rs['month'] . '-' . $rs['day'] . ' ' . $rs['hour'] . ':' . $rs['minute'] . ':' . $rs['second']); } } $validator = new Validator(new SectionConstraint($rs['Section'])); if (!$validator->validate()) { $rs['Section'] = getDefaultSection(); } extract($rs); $GLOBALS['step'] = $step; if ($step != 'create' && isset($sPosted)) { // Previous record? $rs['prev_id'] = checkIfNeighbour('prev', $sPosted); // Next record? $rs['next_id'] = checkIfNeighbour('next', $sPosted); } else { $rs['prev_id'] = $rs['next_id'] = 0; } // Let plugins chime in on partials meta data. callback_event_ref('article_ui', 'partials_meta', 0, $rs, $partials); $rs['partials_meta'] =& $partials; // Get content for volatile partials. foreach ($partials as $k => $p) { if ($p['mode'] == PARTIAL_VOLATILE || $p['mode'] == PARTIAL_VOLATILE_VALUE) { $cb = $p['cb']; $partials[$k]['html'] = is_array($cb) ? call_user_func($cb, $rs, $k) : $cb($rs, $k); } } if ($refresh_partials) { $response[] = announce($message); $response[] = '$("#article_form [type=submit]").val(textpattern.gTxt("save"))'; if ($Status < STATUS_LIVE) { $response[] = '$("#article_form").addClass("saved").removeClass("published")'; } else { $response[] = '$("#article_form").addClass("published").removeClass("saved")'; } // Update the volatile partials. foreach ($partials as $k => $p) { // Volatile partials need a target DOM selector. if (empty($p['selector']) && $p['mode'] != PARTIAL_STATIC) { trigger_error("Empty selector for partial '{$k}'", E_USER_ERROR); } else { // Build response script. if ($p['mode'] == PARTIAL_VOLATILE) { // Volatile partials replace *all* of the existing HTML // fragment for their selector. $response[] = '$("' . $p['selector'] . '").replaceWith("' . escape_js($p['html']) . '")'; } elseif ($p['mode'] == PARTIAL_VOLATILE_VALUE) { // Volatile partial values replace the *value* of elements // matching their selector. $response[] = '$("' . $p['selector'] . '").val("' . escape_js($p['html']) . '")'; } } } send_script_response(join(";\n", $response)); // Bail out. return; } foreach ($partials as $k => $p) { if ($p['mode'] == PARTIAL_STATIC) { $cb = $p['cb']; $partials[$k]['html'] = is_array($cb) ? call_user_func($cb, $rs, $k) : $cb($rs, $k); } } $page_title = $ID ? $Title : gTxt('write'); pagetop($page_title, $message); $class = array(); if ($Status >= STATUS_LIVE) { $class[] = 'published'; } elseif ($ID) { $class[] = 'saved'; } if ($step !== 'create') { $class[] = 'async'; } echo hed(gTxt('tab_write'), 1, array('class' => 'txp-heading txp-accessibility')); echo n . tag_start('form', array('id' => 'article_form', 'name' => 'article_form', 'method' => 'post', 'action' => 'index.php', 'class' => $class)) . n . '<div id="' . $event . '_container" class="txp-layout-grid">'; if (!empty($store_out)) { echo hInput('store', base64_encode(serialize($store_out))); } echo hInput('ID', $ID) . eInput('article') . sInput($step) . hInput('sPosted', $sPosted) . hInput('sLastMod', $sLastMod) . hInput('AuthorID', $AuthorID) . hInput('LastModID', $LastModID) . n . '<input type="hidden" name="view" />'; echo n . '<div class="txp-layout-cell txp-layout-1-4">' . n . '<div id="configuration_content">'; if ($view == 'text') { // Markup help. echo $partials['sidehelp']['html']; // Custom menu entries. echo pluggable_ui('article_ui', 'extend_col_1', '', $rs); // Advanced. // Markup selection. $html_markup = pluggable_ui('article_ui', 'markup', graf('<label for="markup-body">' . gTxt('article_markup') . '</label>' . br . pref_text('textile_body', $textile_body, 'markup-body'), ' class="markup markup-body"') . graf('<label for="markup-excerpt">' . gTxt('excerpt_markup') . '</label>' . br . pref_text('textile_excerpt', $textile_excerpt, 'markup-excerpt'), ' class="markup markup-excerpt"'), $rs); // Form override. $form_pop = $allow_form_override ? form_pop($override_form, 'override-form') : ''; $html_override = $form_pop ? pluggable_ui('article_ui', 'override', graf('<label for="override-form">' . gTxt('override_default_form') . '</label>' . popHelp('override_form') . br . $form_pop, ' class="override-form"'), $rs) : ''; echo wrapRegion('advanced_group', $html_markup . $html_override, 'advanced', 'advanced_options', 'article_advanced'); // Meta info. // keywords. $html_keywords = $partials['keywords']['html']; // description. $html_description = $partials['description']['html']; // URL title. $html_url_title = $partials['url_title']['html']; echo wrapRegion('meta_group', $html_url_title . $html_description . $html_keywords, 'meta', 'meta', 'article_meta'); // Article image. echo $partials['image']['html']; // Custom fields. echo $partials['custom_fields']['html']; // Recent articles. echo wrapRegion('recent_group', $partials['recent_articles']['html'], 'recent', 'recent_articles', 'article_recent'); } else { echo sp; } echo n . '</div>' . n . '</div>'; // End of .txp-layout-cell. echo n . '<div class="txp-layout-cell txp-layout-2-4">' . n . '<div role="region" id="main_content">'; // View mode tabs. echo $partials['view_modes']['html']; // Title input. if ($view == 'preview') { echo n . '<div class="preview">' . hed(gTxt('preview'), 2) . hed($Title, 1, ' class="title"'); } elseif ($view == 'html') { echo n . '<div class="html">' . hed('HTML', 2) . hed($Title, 1, ' class="title"'); } elseif ($view == 'text') { echo n . '<div class="text">' . $partials['title']['html']; } // Body. if ($view == 'preview') { echo n . '<div class="body">' . $Body_html . '</div>'; } elseif ($view == 'html') { echo tag(str_replace(array(n, t), array(br, sp . sp . sp . sp), txpspecialchars($Body_html)), 'code', ' class="body"'); } else { echo $partials['body']['html']; } // Excerpt. if ($articles_use_excerpts) { if ($view == 'preview') { echo n . '<hr />' . n . '<div class="excerpt">' . $Excerpt_html . '</div>'; } elseif ($view == 'html') { echo n . '<hr />' . tag(str_replace(array(n, t), array(br, sp . sp . sp . sp), txpspecialchars($Excerpt_html)), 'code', array('class' => 'excerpt')); } else { echo $partials['excerpt']['html']; } } // Author. if ($view == "text" && $step != "create") { echo $partials['author']['html']; } echo hInput('from_view', $view), n . '</div>'; echo n . '</div>' . n . '</div>'; // End of .txp-layout-cell. echo n . '<div class="txp-layout-cell txp-layout-1-4">' . n . '<div id="supporting_content">'; if ($view == 'text') { // Publish and Save buttons. if ($step == 'create' and empty($GLOBALS['ID'])) { if (has_privs('article.publish')) { $push_button = fInput('submit', 'publish', gTxt('publish'), 'publish'); } else { $push_button = fInput('submit', 'publish', gTxt('save'), 'publish'); } echo graf($push_button, array('id' => 'write-publish')); } elseif ($Status >= STATUS_LIVE && has_privs('article.edit.published') || $Status >= STATUS_LIVE && $AuthorID === $txp_user && has_privs('article.edit.own.published') || $Status < STATUS_LIVE && has_privs('article.edit') || $Status < STATUS_LIVE && $AuthorID === $txp_user && has_privs('article.edit.own')) { echo graf(fInput('submit', 'save', gTxt('save'), 'publish'), array('id' => 'write-save')); } if ($step != 'create') { echo graf(href(gTxt('create_new'), 'index.php?event=article'), ' class="action-create"'); } // Prev/next article links. if ($step != 'create' and ($rs['prev_id'] or $rs['next_id'])) { echo $partials['article_nav']['html']; } // Sort and display. echo pluggable_ui('article_ui', 'sort_display', wrapRegion('write-sort', $partials['status']['html'] . $partials['section']['html'] . $partials['categories']['html'], '', gTxt('sort_display')), $rs); // "Comments" section. echo wrapRegion('comments_group', $partials['comments']['html'], 'comments', 'comment_settings', 'article_comments', $use_comments == 1 ? '' : 'empty'); // "Dates" section. if ($step == "create" and empty($GLOBALS['ID'])) { // Timestamp. // Avoiding modified date to disappear. if (!empty($store_out['year'])) { $persist_timestamp = safe_strtotime($store_out['year'] . '-' . $store_out['month'] . '-' . $store_out['day'] . ' ' . $store_out['hour'] . ':' . $store_out['minute'] . ':' . $store_out['second']); } else { $persist_timestamp = time(); } $posted_block = pluggable_ui('article_ui', 'timestamp', wrapRegion('write-timestamp', graf(checkbox('publish_now', '1', $publish_now, '', 'publish_now') . n . '<label for="publish_now">' . gTxt('set_to_now') . '</label>', ' class="publish-now"') . graf(gTxt('or_publish_at') . popHelp('timestamp'), ' class="publish-at"') . graf(span(gTxt('date'), array('class' => 'txp-label-fixed')) . br . tsi('year', '%Y', $persist_timestamp, '') . ' / ' . tsi('month', '%m', $persist_timestamp, '') . ' / ' . tsi('day', '%d', $persist_timestamp, ''), ' class="date posted created"') . graf(span(gTxt('time'), array('class' => 'txp-label-fixed')) . br . tsi('hour', '%H', $persist_timestamp, '') . ' : ' . tsi('minute', '%M', $persist_timestamp, '') . ' : ' . tsi('second', '%S', $persist_timestamp, ''), ' class="time posted created"'), '', gTxt('timestamp')), array('sPosted' => $persist_timestamp) + $rs); // Expires. if (!empty($store_out['exp_year'])) { $persist_timestamp = safe_strtotime($store_out['exp_year'] . '-' . $store_out['exp_month'] . '-' . $store_out['exp_day'] . ' ' . $store_out['exp_hour'] . ':' . $store_out['exp_minute'] . ':' . $store_out['second']); } else { $persist_timestamp = 0; } $expires_block = pluggable_ui('article_ui', 'expires', wrapRegion('write-expires', graf(span(gTxt('date'), array('class' => 'txp-label-fixed')) . br . tsi('exp_year', '%Y', $persist_timestamp, '') . ' / ' . tsi('exp_month', '%m', $persist_timestamp, '') . ' / ' . tsi('exp_day', '%d', $persist_timestamp, ''), ' class="date expires"') . graf(span(gTxt('time'), array('class' => 'txp-label-fixed')) . br . tsi('exp_hour', '%H', $persist_timestamp, '') . ' : ' . tsi('exp_minute', '%M', $persist_timestamp, '') . ' : ' . tsi('exp_second', '%S', $persist_timestamp, ''), ' class="time expires"'), '', gTxt('expires')), $rs); } else { // Timestamp. $posted_block = $partials['posted']['html']; // Expires. $expires_block = $partials['expires']['html']; } echo wrapRegion('dates_group', $posted_block . $expires_block, 'dates', 'date_settings', 'article_dates'); } echo n . '</div>' . n . '</div>' . n . '</div>' . tInput() . n . '</form>'; }
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>'; } }
function image_list($message = '') { global $txpcfg, $extensions, $img_dir, $file_max_upload_size, $image_list_pageby, $txp_user, $event; pagetop(gTxt('tab_image'), $message); extract($txpcfg); extract(gpsa(array('page', 'sort', 'dir', 'crit', 'search_method'))); if ($sort === '') { $sort = get_pref('image_sort_column', 'id'); } if ($dir === '') { $dir = get_pref('image_sort_dir', 'desc'); } $dir = $dir == 'asc' ? 'asc' : 'desc'; echo '<h1 class="txp-heading">' . gTxt('tab_image') . '</h1>'; echo '<div id="' . $event . '_control" class="txp-control-panel">'; if (!is_dir(IMPATH) or !is_writeable(IMPATH)) { echo graf(gTxt('img_dir_not_writeable', array('{imgdir}' => IMPATH)), ' class="alert-block warning"'); } elseif (has_privs('image.edit.own')) { echo upload_form(gTxt('upload_image'), 'upload_image', 'image_insert', 'image', '', $file_max_upload_size); } switch ($sort) { case 'name': $sort_sql = 'name ' . $dir; break; case 'thumbnail': $sort_sql = 'thumbnail ' . $dir . ', id asc'; break; case 'category': $sort_sql = 'category ' . $dir . ', id asc'; break; case 'date': $sort_sql = 'date ' . $dir . ', id asc'; break; case 'author': $sort_sql = 'author ' . $dir . ', id asc'; break; default: $sort = 'id'; $sort_sql = 'id ' . $dir; break; } set_pref('image_sort_column', $sort, 'image', 2, '', 0, PREF_PRIVATE); set_pref('image_sort_dir', $dir, 'image', 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)) . "')", 'name' => "name = '{$crit_escaped}'", 'category' => "category = '{$crit_escaped}'", 'author' => "author = '{$crit_escaped}'", 'alt' => "alt = '{$crit_escaped}'", 'caption' => "caption = '{$crit_escaped}'") : array('id' => "ID in ('" . join("','", do_list($crit_escaped)) . "')", 'name' => "name like '%{$crit_escaped}%'", 'category' => "category like '%{$crit_escaped}%'", 'author' => "author like '%{$crit_escaped}%'", 'alt' => "alt like '%{$crit_escaped}%'", 'caption' => "caption 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', 'image_list', 0, $criteria); $total = safe_count('txp_image', "{$criteria}"); if ($total < 1) { if ($criteria != 1) { echo n . image_search_form($crit, $search_method) . n . graf(gTxt('no_results_found'), ' class="indicator"') . '</div>'; } else { echo n . graf(gTxt('no_images_recorded'), ' class="indicator"') . '</div>'; } return; } $limit = max($image_list_pageby, 15); list($page, $offset, $numPages) = pager($total, $limit, $page); echo image_search_form($crit, $search_method); $rs = safe_rows_start('*, unix_timestamp(date) as uDate', 'txp_image', "{$criteria} order by {$sort_sql} limit {$offset}, {$limit}\n\t\t"); echo pluggable_ui('image_ui', 'extend_controls', '', $rs); echo '</div>'; // end txp-control-panel if ($rs) { $show_authors = !has_single_author('txp_image'); echo n . '<div id="' . $event . '_container" class="txp-container">'; echo n . n . '<form name="longform" id="images_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', 'image', true, $switch_dir, $crit, $search_method, ('id' == $sort ? "{$dir} " : '') . 'id') . n . column_head('name', 'name', 'image', true, $switch_dir, $crit, $search_method, ('name' == $sort ? "{$dir} " : '') . 'name') . n . column_head('date', 'date', 'image', true, $switch_dir, $crit, $search_method, ('date' == $sort ? "{$dir} " : '') . 'images_detail date created') . n . column_head('thumbnail', 'thumbnail', 'image', true, $switch_dir, $crit, $search_method, ('thumbnail' == $sort ? "{$dir} " : '') . 'thumbnail') . n . hCell(gTxt('tags'), '', ' class="images_detail tag-build"') . n . column_head('image_category', 'category', 'image', true, $switch_dir, $crit, $search_method, ('category' == $sort ? "{$dir} " : '') . 'category') . ($show_authors ? n . column_head('author', 'author', 'image', true, $switch_dir, $crit, $search_method, ('author' == $sort ? "{$dir} " : '') . 'author') : '')) . n . '</thead>'; echo '<tbody>'; $validator = new Validator(); while ($a = nextRow($rs)) { extract($a); $edit_url = '?event=image' . a . 'step=image_edit' . a . 'id=' . $id . a . 'sort=' . $sort . a . 'dir=' . $dir . a . 'page=' . $page . a . 'search_method=' . $search_method . a . 'crit=' . $crit; $name = empty($name) ? gTxt('unnamed') : txpspecialchars($name); if ($thumbnail) { if ($ext != '.swf') { $thumbnail = '<img class="content-image" src="' . imagesrcurl($id, $ext, true) . "?{$uDate}" . '" alt="" ' . "title='{$id}{$ext} ({$w} × {$h})'" . ($thumb_w ? " width='{$thumb_w}' height='{$thumb_h}'" : '') . ' />'; } else { $thumbnail = ''; } } else { $thumbnail = gTxt('no'); } if ($ext != '.swf') { $tag_url = '?event=tag' . a . 'tag_name=image' . a . 'id=' . $id . a . 'ext=' . $ext . a . 'w=' . $w . a . 'h=' . $h . a . 'alt=' . urlencode($alt) . a . 'caption=' . urlencode($caption); $tagbuilder = '<a target="_blank" href="' . $tag_url . a . 'type=textile" onclick="popWin(this.href); return false;">Textile</a>' . sp . '|' . sp . '<a target="_blank" href="' . $tag_url . a . 'type=textpattern" onclick="popWin(this.href); return false;">Textpattern</a>' . sp . '|' . sp . '<a target="_blank" href="' . $tag_url . a . 'type=html" onclick="popWin(this.href); return false;">HTML</a>'; } else { $tagbuilder = sp; } $validator->setConstraints(array(new CategoryConstraint($category, array('type' => 'image')))); $vc = $validator->validate() ? '' : ' error'; $category = $category ? '<span title="' . txpspecialchars(fetch_category_title($category, 'image')) . '">' . $category . '</span>' : ''; $can_edit = has_privs('image.edit') || $author == $txp_user && has_privs('image.edit.own'); echo n . n . tr(n . td($can_edit ? fInput('checkbox', 'selected[]', $id) : ' ', '', 'multi-edit') . n . td(($can_edit ? href($id, $edit_url, ' title="' . gTxt('edit') . '"') : $id) . sp . '<span class="images_detail">[<a href="' . imagesrcurl($id, $ext) . '">' . gTxt('view') . '</a>]</span>', '', 'id') . td($can_edit ? href($name, $edit_url, ' title="' . gTxt('edit') . '"') : $name, '', 'name') . td(gTime($uDate), '', 'images_detail date created') . td(pluggable_ui('image_ui', 'thumbnail', $can_edit ? href($thumbnail, $edit_url) : $thumbnail, $a), '', 'thumbnail') . td($tagbuilder, '', 'images_detail tag-build') . td($category, '', 'category' . $vc) . ($show_authors ? td('<span title="' . txpspecialchars(get_author_name($author)) . '">' . txpspecialchars($author) . '</span>', '', 'author') : '')); } echo '</tbody>', n, endTable(), n, '</div>', n, image_multiedit_form($page, $sort, $dir, $crit, $search_method), n, tInput(), n, '</form>', n, graf(toggle_box('images_detail'), ' class="detail-toggle"'), n, '<div id="' . $event . '_navigation" class="txp-navigation">', n, nav_form('image', $page, $numPages, $sort, $dir, $crit, $search_method, $total, $limit), n, pageby_form('image', $image_list_pageby), n, '</div>', n, '</div>'; } }
function file_list($message = '') { global $file_base_path, $file_statuses, $file_list_pageby, $txp_user, $event; pagetop(gTxt('tab_file'), $message); extract(gpsa(array('page', 'sort', 'dir', 'crit', 'search_method'))); if ($sort === '') { $sort = get_pref('file_sort_column', 'filename'); } if ($dir === '') { $dir = get_pref('file_sort_dir', 'asc'); } $dir = $dir == 'desc' ? 'desc' : 'asc'; echo '<h1 class="txp-heading">' . gTxt('tab_file') . '</h1>'; echo '<div id="' . $event . '_control" class="txp-control-panel">'; if (!is_dir($file_base_path) or !is_writeable($file_base_path)) { echo graf(gTxt('file_dir_not_writeable', array('{filedir}' => $file_base_path)), ' class="alert-block warning"'); } elseif (has_privs('file.edit.own')) { $existing_files = get_filenames(); if (count($existing_files) > 0) { echo form(eInput('file') . sInput('file_create') . graf('<label for="file-existing">' . gTxt('existing_file') . '</label>' . sp . selectInput('filename', $existing_files, '', 1, '', 'file-existing') . sp . fInput('submit', '', gTxt('Create')), ' class="existing-file"'), '', '', 'post', '', '', 'assign_file'); } echo file_upload_form(gTxt('upload_file'), 'upload', 'file_insert'); } switch ($sort) { case 'id': $sort_sql = 'id ' . $dir; break; case 'description': $sort_sql = 'description ' . $dir . ', filename desc'; break; case 'category': $sort_sql = 'category ' . $dir . ', filename desc'; break; case 'title': $sort_sql = 'title ' . $dir . ', filename desc'; break; case 'downloads': $sort_sql = 'downloads ' . $dir . ', filename desc'; break; case 'author': $sort_sql = 'author ' . $dir . ', id asc'; break; default: $sort = 'filename'; $sort_sql = 'filename ' . $dir; break; } set_pref('file_sort_column', $sort, 'file', PREF_HIDDEN, '', 0, PREF_PRIVATE); set_pref('file_sort_dir', $dir, 'file', PREF_HIDDEN, '', 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)) . "')", 'filename' => "filename = '{$crit_escaped}'", 'title' => "title = '{$crit_escaped}'", 'description' => "description = '{$crit_escaped}'", 'category' => "category = '{$crit_escaped}'", 'author' => "author = '{$crit_escaped}'") : array('id' => "ID in ('" . join("','", do_list($crit_escaped)) . "')", 'filename' => "filename like '%{$crit_escaped}%'", 'title' => "title like '%{$crit_escaped}%'", 'description' => "description like '%{$crit_escaped}%'", 'category' => "category like '%{$crit_escaped}%'", 'author' => "author 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', 'file_list', 0, $criteria); $total = safe_count('txp_file', "{$criteria}"); if ($total < 1) { if ($criteria != 1) { echo n . file_search_form($crit, $search_method) . n . graf(gTxt('no_results_found'), ' class="indicator"') . '</div>'; } else { echo n . graf(gTxt('no_files_recorded'), ' class="indicator"') . '</div>'; } return; } $limit = max($file_list_pageby, 15); list($page, $offset, $numPages) = pager($total, $limit, $page); echo file_search_form($crit, $search_method) . '</div>'; $rs = safe_rows_start('*', 'txp_file', "{$criteria} order by {$sort_sql} limit {$offset}, {$limit}"); if ($rs) { $show_authors = !has_single_author('txp_file'); echo n . '<div id="' . $event . '_container" class="txp-container">'; echo '<form name="longform" id="files_form" class="multi_edit_form" method="post" action="index.php">' . n . '<div class="txp-listtables">' . n . startTable('', '', 'txp-list') . n . '<thead>' . tr(n . hCell(fInput('checkbox', 'select_all', 0, '', '', '', '', '', 'select_all'), '', ' title="' . gTxt('toggle_all_selected') . '" class="multi-edit"') . n . column_head('ID', 'id', 'file', true, $switch_dir, $crit, $search_method, ('id' == $sort ? "{$dir} " : '') . 'id') . n . column_head('file_name', 'filename', 'file', true, $switch_dir, $crit, $search_method, ('filename' == $sort ? "{$dir} " : '') . 'name') . n . column_head('title', 'title', 'file', true, $switch_dir, $crit, $search_method, ('title' == $sort ? "{$dir} " : '') . 'title') . n . column_head('description', 'description', 'file', true, $switch_dir, $crit, $search_method, ('description' == $sort ? "{$dir} " : '') . 'files_detail description') . n . column_head('file_category', 'category', 'file', true, $switch_dir, $crit, $search_method, ('category' == $sort ? "{$dir} " : '') . 'category') . n . hCell(gTxt('tags'), '', ' class="files_detail tag-build"') . n . hCell(gTxt('status'), '', ' class="status"') . n . hCell(gTxt('condition'), '', ' class="condition"') . n . column_head('downloads', 'downloads', 'file', true, $switch_dir, $crit, $search_method, ('downloads' == $sort ? "{$dir} " : '') . 'downloads') . ($show_authors ? n . column_head('author', 'author', 'file', true, $switch_dir, $crit, $search_method, ('author' == $sort ? "{$dir} " : '') . 'author') : '')) . n . '</thead>'; echo '<tbody>'; $validator = new Validator(); while ($a = nextRow($rs)) { extract($a); $filename = sanitizeForFile($filename); $edit_url = '?event=file' . a . 'step=file_edit' . a . 'id=' . $id . a . 'sort=' . $sort . a . 'dir=' . $dir . a . 'page=' . $page . a . 'search_method=' . $search_method . a . 'crit=' . $crit; $file_exists = file_exists(build_file_path($file_base_path, $filename)); $download_link = $file_exists ? make_download_link($id, $downloads, $filename) : $downloads; $validator->setConstraints(array(new CategoryConstraint($category, array('type' => 'file')))); $vc = $validator->validate() ? '' : ' error'; $category = $category ? '<span title="' . txpspecialchars(fetch_category_title($category, 'file')) . '">' . $category . '</span>' : ''; $tag_url = '?event=tag' . a . 'tag_name=file_download_link' . a . 'id=' . $id . a . 'description=' . urlencode($description) . a . 'filename=' . urlencode($filename); $condition = '<span class="'; $condition .= $file_exists ? 'success' : 'error'; $condition .= '">'; $condition .= $file_exists ? gTxt('file_status_ok') : gTxt('file_status_missing'); $condition .= '</span>'; $can_edit = has_privs('file.edit') || $author == $txp_user && has_privs('file.edit.own'); echo tr(n . td($can_edit ? fInput('checkbox', 'selected[]', $id) : ' ', '', 'multi-edit') . n . td(($can_edit ? href($id, $edit_url, ' title="' . gTxt('edit') . '"') : $id) . ($file_exists ? sp . '<span class="files_detail">[' . make_download_link($id, gTxt('download'), $filename) . ']</span>' : ''), '', 'id') . td($can_edit ? href(txpspecialchars($filename), $edit_url, ' title="' . gTxt('edit') . '"') : txpspecialchars($filename), '', 'name') . td(txpspecialchars($title), '', 'title') . td(txpspecialchars($description), '', 'files_detail description') . td($category, '', 'category' . $vc) . td(n . '<a target="_blank" href="' . $tag_url . a . 'type=textile" onclick="popWin(this.href, 400, 250); return false;">Textile</a>' . sp . '|' . sp . '<a target="_blank" href="' . $tag_url . a . 'type=textpattern" onclick="popWin(this.href, 400, 250); return false;">Textpattern</a>' . sp . '|' . sp . '<a target="_blank" href="' . $tag_url . a . 'type=html" onclick="popWin(this.href, 400, 250); return false;">HTML</a>', '', 'files_detail tag-build') . td(in_array($status, array_keys($file_statuses)) ? $file_statuses[$status] : '<span class="error">' . gTxt('none') . '</span>', '', 'status') . td($condition, '', 'condition') . td($download_link, '', 'downloads') . ($show_authors ? td('<span title="' . txpspecialchars(get_author_name($author)) . '">' . txpspecialchars($author) . '</span>', '', 'author') : '')); } echo '</tbody>', n, endTable(), n, '</div>', n, file_multiedit_form($page, $sort, $dir, $crit, $search_method), n, tInput(), n, '</form>', n, graf(toggle_box('files_detail'), ' class="detail-toggle"'), n, '<div id="' . $event . '_navigation" class="txp-navigation">', n, nav_form('file', $page, $numPages, $sort, $dir, $crit, $search_method, $total, $limit), n, pageby_form('file', $file_list_pageby), n, '</div>', n, '</div>'; } }
function link_list($message = '') { global $event, $step, $link_list_pageby, $txp_user; pagetop(gTxt('tab_link'), $message); extract(gpsa(array('page', 'sort', 'dir', 'crit', 'search_method'))); if ($sort === '') { $sort = get_pref('link_sort_column', 'name'); } if ($dir === '') { $dir = get_pref('link_sort_dir', 'asc'); } $dir = $dir == 'desc' ? 'desc' : 'asc'; switch ($sort) { case 'id': $sort_sql = 'id ' . $dir; break; case 'description': $sort_sql = 'description ' . $dir . ', id asc'; break; case 'url': $sort_sql = 'url ' . $dir . ', id asc'; break; case 'category': $sort_sql = 'category ' . $dir . ', id asc'; break; case 'date': $sort_sql = 'date ' . $dir . ', id asc'; break; case 'author': $sort_sql = 'author ' . $dir . ', id asc'; break; default: $sort = 'name'; $sort_sql = 'linksort ' . $dir . ', id asc'; break; } set_pref('link_sort_column', $sort, 'link', 2, '', 0, PREF_PRIVATE); set_pref('link_sort_dir', $dir, 'link', 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' => "ID in ('" . join("','", do_list($crit_escaped)) . "')", 'name' => "linkname = '{$crit_escaped}'", 'description' => "description = '{$crit_escaped}'", 'url' => "url = '{$crit_escaped}'", 'category' => "category = '{$crit_escaped}'", 'author' => "author = '{$crit_escaped}'") : array('id' => "ID in ('" . join("','", do_list($crit_escaped)) . "')", 'name' => "linkname like '%{$crit_escaped}%'", 'description' => "description like '%{$crit_escaped}%'", 'url' => "url like '%{$crit_escaped}%'", 'category' => "category like '%{$crit_escaped}%'", 'author' => "author like '%{$crit_escaped}%'"); if (array_key_exists($search_method, $critsql)) { $criteria = $critsql[$search_method]; } else { $search_method = ''; $crit = ''; } } else { $search_method = ''; $crit = ''; } $criteria .= callback_event('admin_criteria', 'link_list', 0, $criteria); $total = getCount('txp_link', $criteria); echo hed(gTxt('tab_link'), 1, array('class' => 'txp-heading')); echo n . '<div id="' . $event . '_control" class="txp-control-panel">'; if (has_privs('link.edit')) { echo graf(sLink('link', 'link_edit', gTxt('add_new_link')), ' class="txp-buttons"'); } if ($total < 1) { if ($criteria != 1) { echo link_search_form($crit, $search_method) . graf(gTxt('no_results_found'), ' class="indicator"') . '</div>'; } else { echo graf(gTxt('no_links_recorded'), ' class="indicator"') . '</div>'; } return; } $limit = max($link_list_pageby, 15); list($page, $offset, $numPages) = pager($total, $limit, $page); echo link_search_form($crit, $search_method) . '</div>'; $rs = safe_rows_start('*, unix_timestamp(date) as uDate', 'txp_link', "{$criteria} order by {$sort_sql} limit {$offset}, {$limit}"); if ($rs) { $show_authors = !has_single_author('txp_link'); echo n . tag_start('div', array('id' => $event . '_container', 'class' => 'txp-container')) . n . tag_start('form', array('action' => 'index.php', 'id' => 'links_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', 'link', true, $switch_dir, $crit, $search_method, ('id' == $sort ? "{$dir} " : '') . 'txp-list-col-id') . column_head('link_name', 'name', 'link', true, $switch_dir, $crit, $search_method, ('name' == $sort ? "{$dir} " : '') . 'txp-list-col-name') . column_head('description', 'description', 'link', true, $switch_dir, $crit, $search_method, ('description' == $sort ? "{$dir} " : '') . 'txp-list-col-description links_detail') . column_head('link_category', 'category', 'link', true, $switch_dir, $crit, $search_method, ('category' == $sort ? "{$dir} " : '') . 'txp-list-col-category category') . column_head('url', 'url', 'link', true, $switch_dir, $crit, $search_method, ('url' == $sort ? "{$dir} " : '') . 'txp-list-col-url') . column_head('date', 'date', 'link', true, $switch_dir, $crit, $search_method, ('date' == $sort ? "{$dir} " : '') . 'txp-list-col-created date links_detail') . ($show_authors ? column_head('author', 'author', 'link', true, $switch_dir, $crit, $search_method, ('author' == $sort ? "{$dir} " : '') . 'txp-list-col-author name') : '')) . n . tag_end('thead') . n . tag_start('tbody'); $validator = new Validator(); while ($a = nextRow($rs)) { extract($a, EXTR_PREFIX_ALL, 'link'); $edit_url = array('event' => 'link', 'step' => 'link_edit', 'id' => $link_id, 'sort' => $sort, 'dir' => $dir, 'page' => $page, 'search_method' => $search_method, 'crit' => $crit); $validator->setConstraints(array(new CategoryConstraint($link_category, array('type' => 'link')))); $vc = $validator->validate() ? '' : ' error'; $can_edit = has_privs('link.edit') || $link_author === $txp_user && has_privs('link.edit.own'); $view_url = txpspecialchars($link_url); echo tr(td(fInput('checkbox', 'selected[]', $link_id), '', 'txp-list-col-multi-edit') . hCell($can_edit ? href($link_id, $edit_url, ' title="' . gTxt('edit') . '"') : $link_id, '', ' scope="row" class="txp-list-col-id"') . td($can_edit ? href(txpspecialchars($link_linkname), $edit_url, ' title="' . gTxt('edit') . '"') : txpspecialchars($link_linkname), '', 'txp-list-col-name') . td(txpspecialchars($link_description), '', 'txp-list-col-description links_detail') . td(span($link_category, array('title' => fetch_category_title($link_category, 'link'))), '', 'txp-list-col-category category' . $vc) . td(href($view_url, $view_url, ' rel="external" target="_blank"'), '', 'txp-list-col-url') . td(gTime($link_uDate), '', 'txp-list-col-created date links_detail') . ($show_authors ? td(span(txpspecialchars($link_author), array('title' => get_author_name($link_author))), '', 'txp-list-col-author name') : '')); } echo n . tag_end('tbody') . n . tag_end('table') . n . tag_end('div') . link_multiedit_form($page, $sort, $dir, $crit, $search_method) . tInput() . n . tag_end('form') . graf(toggle_box('links_detail'), array('class' => 'detail-toggle')) . n . tag_start('div', array('id' => $event . '_navigation', 'class' => 'txp-navigation')) . pageby_form('link', $link_list_pageby) . nav_form('link', $page, $numPages, $sort, $dir, $crit, $search_method, $total, $limit) . n . tag_end('div') . n . tag_end('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'); } }