prepare("UPDATE keys
SET type = 'disabled'
WHERE name = '$mod'");
$log_message = "Moderator account $mod was disabled";
} elseif ( (isset($_POST['enable_mod'])) ) {
$mod = strip_tags($_POST['enable_mod']);
$statement = $db->prepare("UPDATE keys
SET type = 'mod'
WHERE name = '$mod'");
$log_message = "Moderator account $mod was enabled";
} elseif ( (isset($_POST['delete_mod'])) ) {
$mod = strip_tags($_POST['delete_mod']);
$statement = $db->prepare("DELETE FROM keys
WHERE name = '$mod'");
$log_message = "Moderator account $mod was deleted";
}
$result = $statement->execute();
log_event($db, $settings, "sys", $log_message, '');
}
// Check if the password for the admin is set or not.
// If it was not done already, generate token and write to db and the
// file /var/opt/endboard/admin_$name_token.txt
function check_admin($db, $settings)
{
if ( ($settings['admin'] == 'change-me')
|| ($settings['admin'] == '') ) {
$config_file = $settings['config_file'];
$admin_message = "
The name of the admin is not updated "
. "in the configfile, or it is empty. Set "
. "the variable \$admin in the file "
. " $config_file and retry.
";
quit($db, $admin_message);
}
$admin = $settings['admin'];
$filename = $settings['work_dir'] . 'admin_' . $admin . '_token.txt';
$statement = $db->prepare("SELECT key FROM keys
WHERE type = 'admin'
AND name = '$admin'");
$result = $statement->execute();
$key = '';
$counter = 0;
while ($row = $result->fetchArray(SQLITE3_NUM)) {
$key = "{$row[0]}";
$counter++;
}
if ( ($key == '') && (!file_exists($filename)) ) {
$token = make_token(250, 'alnum');
$token_hash = password_hash($token, PASSWORD_DEFAULT);
if ($counter == 0) {
$statement = $db->prepare("INSERT INTO keys(token, type, name)
VALUES ('$token_hash',
'admin',
'$admin')");
} else {
$statement = $db->prepare("UPDATE keys
SET token = '$token_hash'
WHERE name = '$admin'
AND type = 'admin'");
}
$result = $statement->execute();
$content = "Token = \r\n$token\r\n";
file_put_contents($filename, $content);
return FALSE;
} elseif ( ($key == '') ) {
return FALSE;
} else {
return TRUE;
}
}
// Check if access to the admin panel is enabled in the config file.
function check_admin_panel($db, $settings)
{
if ($settings['enable_admin_panel'] != TRUE) {
header( 'HTTP/1.1 403 Forbidden' );
quit($db, '403');
}
}
// Checks if the number of moderators applications is more than 10.
function check_application_count($db)
{
$statement = $db->prepare("SELECT name
FROM keys
WHERE type = 'application'");
$result = $statement->execute();
$counter = 0;
while ($row = $result->fetchArray(SQLITE3_NUM)) {
$counter++;
}
if ($counter > 10) {
// 10 seems reasonable in order not to loose the overview
return FALSE;
} else {
return TRUE;
}
}
// Check if access to the admin panel and its functions can be given
// or not. First, the token is checked, if there
// is one. If there is none, user/password is checked against the db.
// If the login is successful, a token is created and given back.
function check_auth_admin($db, $settings)
{
$token = read_pretty_vars('last', 'alnum', 250);
// The length of the token is 250 characters
if ( (mb_strlen($token) !== 250) ) {
// The length of the token is 250 characters
$token = get_post_token();
}
if ( (mb_strlen($token) === 250) ) {
// The length of the token is 250 characters
$statement = $db->prepare("SELECT timestamp_token, token, name
FROM keys
WHERE type = 'admin'");
$result = $statement->execute();
while ($row = $result->fetchArray(SQLITE3_NUM)) {
$timestamp_token = "{$row[0]}";
$access_token = "{$row[1]}";
$auth_name = "{$row[2]}";
}
$current = time();
$max_age = $current - ($settings['lifetime_token'] * 60);
// max lifetime is defined in minutes, times 60 to go to seconds
if ( ($timestamp_token < $max_age) ) {
$auth_message = 'outdated token used';
log_event($db, $settings, 'auth', $auth_message, '');
$quit_message = 'Token expired.Log in '
. 'again to get a new one.'
. 'This incident was logged.
';
quit($db, $quit_message);
}
if ( (!password_verify($token, $access_token)) ) {
$auth_message = 'invalid token used';
log_event($db, $settings, 'auth', $auth_message, '');
sleep(10);
$quit_message = 'Invalid token used.'
. 'This incident was logged.
';
quit($db, $quit_message);
}
} elseif ( (!isset($_POST['auth_name']))
|| (!isset($_POST['auth_password'])) ) {
$quit_message = 'Please provide the name and'
. ' password for your account.
';
quit($db, $quit_message);
} else {
$auth_name = filter($_POST['auth_name'], 'alnum', 50);
// 50 seems to be a generous for the length of the username
$statement = $db->prepare("SELECT key
FROM keys
WHERE type = 'admin'
AND name = '$auth_name'");
$result = $statement->execute();
$key = '';
while ($row = $result->fetchArray(SQLITE3_NUM)) {
$key = "{$row[0]}";
}
if ( (!password_verify($_POST['auth_password'], $key)) ) {
$auth_message = 'wrong combination user/password';
log_event($db, $settings, 'auth', $auth_message, '');
sleep(10);
$quit_message = 'Combination of password and username '
. 'is invalid. This incident was logged.
';
quit($db, $quit_message);
}
$auth_message = "admin $auth_name logged on";
log_event($db, $settings, 'auth', $auth_message, '');
$current = time();
$statement = $db->prepare("UPDATE keys
SET timestamp_token = '$current'
WHERE name = '$auth_name'
AND type = 'admin'");
$result = $statement->execute();
}
$token = make_token(250, 'alnum');
$token_hash = password_hash($token, PASSWORD_DEFAULT);
$statement = $db->prepare("UPDATE keys
SET token = '$token_hash'
WHERE name = '$auth_name'
AND type = 'admin'");
$result = $statement->execute();
return $token;
}
// Check if access to the mod panel and can be given or not.
// The token is checked, if there is one. If there is none,
// user/password is checked against the db.
// If the login is successful, a token is created and given back.
function check_auth_mod($db, $settings)
{
$token = read_pretty_vars('last', 'alnum', 250);
// the length of the token is defined to 250 characters, so that it
// cannot be memorized,
// and so that it does never show fully in the addressbar
if ( (mb_strlen($token) !== 250) ) {
// token length = 250
$token = get_post_token();
}
if ( (mb_strlen($token) === 250) ) {
// token length = 250
$statement = $db->prepare("SELECT timestamp_token, token, name
FROM keys
WHERE type = 'mod'");
$result = $statement->execute();
$found_token = FALSE;
while ($row = $result->fetchArray(SQLITE3_NUM)) {
$timestamp_token = "{$row[0]}";
$access_token = "{$row[1]}";
$auth_name = "{$row[2]}";
if ( (password_verify($token, $access_token)) ) {
$found_token = TRUE;
break;
}
}
if ( ($found_token == FALSE) ) {
$auth_message = 'invalid token used';
log_event($db, $settings, 'auth', $auth_message, '');
quit($db, 'Token invalid. This incident was logged.
');
}
$current = time();
$max_age = $current - ($settings['lifetime_token'] * 60);
// lifetime of token is in minutes, times 60 to go to seconds
if ($timestamp_token < $max_age) {
$auth_message = 'outdated token used';
log_event($db, $settings, 'auth', $auth_message, '');
$quit_message = 'Token expired.Log in'
. ' again to get a new one. '
. 'This incident was logged.
';
quit($db, $quit_message);
}
} elseif ( (!isset($_POST['auth_name']))
|| (!isset($_POST['auth_password'])) ) {
$quit_message = 'Please provide the name'
. ' and password for your account.
';
quit($db, $quit_message);
} else {
$auth_name = filter($_POST['auth_name'], 'alnum', 50);
// 50 seems to be a generous for the length of the username
$statement = $db->prepare("SELECT key FROM keys
WHERE type = 'mod'
AND name = '$auth_name'");
$result = $statement->execute();
$key = '';
while ($row = $result->fetchArray(SQLITE3_NUM)) {
$key = "{$row[0]}";
}
if ( (!password_verify($_POST['auth_password'], $key)) ) {
$auth_message = 'wrong combination user/password';
log_event($db, $settings, 'auth', $auth_message, '');
sleep(10);
$quit_message = 'Combination of password and username is'
. ' invalid. This incident was logged.
';
quit($db, $quit_message);
}
$auth_message = "mod $auth_name logged on";
log_event($db, $settings, 'auth', $auth_message, '');
$current = time();
$statement = $db->prepare("UPDATE keys
SET timestamp_token = '$current'
WHERE name = '$auth_name'
AND type = 'mod'");
$result = $statement->execute();
}
$token = make_token(250, 'alnum');
$token_hash = password_hash($token, PASSWORD_DEFAULT);
$statement = $db->prepare("UPDATE keys
SET token = '$token_hash'
WHERE name = '$auth_name'
AND type = 'mod'");
$result = $statement->execute();
return $token;
}
// Check if access to the mod panel is enabled in the config file.
function check_mod_panel($db, $settings)
{
if ($settings['enable_mod_panel'] != TRUE) {
header( 'HTTP/1.1 403 Forbidden' );
quit($db, '403');
}
}
// Delete selected logs
function delete_logs($db, $type, $token)
{
if ($type == 'all') {
$statement = $db->prepare("DELETE FROM logs");
$delete_message = 'all logs were deleted';
} else {
$statement = $db->prepare("DELETE FROM logs
WHERE type = '$type'");
$delete_message = "logs of type $type were deleted";
}
$result = $statement->execute();
echo "$delete_message";
}
// Delete one post or a range of posts.
// If you use php8.* you can change to str_contains below.
function delete_posts($db, $sub, $settings, $token, $delete_mode)
{
//rewrite to check if post exists first,
// and only move it if it is not shadowed
if ($delete_mode == 'shadow') {
$posts = strip_tags($_POST['shadow_posts']);
} elseif ($delete_mode == 'move') {
$posts = strip_tags($_POST['shadow_posts']);
$target_sub = filter($_POST['target_sub'], 'alnum',
$settings['max_name_sub']);
if ( (check_sub_exists($db, $target_sub) != TRUE) ) {
quit($db, "Sub $target_sub does not exist.
");
}
} else {
$posts = strip_tags($_POST['delete_posts']);
}
// if (str_contains($posts, '-')) {
// only uncomment if you use php8.*
if (strpos($posts, '-') !== FALSE) {
$delete_minmax = explode('-', $posts);
$delete_array = array();
for($delete = $delete_minmax['0'];
$delete <= $delete_minmax['1']; $delete++) {
array_push($delete_array, $delete);
}
} else {
$delete_array = explode(' ', $posts);
}
$statement = $db->prepare("SELECT name, token
FROM keys
WHERE type = 'mod'");
$result = $statement->execute();
while ($row = $result->fetchArray(SQLITE3_NUM)) {
$name = "{$row[0]}";
$access_token = "{$row[1]}";
if ( (password_verify($token, $access_token)) ) {
break;
}
}
$html_string = '';
if ( (!empty($delete_array)) && ($delete_mode == 'delete') ) {
foreach($delete_array as $delete_post) {
$statement = $db->prepare("DELETE FROM threads
WHERE post_id = '$delete_post'
AND sub = '$sub'");
$result = $statement->execute();
$delete_message = "message $delete_post from "
. "sub $sub deleted by $name";
log_event($db, $settings, "del", $delete_message, '');
$html_string .= "$delete_message
";
}
} elseif ( (!empty($delete_array)) && ($delete_mode == 'shadow') ) {
foreach($delete_array as $delete_post) {
$statement = $db->prepare("UPDATE threads
SET shadow = 'yes'
WHERE post_id = '$delete_post'
AND sub = '$sub'");
$result = $statement->execute();
$delete_message = "message $delete_post from ";
$delete_message .= "sub $sub shadowed by $name";
log_event($db, $settings, "del", $delete_message, '');
$html_string .= "$delete_message
";
}
} elseif ( (!empty($delete_array)) && ($delete_mode == 'move') ) {
move_post($db, $settings, $delete_array, $sub, $target_sub, $name);
}
$html_string .= 'Done.
';
if ($delete_mode == 'delete') {
$html_string .= "";
} else {
$html_string .= "";
}
echo "$html_string";
}
// Delete or shadow a whole sub
function delete_sub($db, $sub, $settings, $token, $shadow_only)
{
$token_hash = hash('sha512',$token);
$statement = $db->prepare("SELECT name
FROM keys
WHERE token = '$token_hash'");
$result = $statement->execute();
while ($row = $result->fetchArray(SQLITE3_NUM)) {
$name = "{$row[0]}";
}
$html_string = '';
if ( ($sub != '') && ($shadow_only == 'no') ) {
$statement = $db->prepare("DELETE FROM threads
WHERE sub = '$sub'");
$result = $statement->execute();
$delete_message = "sub $sub deleted by $name";
log_event($db, $settings, "del", $delete_message, '');
$html_string .= "$delete_message
";
} elseif ( ($sub != '') && ($shadow_only == 'yes') ) {
$statement = $db->prepare("UPDATE threads
SET shadow = 'yes'
WHERE sub = '$sub'");
$result = $statement->execute();
$delete_message = "sub $sub shadowed by $name";
log_event($db, $settings, "del", $delete_message, '');
$html_string .= "$delete_message
";
}
$html_string .= "Done.
";
if ($shadow_only == 'yes') {
$html_string .= "";
} else {
$html_string .= "";
}
echo "$html_string";
}
// Delete an admin or mod token to end the session
function destroy_token($db, $token, $settings, $log_message)
{
$name = '';
$statement = $db->prepare("SELECT name, token
FROM keys");
$result = $statement->execute();
while ($row = $result->fetchArray(SQLITE3_NUM)) {
$name = "{$row[0]}";
$access_token = "{$row[1]}";
if ( (password_verify($token, $access_token)) ) {
break;
}
}
if ( (empty($name)) ) {
$log_message = 'invalid token used';
} else {
$statement = $db->prepare("UPDATE keys
SET token = 'none'
WHERE name = '$name'");
$result = $statement->execute();
$log_message .= ": $name";
}
log_event($db, $settings, 'auth', $log_message, '');
}
// do a full dump of the board, including names and tripcodes. The file
// will be saved locally (in /var/opt/endboard/). Can be called by the
// admin via the admins interface, or from cli.
function dump_full($db, $settings)
{
// rewrite to include ranges
$json_dump = array();
$statement = $db->prepare("SELECT post_id, org_id,
sub, text, timestamp, name,
tripcode, original, shadow,
move_message, edit_message
FROM threads
");
$result = $statement->execute();
while ($row = $result->fetchArray(SQLITE3_NUM)) {
$post = array();
$post['post_id'] = "{$row[0]}";
$post['org_id'] = "{$row[1]}";
$post['sub'] = "{$row[2]}";
$post['text'] = "{$row[3]}";
$post['timestamp'] = "{$row[4]}";
$post['name'] = "{$row[5]}";
$post['tripcode'] = "{$row[6]}";
$post['original'] = "{$row[7]}";
$post['shadow'] = "{$row[8]}";
$post['move_message'] = "{$row[9]}";
$post['edit_message'] = "{$row[10]}";
array_push($json_dump, $post);
}
$diff = make_token(20, 'alnum');
$filename = $settings['work_dir'] . 'full_dump_' . $diff . '.json';
file_put_contents($filename, json_encode($json_dump,
JSON_PRETTY_PRINT
| JSON_NUMERIC_CHECK
| JSON_UNESCAPED_UNICODE));
}
// This function can be used to replicate an existing board.
// Save the dump from the overboard of the existing board, then put
// it under /var/opt/endboard/board.json of your new server
// (or whatever name you defined in the config-file).
// Log in to your admin panel, click on link 'import' in the footer
function import_overboard($db, $settings)
{
$board_file = $settings['work_dir'] . $settings['import_file'];
if ( file_exists($board_file) ) {
$html_string = "Found importfile $board_file
";
} else {
$html_string = "Could not find importfile "
. "$board_file, aborting.
";
echo "$html_string";
return;
}
$board_json = file_get_contents($board_file);
$board_list = json_decode($board_json, TRUE);
$counter = 0;
foreach($board_list as $post) {
$post_id = $post['post_id'];
$text = $post['text'];
$sub = $post['sub'];
$org_id = $post['org_id'];
$shadow = $post['shadow'];
if (!empty($post['timestamp'])) {
$timestamp = $post['timestamp'];
} else {
$timestamp = '';
}
if (!empty($post['name'])) {
$name = $post['name'];
} else {
$name = '';
}
if (!empty($post['tripcode'])) {
$tripcode = $post['tripcode'];
} else {
$tripcode = '';
}
if (!empty($post['move_message'])) {
$move_message = $post['move_message'];
} else {
$move_message = '';
}
if (!empty($post['edit_message'])) {
$edit_message = $post['edit_message'];
} else {
$edit_message = '';
}
if ( (!empty($text)) && (!empty($sub))
&& (!empty($post_id)) && (!empty($org_id)) ) {
if (!check_post_exists($db, $sub, $post_id)) {
$global_id = hash('sha512', $sub . $post_id .
$org_id . $text . $timestamp);
$text_id = hash('sha512', $text);
$statement = $db->prepare("INSERT OR IGNORE INTO threads
(post_id, sub, text, org_id,
shadow, global_id, text_id,
timestamp, name, tripcode,
original, move_message,
edit_message)
VALUES ('$post_id', '$sub', ?,
'$org_id', '$shadow', '$global_id',
'$text_id', '$timestamp',
'$name', '$tripcode',
'$post_id', ?, ?)");
$statement->bindParam(1, $text);
$statement->bindParam(2, $move_message);
$statement->bindParam(3, $edit_message);
$statement->execute();
$counter++;
$import_message = "message $post_id from sub $sub imported";
log_event($db, $settings, 'import', $import_message, '');
$html_string .= "$import_message
";
} else {
$import_message = "message $post_id from sub $sub"
. " existed already and was not imported";
log_event($db, $settings, 'import', $import_message, '');
$html_string .= "$import_message
";
}
}
}
rename($board_file, $board_file . '.done');
$html_string .= "Finished, imported "
. "$counter messages altogether.
"
. "The boardfile was "
. "renamed to avoid another import.
";
echo "$html_string";
}
// Moves a post to a different sub. In case it is an original post, all
// replies are moved as well.
function move_post($db, $settings, $delete_array, $sub, $target_sub, $name)
{
foreach($delete_array as $delete_post) {
$statement = $db->prepare("UPDATE threads
SET shadow = 'yes'
WHERE post_id = '$delete_post'
AND sub = '$sub'");
$result = $statement->execute();
$statement = $db->prepare("SELECT post_id, org_id, text, name,
timestamp, tripcode, move_message,
edit_message, original
FROM threads
WHERE post_id = '$delete_post'
AND sub = '$sub'");
$result = $statement->execute();
while ($row = $result->fetchArray(SQLITE3_NUM)) {
$post_id = "{$row[0]}";
$org_id = "{$row[1]}";
$text = "{$row[2]}";
$name = "{$row[3]}";
$timestamp = "{$row[4]}";
$tripcode = "{$row[5]}";
$move_message = "{$row[6]}";
$edit_message = "{$row[7]}";
$original = "{$row[8]}";
}
if ( ($org_id == $original) ) {
$new_move = "system message: "
. "post $post_id from sub \"$sub\" was moved "
. "to sub \"$target_sub\"";
$new_id = make_post($db, $target_sub, $settings, $text, '');
$delete_message = "message $delete_post from sub $sub"
. " moved to $target_sub";
log_event($db, $settings, "del", $delete_message, '');
echo "$delete_message
";
$statement = $db->prepare("UPDATE threads
SET shadow = 'yes'
WHERE org_id = '$post_id'
AND sub = '$sub'");
$result = $statement->execute();
$statement = $db->prepare("UPDATE threads
SET move_message = '$new_move',
edit_message = '$edit_message',
original = '$new_id'
WHERE post_id = '$new_id'
AND sub = '$target_sub'");
$result = $statement->execute();
if ( (!empty($name)) &&
(!empty($tripcode)) ) {
$statement = $db->prepare("UPDATE threads
SET name = '$name',
tripcode = '$tripcode'
WHERE post_id = '$new_id'
AND sub = '$target_sub'");
$result = $statement->execute();
}
$statement = $db->prepare("SELECT post_id, org_id, text, name,
timestamp, tripcode, move_message,
edit_message
FROM threads
WHERE org_id = '$post_id'
AND post_id != '$post_id'
AND sub = '$sub'");
$result = $statement->execute();
while ($row = $result->fetchArray(SQLITE3_NUM)) {
$post_id = "{$row[0]}";
$org_id = "{$row[1]}";
$text = "{$row[2]}";
$name = "{$row[3]}";
$timestamp = "{$row[4]}";
$tripcode = "{$row[5]}";
$move_message = "{$row[6]}";
$edit_message = "{$row[7]}";
$original = "{$row[8]}";
$new_move = "system message: "
. "post $post_id from sub \"$sub\" was moved "
. "to sub \"$target_sub\"";
$new_reply_id = make_post($db, $target_sub, $settings,
$text, $new_id);
$delete_message = "message $post_id from sub $sub moved "
. "to $target_sub";
log_event($db, $settings, "del", $delete_message, '');
echo "$delete_message
";
$statement = $db->prepare("UPDATE threads
SET shadow = 'yes'
WHERE org_id = '$post_id'
AND sub = '$sub'");
$result = $statement->execute();
$statement = $db->prepare("UPDATE threads
SET move_message = '$new_move',
edit_message = '$edit_message',
original = '$new_id'
WHERE post_id = '$new_reply_id'
AND sub = '$target_sub'");
$result = $statement->execute();
if ( (!empty($name)) &&
(!empty($tripcode)) ) {
$statement = $db->prepare("UPDATE threads
SET name = '$name',
tripcode = '$tripcode'
WHERE post_id = '$new_id'
AND sub = '$target_sub'");
$result = $statement->execute();
}
}
} else {
$new_move = "system message: post "
. "$post_id from sub \"$sub\" was moved "
. "to sub \"$target_sub\"";
$new_id = make_post($db, $target_sub, $settings, $text, '');
$delete_message = "message $post_id from sub $sub moved"
. " to $target_sub";
log_event($db, $settings, "del", $delete_message, '');
echo "$delete_message
";
$statement = $db->prepare("UPDATE threads
SET shadow = 'yes'
WHERE org_id = '$post_id'
AND sub = '$sub'");
$result = $statement->execute();
$statement = $db->prepare("UPDATE threads
SET move_message = '$new_move',
edit_message = '$edit_message',
original = '$new_id'
WHERE post_id = '$new_id'
AND sub = '$target_sub'");
$result = $statement->execute();
if ( (!empty($name)) &&
(!empty($tripcode)) ) {
$statement = $db->prepare("UPDATE threads
SET name = '$name',
tripcode = '$tripcode'
WHERE post_id = '$new_id'
AND sub = '$target_sub'");
$result = $statement->execute();
}
}
}
}
// Set the password for the admin, delete all old admin accounts
// (there can only be one...)
function set_password($db, $name, $password_hash, $token, $settings)
{
$db_token = '';
$db_name = '';
$statement = $db->prepare("SELECT name, token
FROM keys
WHERE type = 'admin'
AND name = '$name'");
$result = $statement->execute();
while ($row = $result->fetchArray(SQLITE3_NUM)) {
$db_name = "{$row[0]}";
$db_token = "{$row[1]}";
}
if ( (!password_verify($token, $db_token)) ) {
$auth_message = "wrong combination name/token";
log_event($db, $settings, 'auth', $auth_message, '');
sleep(10);
$quit_message = "Combination of username and token is invalid."
. " This incident was logged.
";
quit($db, $quit_message);
} else {
$statement = $db->prepare("UPDATE keys
SET key = '$password_hash'
WHERE name = '$name'
AND type = 'admin'");
$result = $statement->execute();
$statement = $db->prepare("DELETE FROM keys
WHERE type = 'admin'
AND name != '$name'");
$result = $statement->execute();
unlink($settings['work_dir'] . "admin_" . $name . "_token.txt");
}
}
// Show the form that allows the admin and mods to log in.
// Can be disabled in the config file.
function show_auth_form($db, $css, $settings, $type)
{
$html_string = 'Give your account name and password to log in.
'
. '
';
echo "$html_string";
}
// Show all posts that have been shadowed by moderators
function show_shadowed($db, $css, $settings, $token)
{
print_top_header('Shadowed messages and subs');
$statement = $db->prepare("SELECT post_id, org_id, sub, text
FROM threads
WHERE shadow = 'yes'
ORDER BY sub");
$result = $statement->execute();
$prev_sub = '';
$html_string = '';
while ($row = $result->fetchArray(SQLITE3_NUM)) {
$post_id = "{$row[0]}";
$org_id = "{$row[1]}";
$sub = "{$row[2]}";
$text = "{$row[3]}";
$post_text = break_text(bbcode_to_html($text, $settings, $sub),
$settings);
$html_string .= ""
. "
"
. " | "
. "-------------------------------------"
. " |
"
. "
$sub/$post_id
$post_text"
. "
";
if ($prev_sub != $sub) {
$html_string .= " | "
. "-------------------------------------"
. " |
";
}
$html_string .= '
';
$prev_sub = $sub;
}
echo "$html_string";
}
// Show the existing subs to the admin
function show_subs_admin_mod($db, $settings, $css, $token, $type)
{
if ( ($type == 'admin') ) {
$link = 'a';
} else {
$link = 'm';
}
$html_string = '';
$statement = $db->prepare("SELECT DISTINCT sub
FROM threads
WHERE shadow = 'no'
ORDER BY sub
COLLATE NOCASE");
$result = $statement->execute();
while ($row = $result->fetchArray(SQLITE3_NUM)) {
$sub = "{$row[0]}";
$total_posts = give_total_posts($db, $sub, FALSE, $settings);
$html_string .= " | $sub"
. "($total_posts)
";
}
$html_string .= '
';
echo "$html_string";
}
// Show the form that allows to apply for a moderators account.
function show_apply_form($db, $settings)
{
//rewrite to set rows ?
$html_string = 'Give the desired name for your account, '
. 'an email address'
. ' (or other contact) and a password.
'
. '
'
. '
';
echo "$html_string";
}
// Show the form that allows to set passwords for the admin account.
function show_set_password_form($db, $settings)
{
//rewrite to set rows ?
$html_string = 'Give the name of your account and the token'
.' to set your password.
'
.'
'
.'
';
echo "$html_string";
}
// Show the form that enables the admin and the mods to delete,
// shadow or move messages and subs
function show_form_admin_mod($db, $sub, $token, $type)
{
$html_string = '
';
if ( ($type == 'admin') ) {
$html_string .= '