PupperWoff
7 years ago
committed by
discomrade
12 changed files with 721 additions and 0 deletions
@ -0,0 +1,85 @@ |
|||||
|
<?php |
||||
|
|
||||
|
|
||||
|
|
||||
|
// require 'inc/config.php'; |
||||
|
// require 'inc/config_instance.php'; |
||||
|
require 'inc/functions.php'; |
||||
|
|
||||
|
|
||||
|
global $config; |
||||
|
|
||||
|
// Check so only ADMIN can run script |
||||
|
check_login(true); |
||||
|
if (!$mod || $mod['type'] != ADMIN) |
||||
|
die("You need to be logged in as admin"); |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
$page['title'] = 'Updating Database - Archiving of Threads'; |
||||
|
|
||||
|
|
||||
|
$step = isset($_GET['step']) ? round($_GET['step']) : 0; |
||||
|
|
||||
|
switch($step) |
||||
|
{ |
||||
|
default: |
||||
|
case 0: |
||||
|
$page['body'] = '<p style="text-align:center">You are about to update the database to allow archiving of threads.</p>'; |
||||
|
$page['body'] .= '<p style="text-align:center"><a href="?step=2">Click here to update database entries.</a></p>'; |
||||
|
break; |
||||
|
case 2: |
||||
|
$page['body'] = '<p style="text-align:center">Database have been updated.</p>'; |
||||
|
|
||||
|
$sql_errors = ""; |
||||
|
|
||||
|
// Update posts_* table to archive function |
||||
|
// Get list of boards |
||||
|
$boards = listBoards(); |
||||
|
foreach ($boards as &$_board) { |
||||
|
$query = Element('archive.sql', array('board' => $_board['uri'])); |
||||
|
if (mysql_version() < 50503) |
||||
|
$query = preg_replace('/(CHARSET=|CHARACTER SET )utf8mb4/', '$1utf8', $query); |
||||
|
query($query) or error(db_error()); |
||||
|
|
||||
|
// Create Archive Folders |
||||
|
if (!file_exists($_board['dir'] . $config['dir']['archive'])) |
||||
|
@mkdir($_board['dir'] . $config['dir']['archive'], 0777) |
||||
|
or error("Couldn't create " . $_board['dir'] . $config['dir']['archive'] . ". Check permissions.", true); |
||||
|
if (!file_exists($_board['dir'] . $config['dir']['archive'] . $config['dir']['img'])) |
||||
|
@mkdir($_board['dir'] . $config['dir']['archive'] . $config['dir']['img'], 0777) |
||||
|
or error("Couldn't create " . $_board['dir'] . $config['dir']['archive'] . $config['dir']['img'] . ". Check permissions.", true); |
||||
|
if (!file_exists($_board['dir'] . $config['dir']['archive'] . $config['dir']['thumb'])) |
||||
|
@mkdir($_board['dir'] . $config['dir']['archive'] . $config['dir']['thumb'], 0777) |
||||
|
or error("Couldn't create " . $_board['dir'] . $config['dir']['archive'] . $config['dir']['img'] . ". Check permissions.", true); |
||||
|
if (!file_exists($_board['dir'] . $config['dir']['archive'] . $config['dir']['res'])) |
||||
|
@mkdir($_board['dir'] . $config['dir']['archive'] . $config['dir']['res'], 0777) |
||||
|
or error("Couldn't create " . $_board['dir'] . $config['dir']['archive'] . $config['dir']['img'] . ". Check permissions.", true); |
||||
|
// Create Featured threads Folders |
||||
|
if (!file_exists($_board['dir'] . $config['dir']['featured'])) |
||||
|
@mkdir($_board['dir'] . $config['dir']['featured'], 0777) |
||||
|
or error("Couldn't create " . $_board['dir'] . $config['dir']['featured'] . ". Check permissions.", true); |
||||
|
if (!file_exists($_board['dir'] . $config['dir']['featured'] . $config['dir']['img'])) |
||||
|
@mkdir($_board['dir'] . $config['dir']['featured'] . $config['dir']['img'], 0777) |
||||
|
or error("Couldn't create " . $_board['dir'] . $config['dir']['featured'] . $config['dir']['img'] . ". Check permissions.", true); |
||||
|
if (!file_exists($_board['dir'] . $config['dir']['featured'] . $config['dir']['thumb'])) |
||||
|
@mkdir($_board['dir'] . $config['dir']['featured'] . $config['dir']['thumb'], 0777) |
||||
|
or error("Couldn't create " . $_board['dir'] . $config['dir']['featured'] . $config['dir']['img'] . ". Check permissions.", true); |
||||
|
if (!file_exists($_board['dir'] . $config['dir']['featured'] . $config['dir']['res'])) |
||||
|
@mkdir($_board['dir'] . $config['dir']['featured'] . $config['dir']['res'], 0777) |
||||
|
or error("Couldn't create " . $_board['dir'] . $config['dir']['featured'] . $config['dir']['img'] . ". Check permissions.", true); |
||||
|
} |
||||
|
|
||||
|
if (!empty($sql_errors)) |
||||
|
$page['body'] .= '<div class="ban"><h2>SQL errors</h2><p>SQL errors were encountered when trying to update the database and hashing ip addresses.</p><p>The errors encountered were:</p><ul>' . $sql_errors . '</ul></div>'; |
||||
|
|
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
echo Element('page.html', $page); |
||||
|
|
||||
|
?> |
||||
|
<!-- There is probably a much better way to do this, but eh. --> |
||||
|
<link rel="stylesheet" type="text/css" href="stylesheets/style.css" /> |
@ -0,0 +1,291 @@ |
|||||
|
<?php |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
class Archive { |
||||
|
|
||||
|
|
||||
|
// Archive thread and replies |
||||
|
static public function archiveThread($thread_id) { |
||||
|
global $config, $board; |
||||
|
|
||||
|
// If archiving is turned off return |
||||
|
if(!$config['archive']['threads']) |
||||
|
return; |
||||
|
|
||||
|
// Check if it is a thread |
||||
|
$thread_query = prepare(sprintf("SELECT `thread`, `subject`, `body_nomarkup` FROM ``posts_%s`` WHERE `id` = :id", $board['uri'])); |
||||
|
$thread_query->bindValue(':id', $thread_id, PDO::PARAM_INT); |
||||
|
$thread_query->execute() or error(db_error($thread_query)); |
||||
|
$thread_data = $thread_query->fetch(PDO::FETCH_ASSOC); |
||||
|
|
||||
|
if($thread_data['thread'] !== NULL) |
||||
|
error($config['error']['invalidpost']); |
||||
|
|
||||
|
// Create Snippet of thread text |
||||
|
$thread_data['snippet_body'] = strtok($thread_data['body_nomarkup'], "\r\n"); |
||||
|
$thread_data['snippet_body'] = substr($thread_data['snippet_body'], 0, $config['archive']['snippet_len'] - strlen($thread_data['subject'])); |
||||
|
archive_list_markup($thread_data['snippet_body']); |
||||
|
$thread_data['snippet'] = '<b>' . $thread_data['subject'] . '</b> '; |
||||
|
$thread_data['snippet'] .= $thread_data['snippet_body']; |
||||
|
|
||||
|
// Select thread and replies in one query |
||||
|
$query = prepare(sprintf("SELECT `id`,`thread`,`files`,`slug` FROM ``posts_%s`` WHERE `id` = :id OR `thread` = :id", $board['uri'])); |
||||
|
$query->bindValue(':id', $thread_id, PDO::PARAM_INT); |
||||
|
$query->execute() or error(db_error($query)); |
||||
|
|
||||
|
// List of files associated with thread |
||||
|
$file_list = array(); |
||||
|
|
||||
|
while ($post = $query->fetch(PDO::FETCH_ASSOC)) { |
||||
|
// Copy Static HTML page for Thread |
||||
|
if (!$post['thread']) { |
||||
|
// Read Content of HTML |
||||
|
$thread_file_content = @file_get_contents($board['dir'] . $config['dir']['res'] . link_for($post)); |
||||
|
|
||||
|
// Replace links and posting mode to Archived |
||||
|
$thread_file_content = str_replace(sprintf('src="/' . $config['board_path'], $board['uri']), sprintf('src="/' . $config['board_path'] . $config['dir']['archive'], $board['uri']), $thread_file_content); |
||||
|
$thread_file_content = str_replace(sprintf('href="/' . $config['board_path'], $board['uri']), sprintf('href="/' . $config['board_path'] . $config['dir']['archive'], $board['uri']), $thread_file_content); |
||||
|
$thread_file_content = str_replace('Posting mode: Reply', 'Archived thread', $thread_file_content); |
||||
|
// Remove Post Form from HTML (First Form) |
||||
|
$thread_file_content = preg_replace("/<form name=\"post\"(.*?)<\/form>/i", "", $thread_file_content); |
||||
|
|
||||
|
// Remove Form from HTML |
||||
|
$thread_file_content = preg_replace("/<form(.*?)>/i", "", $thread_file_content); |
||||
|
$thread_file_content = preg_replace("/<\/form>/i", "", $thread_file_content); |
||||
|
$thread_file_content = preg_replace("/<input (.*?)>/i", "", $thread_file_content); |
||||
|
|
||||
|
// Remove Redundant code from HTML |
||||
|
$thread_file_content = preg_replace("/<div id=\"report\-fields\"(.*?)<\/div>/i", "", $thread_file_content); |
||||
|
$thread_file_content = preg_replace("/<div id=\"thread\-interactions\"(.*?)<\/div>/i", "", $thread_file_content); |
||||
|
|
||||
|
// Write altered thread HTML to archive location |
||||
|
@file_put_contents($board['dir'] . $config['dir']['archive'] . $config['dir']['res'] . sprintf($config['file_page'], $thread_id), $thread_file_content, LOCK_EX); |
||||
|
} |
||||
|
|
||||
|
// Copy Images and Files Associated with Thread |
||||
|
if ($post['files']) { |
||||
|
foreach (json_decode($post['files']) as $i => $f) { |
||||
|
if ($f->file !== 'deleted') { |
||||
|
@copy($board['dir'] . $config['dir']['img'] . $f->file, $board['dir'] . $config['dir']['archive'] . $config['dir']['img'] . $f->file); |
||||
|
@copy($board['dir'] . $config['dir']['thumb'] . $f->thumb, $board['dir'] . $config['dir']['archive'] . $config['dir']['thumb'] . $f->thumb); |
||||
|
|
||||
|
$file_list[] = $f; |
||||
|
|
||||
|
// $file_list[$i]['file'] = $f->file; |
||||
|
// $file_list[$i]['thumb'] = $f->thumb; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Insert Archive Data in Database |
||||
|
$query = prepare(sprintf("INSERT INTO ``archive_%s`` VALUES (:thread_id, :snippet, :time, :files, 0)", $board['uri'])); |
||||
|
$query->bindValue(':thread_id', $thread_id, PDO::PARAM_INT); |
||||
|
$query->bindValue(':snippet', $thread_data['snippet'], PDO::PARAM_STR); |
||||
|
$query->bindValue(':time', (!$config['archive']['lifetime'])?0:strtotime("+".$config['archive']['lifetime']." days"), PDO::PARAM_INT); |
||||
|
$query->bindValue(':files', json_encode($file_list)); |
||||
|
$query->execute() or error(db_error($query)); |
||||
|
|
||||
|
|
||||
|
// Purge Threads that have timed out |
||||
|
self::purgeArchive(); |
||||
|
|
||||
|
// Rebuild Archive Index |
||||
|
self::buildArchiveIndex(); |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
// Removes Archived Threads that has outlived their lifetime |
||||
|
static public function purgeArchive() { |
||||
|
global $config, $board; |
||||
|
|
||||
|
// Delete all static pages and files for archived threads that has timed out |
||||
|
$query = query(sprintf("SELECT `id`, `files` FROM ``archive_%s`` WHERE `lifetime` < %d AND `featured` = 0", $board['uri'], time())) or error(db_error()); |
||||
|
while($thread = $query->fetch(PDO::FETCH_ASSOC)) { |
||||
|
// Delete Files |
||||
|
foreach (json_decode($thread['files']) as $f) { |
||||
|
@unlink($board['dir'] . $config['dir']['archive'] . $config['dir']['img'] . $f->file); |
||||
|
@unlink($board['dir'] . $config['dir']['archive'] . $config['dir']['img'] . $f->thumb); |
||||
|
} |
||||
|
|
||||
|
// Delete Thread |
||||
|
@unlink($board['dir'] . $config['dir']['archive'] . $config['dir']['res'] . sprintf($config['file_page'], $thread['id'])); |
||||
|
} |
||||
|
|
||||
|
// Delete Archive Entries |
||||
|
if($query->rowCount() != 0) |
||||
|
$query = query(sprintf("DELETE FROM ``archive_%s`` WHERE `lifetime` < %d AND `featured` = 0", $board['uri'], time())) or error(db_error()); |
||||
|
|
||||
|
return $query->rowCount(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
// Feature thread and replies |
||||
|
static public function featureThread($thread_id) { |
||||
|
global $config, $board; |
||||
|
|
||||
|
// If featuring of threads is turned off return |
||||
|
if(!$config['feature']['threads']) |
||||
|
return; |
||||
|
|
||||
|
$query = query(sprintf("SELECT `id`, `files` FROM ``archive_%s`` WHERE `featured` = 0", $board['uri'])) or error(db_error()); |
||||
|
if(!$thread = $query->fetch(PDO::FETCH_ASSOC)) |
||||
|
error($config['error']['invalidpost']); |
||||
|
|
||||
|
// Read Content of HTML |
||||
|
$thread_file_content = @file_get_contents($board['dir'] . $config['dir']['archive'] . $config['dir']['res'] . sprintf($config['file_page'], $thread_id)); |
||||
|
|
||||
|
// Replace links and posting mode to Archived |
||||
|
$thread_file_content = str_replace(sprintf('src="/' . $config['board_path'] . $config['dir']['archive'], $board['uri']), sprintf('src="/' . $config['board_path'] . $config['dir']['featured'], $board['uri']), $thread_file_content); |
||||
|
$thread_file_content = str_replace(sprintf('href="/' . $config['board_path'] . $config['dir']['archive'], $board['uri']), sprintf('href="/' . $config['board_path'] . $config['dir']['featured'], $board['uri']), $thread_file_content); |
||||
|
$thread_file_content = str_replace('Archived thread', 'Featured thread', $thread_file_content); |
||||
|
|
||||
|
// Write altered thread HTML to archive location |
||||
|
@file_put_contents($board['dir'] . $config['dir']['featured'] . $config['dir']['res'] . sprintf($config['file_page'], $thread_id), $thread_file_content, LOCK_EX); |
||||
|
|
||||
|
foreach (json_decode($thread['files']) as $f) { |
||||
|
@copy($board['dir'] . $config['dir']['archive'] . $config['dir']['img'] . $f->file, $board['dir'] . $config['dir']['featured'] . $config['dir']['img'] . $f->file); |
||||
|
@copy($board['dir'] . $config['dir']['archive'] . $config['dir']['thumb'] . $f->thumb, $board['dir'] . $config['dir']['featured'] . $config['dir']['thumb'] . $f->thumb); |
||||
|
} |
||||
|
|
||||
|
// Update DB entry |
||||
|
query(sprintf("UPDATE ``archive_%s`` SET `featured` = 1 WHERE `id` = %d", $board['uri'], (int)$thread_id)) or error(db_error()); |
||||
|
|
||||
|
// Rebuild Featured Index |
||||
|
self::buildFeaturedIndex(); |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
static public function deleteFeatured($thread_id) { |
||||
|
global $config, $board; |
||||
|
|
||||
|
$query = query(sprintf("SELECT `id`, `files`, `lifetime` FROM ``archive_%s`` WHERE `featured` = 1", $board['uri'])) or error(db_error()); |
||||
|
if(!$thread = $query->fetch(PDO::FETCH_ASSOC)) |
||||
|
error($config['error']['invalidpost']); |
||||
|
|
||||
|
|
||||
|
// Delete Files |
||||
|
foreach (json_decode($thread['files']) as $f) { |
||||
|
@unlink($board['dir'] . $config['dir']['featured'] . $config['dir']['img'] . $f->file); |
||||
|
@unlink($board['dir'] . $config['dir']['featured'] . $config['dir']['img'] . $f->thumb); |
||||
|
} |
||||
|
|
||||
|
// Delete Thread |
||||
|
@unlink($board['dir'] . $config['dir']['featured'] . $config['dir']['res'] . sprintf($config['file_page'], $thread_id)); |
||||
|
|
||||
|
// Delete Entry in DB if it has timed out |
||||
|
if($thread['lifetime'] != 0 && $thread['lifetime'] < time()) |
||||
|
query(sprintf("DELETE FROM ``archive_%s`` WHERE `id` = %d", $board['uri'], (int)$thread_id)) or error(db_error()); |
||||
|
else |
||||
|
query(sprintf("UPDATE ``archive_%s`` SET `featured` = 0 WHERE `id` = %d", $board['uri'], (int)$thread_id)) or error(db_error()); |
||||
|
|
||||
|
// Rebuild Featured Index |
||||
|
self::buildFeaturedIndex(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
static public function RebuildArchiveIndexes() { |
||||
|
global $config; |
||||
|
|
||||
|
// If archiving is turned off return |
||||
|
if(!$config['archive']['threads']) |
||||
|
return; |
||||
|
|
||||
|
// Purge Archive |
||||
|
self::purgeArchive(); |
||||
|
|
||||
|
// Rebuild Archive Index |
||||
|
self::buildArchiveIndex(); |
||||
|
|
||||
|
// Rebuild Featured Index |
||||
|
self::buildFeaturedIndex(); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
static public function buildArchiveIndex() { |
||||
|
global $config, $board; |
||||
|
|
||||
|
// If archiving is turned off return |
||||
|
if(!$config['archive']['threads']) |
||||
|
return; |
||||
|
|
||||
|
$query = query(sprintf("SELECT `id`, `snippet`, `featured` FROM ``archive_%s`` WHERE `lifetime` > %d ORDER BY `lifetime` DESC", $board['uri'], time())) or error(db_error()); |
||||
|
$archive = $query->fetchAll(PDO::FETCH_ASSOC); |
||||
|
|
||||
|
foreach($archive as &$thread) |
||||
|
$thread['archived_url'] = $config['dir']['res'] . sprintf($config['file_page'], $thread['id']); |
||||
|
|
||||
|
$title = sprintf(_('Archived') . ' %s: ' . $config['board_abbreviation'], _('threads'), $board['uri']); |
||||
|
$archive_page = Element('page.html', array( |
||||
|
'config' => $config, |
||||
|
'mod' => false, |
||||
|
'hide_dashboard_link' => true, |
||||
|
'boardlist' => createBoardList(false), |
||||
|
'title' => $title, |
||||
|
'subtitle' => "", |
||||
|
'boardlist' => createBoardlist(), |
||||
|
'body' => Element("mod/archive_list.html", array( |
||||
|
'config' => $config, |
||||
|
'thread_count' => $query->rowCount(), |
||||
|
'archive' => $archive |
||||
|
)) |
||||
|
)); |
||||
|
|
||||
|
file_write($config['dir']['home'] . $board['dir'] . $config['dir']['archive'] . $config['file_index'], $archive_page); |
||||
|
} |
||||
|
|
||||
|
static public function buildFeaturedIndex() { |
||||
|
global $config, $board; |
||||
|
|
||||
|
// If featuring of threads is turned off return |
||||
|
if(!$config['feature']['threads']) |
||||
|
return; |
||||
|
|
||||
|
$query = query(sprintf("SELECT `id`, `snippet`, `featured` FROM ``archive_%s`` WHERE `featured` = 1 ORDER BY `lifetime` DESC", $board['uri'])) or error(db_error()); |
||||
|
$archive = $query->fetchAll(PDO::FETCH_ASSOC); |
||||
|
|
||||
|
foreach($archive as &$thread) |
||||
|
$thread['featured_url'] = $config['dir']['res'] . sprintf($config['file_page'], $thread['id']); |
||||
|
|
||||
|
$title = sprintf(_('Featured') . ' %s: ' . $config['board_abbreviation'], _('threads'), $board['uri']); |
||||
|
$archive_page = Element('page.html', array( |
||||
|
'config' => $config, |
||||
|
'mod' => false, |
||||
|
'hide_dashboard_link' => true, |
||||
|
'boardlist' => createBoardList(false), |
||||
|
'title' => $title, |
||||
|
'subtitle' => "", |
||||
|
'boardlist' => createBoardlist(), |
||||
|
'body' => Element("mod/archive_featured_list.html", array( |
||||
|
'config' => $config, |
||||
|
'archive' => $archive |
||||
|
)) |
||||
|
)); |
||||
|
|
||||
|
file_write($config['dir']['home'] . $board['dir'] . $config['dir']['featured'] . $config['file_index'], $archive_page); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
?> |
@ -0,0 +1,10 @@ |
|||||
|
CREATE TABLE IF NOT EXISTS ``archive_{{ board }}`` ( |
||||
|
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, |
||||
|
`snippet` text NOT NULL, |
||||
|
`lifetime` int(11) NOT NULL, |
||||
|
`files` text NOT NULL, |
||||
|
`featured` int(1) NOT NULL, |
||||
|
UNIQUE KEY `id` (`id`), |
||||
|
KEY `lifetime` (`lifetime`) |
||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4; |
||||
|
|
@ -0,0 +1,37 @@ |
|||||
|
|
||||
|
|
||||
|
<table id="archive-list" class="archive-list modlog"> |
||||
|
<thead> |
||||
|
<tr> |
||||
|
<th width='80px'>Post #</th> |
||||
|
<th>Snippet</th> |
||||
|
<th width='50px'> </th> |
||||
|
{% if mod and mod|hasPermission(config.mod.delete_featured_archived_threads, board.uri) %} |
||||
|
<th width='80px'> </th> |
||||
|
{% endif %} |
||||
|
</tr> |
||||
|
</thead> |
||||
|
<tbody> |
||||
|
{% for thread in archive %} |
||||
|
<tr> |
||||
|
<td>{{ thread.id }}</td> |
||||
|
<td>{{ thread.snippet }}</td> |
||||
|
<td><a href="{{ thread.featured_url }}">[{% trans 'View' %}]</a></td> |
||||
|
{% if mod and mod|hasPermission(config.mod.delete_featured_archived_threads, board.uri) %} |
||||
|
<td> |
||||
|
<form action="" method="post" class="archiveForm"> |
||||
|
<input type="hidden" name="token" value="{{ token }}"> |
||||
|
<input type="hidden" name="id" value="{{ thread.id }}"> |
||||
|
<input type="hidden" name="delete" value="1"> |
||||
|
<a href="#" onclick="return confirm('Are you sure you want to permanently delete this thread from featured archive?')?this.parentNode.submit():false;">[{% trans 'Delete' %}]</a> |
||||
|
</form> |
||||
|
</td> |
||||
|
{% endif %} |
||||
|
</tr> |
||||
|
{% endfor %} |
||||
|
</tbody> |
||||
|
</table> |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
@ -0,0 +1,44 @@ |
|||||
|
|
||||
|
|
||||
|
<p style="text-align: center"> |
||||
|
<b>{% trans 'Displaying' %} {{ thread_count }} {% trans 'expired threads' %}{% if config.archive.lifetime %} {% trans 'from the past' %} {{ config.archive.lifetime }} {% trans 'days' %}{% endif %}</b> |
||||
|
</p> |
||||
|
|
||||
|
<table id="archive-list" class="archive-list modlog"> |
||||
|
<thead> |
||||
|
<tr> |
||||
|
<th width='80px'>Post #</th> |
||||
|
<th>Snippet</th> |
||||
|
<th width='50px'> </th> |
||||
|
{% if mod and mod|hasPermission(config.mod.feature_archived_threads, board.uri) %} |
||||
|
<th width='80px'> </th> |
||||
|
{% endif %} |
||||
|
</tr> |
||||
|
</thead> |
||||
|
<tbody> |
||||
|
{% for thread in archive %} |
||||
|
<tr> |
||||
|
<td>{{ thread.id }}</td> |
||||
|
<td>{{ thread.snippet }}</td> |
||||
|
<td><a href="{{ thread.archived_url }}">[{% trans 'View' %}]</a></td> |
||||
|
{% if mod and mod|hasPermission(config.mod.feature_archived_threads, board.uri) %} |
||||
|
<td> |
||||
|
{% if not thread.featured %} |
||||
|
<form action="" method="post" class="archiveForm"> |
||||
|
<input type="hidden" name="token" value="{{ token }}"> |
||||
|
<input type="hidden" name="id" value="{{ thread.id }}"> |
||||
|
<input type="hidden" name="feature" value="1"> |
||||
|
<a href="#" onclick="confirm('Are you sure you want to add thread to featured archive?')?this.parentNode.submit():false;">[{% trans 'Feature' %}]</a> |
||||
|
</form> |
||||
|
{% else %} |
||||
|
<b>{% trans 'Featured' %}</b> |
||||
|
{% endif %} |
||||
|
</td> |
||||
|
{% endif %} |
||||
|
</tr> |
||||
|
{% endfor %} |
||||
|
</tbody> |
||||
|
</table> |
||||
|
|
||||
|
|
||||
|
|
Loading…
Reference in new issue