dev_endboard/opt/mobile.php

960 lines
32 KiB
PHP

<?php
/*
* This is the endboard software, version beta 0.80.
* It is a textboard, written for the use in the darknets.
*
* This file contains all the functions needed for the second page, located
* under /srv/endboard/mob by default. This page is meant for mobile phones
* and other devices with touchscreens. It is sourced by the index file in
* that directory.
*
* The writing of this code started some time ago with another software
* called smolBBS. Although there is almost no original code left now,
* I still regard endboard as a fork of smolBBS.
* The author of smolBBS has required that the following text be
* distributed with any redistribution, so here it goes.
* The license and other conditions apply to endboard as well.
*
* IRC: *dulm @ irc.rizon.net
*
* Copyright (C) 2020 sandlind
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* (1) Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* (2) Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* (3)The name of the author may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
// Give a new location to the browser.
// Does not work with lynx, unfortunately, but then the link can be used.
// For the mobile version, lynx does not matter, of course.
function answer_redirect_mob($sub)
{
header( "refresh:3;url=/mob/s/$sub" );
// we wait 3 seconds with the redirection
$html_string = '<title>wait for it...</title></head>'
. '<body><div class="site-container">'
. '<div class="posts" id="posts">'
. '<div class="message first">'
. '<h3>Redirection in about 3 secs.'
. ' If that does not work, go'
. " <a href='/mob/s/$sub'>back</a>.</div></div>";
echo "$html_string";
}
// Translate simple bbcode to html, and highlight quotes, like so:
// [b bold],[i italic],[u underlined],[s strikethrough]
// [h headline],[sp spoiler],[li list element],[url link],>>quote\r\n
function bbcode_to_html_mob($text, $settings)
{
if ( ($settings['enable_bbcode'] == FALSE) ) {
return $text;
}
$search = array (
'/(\[b\ )(.*)(\])/',
'/(\[i\ )(.*)(\])/',
'/(\[u\ )(.*)(\])/',
'/(\[s\ )(.*)(\])/',
'/(\[h\ )(.*)(\])/',
'/(\[sp\ )(.*)(\])/',
'/(\[li\ )(.*)(\])/',
'/(\[url\ )(.*)(\])/',
'/>>(.*)\r\n/'
);
$replace = array (
'<strong>$2</strong>',
'<em>$2</em>',
'<u>$2</u>',
'<s>$2</s>',
'<h2>$2</h2>',
'<span class=spoiler tabindex="0">$2</span>',
'<li>$2</li>',
'<a href="$2" target="_blank">$2</a>',
'<quote>>>$1$2</quote><br>'
);
return preg_replace($search, $replace, $text);
}
// check if the ip has already passed the portal, in this case return.
// if not, display a simple text and button to click to proceed.
// the page displayed is done with inline styling, so that no
// additional files will be requested.
// Update: what started with the checking of the ip, has now expanded to
// up to six parameters, which are concantenated and hashed.
function check_portal_mob($db, $settings, $ip)
{
if ( ($settings['enable_portal'] != TRUE) ) {
return;
}
if ( ($settings['enable_portal_tor'] != TRUE)
&& ($_SERVER['REMOTE_ADDR'] == '127.0.0.1') ) {
return;
}
$current = time();
$max_age = $current - ($settings['portal_lifetime'] * 60);
// lifetime is in minutes, so times 60 to go to seconds
if ($settings['auto_prolong_portal'] == TRUE) {
$statement = $db->prepare("SELECT unix_timestamp
FROM logs
WHERE type = 'portal'
AND ip = '$ip'
AND event in ('pass',
'visit')
AND unix_timestamp > '$max_age'
ORDER BY ROWID DESC LIMIT 1");
} else {
$statement = $db->prepare("SELECT unix_timestamp
FROM logs
WHERE type = 'portal'
AND ip = '$ip'
AND event in ('pass')
AND unix_timestamp > '$max_age'
ORDER BY ROWID DESC LIMIT 1");
}
$result = $statement->execute();
$portal_pass = 0;
while ($row = $result->fetchArray(SQLITE3_NUM)) {
$portal_pass++;
}
if ( ($portal_pass > 0) ) {
// bigger zero means we have the last hit, meaning the ip
// is known
$portal_message = 'visit';
log_event($db, $settings, "portal", $portal_message, $ip);
return;
} else {
$random_string = make_token(10, 'alpha');
$request = $_SERVER['REQUEST_URI'] . '/random=' . $random_string;
header( 'HTTP/1.1 202 Accepted' );
header( 'Cache-Control: no-store', FALSE );
$html_string = "<!DOCTYPE html><html><head><style>"
. "body {font-size:30px;background-color: black;"
. "color: #33cccc;text-align: center;width: 30em;"
. "margin-left: auto;margin-right: auto;}"
. "input[type=submit] {padding:5px 15px;"
. "font-size:25px;"
. "background-color: black;"
. "color: #33cccc;"
. "cursor:pointer;"
. "border: 1px solid #11bbcc;"
. "-webkit-border-radius: 5px;"
. "border-radius: 5px;}"
. "</style></head><body><br><br><br>"
. "<code>Entry portal: "
. "Please click the button to proceed.</code>"
. "<br><br><br><br><br><br><div class='form'>"
. "<form action='/ep' method='post'>"
. "<input type='hidden' name='portal' value='$request'>"
. "<input type='submit' value='Enter'><br>"
. "</form></div>"
. "<br><br><br><br><br><br><code>Sorry for this,"
. " it's just a lowlevel protection "
. "against scraping bots.</code></body></html>";
echo "$html_string";
quit($db, '');
}
}
// Show each post in a thread
function print_thread_mob($db, $sub, $settings, $org_id)
{
$html_string = '<div class="posts" id="posts">';
$statement = $db->prepare("SELECT post_id, org_id, sub, text
FROM threads WHERE sub = '$sub'
AND org_id = '$org_id'
AND shadow = 'no'
ORDER BY post_id");
$result = $statement->execute();
while ($row = $result->fetchArray(SQLITE3_NUM)) {
$post_id = "{$row[0]}";
$org_id = "{$row[1]}";
$post_text = "{$row[3]}";
$post_text = break_text(bbcode_to_html_mob($post_text, $settings),
$settings);
$id_text = make_id_text($post_id);
$html_string .= "<div><div class='message'>#$id_text <br>"
. "<p id=\"$post_id\"></p><br>"
. "$post_text<br><br></div><br></div>";
}
$html_string .= '</div>';
echo "$html_string";
}
// Show each post of the overboard (so all original posts in their
// sequence, including bumps, except for the subs that are excluded)
function print_overboard_mob($db, $settings, $page)
{
$out = '';
$pagination = $settings['pagination'];
if ( (!empty($settings['no_overboard'])) ) {
$last = array_pop($settings['no_overboard']);
foreach($settings['no_overboard'] as $no_overboard) {
$str = "'" . $no_overboard . "', ";
$out .= $str;
}
$out .= "'" . $last . "'";
}
if ($page == 'all') {
$statement = $db->prepare("SELECT post_id, org_id, sub, text
FROM threads
WHERE org_id = original
AND shadow = 'no'
AND sub NOT IN ($out)
ORDER BY ROWID DESC");
} elseif ($page > 0) {
// if the page is defined
$page_start = ($page - 1) * $settings['pagination'];
$statement = $db->prepare("SELECT post_id, org_id, sub, text
FROM threads
WHERE org_id = original
AND shadow = 'no'
AND sub NOT IN ($out)
ORDER BY ROWID DESC
LIMIT '$page_start', '$pagination'");
} else {
$statement = $db->prepare("SELECT post_id, org_id, sub, text
FROM threads
WHERE org_id = original
AND shadow = 'no'
AND sub NOT IN ($out)
ORDER BY ROWID DESC
LIMIT '$pagination'");
}
$result = $statement->execute();
echo '<div class="posts" id="posts">';
while ($row = $result->fetchArray(SQLITE3_NUM)) {
$html_string = '<div class="message first">';
$post_id = "{$row[0]}";
$org_id = "{$row[1]}";
$sub = "{$row[2]}";
$text = "{$row[3]}";
$post_text = break_text(bbcode_to_html_mob($text, $settings));
$link_string_1 = "/mob/r/$sub/$org_id/op";
$link_string_2 = "/mob/r/$sub/$org_id";
$link_string_3 = "/mob/s/$sub";
$html_string .= "<a href='$link_string_3'>$sub</a> "
. "<a href='$link_string_1'>#$post_id</a>"
. "<br>$post_text<br>"
. "<a href='$link_string_2'>reply</a></div>";
echo "$html_string";
if ($page == 'all') {
print_replies_mob($db, $sub, $post_id, $org_id,
$settings, 'open');
} else {
print_replies_mob($db, $sub, $post_id, $org_id,
$settings, 'closed');
}
echo '<hr /><hr />';
}
}
// Show each post of an individual feed
function print_individual_feed_mob($db, $settings, $ex_subs, $in_subs)
{
echo '<div class="posts" id="posts">';
$counter = 0;
if ( (!empty($ex_subs)) ) {
$out = '';
$last = array_pop($ex_subs);
foreach($ex_subs as $ex_sub) {
$str = "'" . $ex_sub . "', ";
$out .= $str;
}
$out .= "'" . $last . "'";
$statement = $db->prepare("SELECT post_id, org_id, sub, text
FROM threads
WHERE org_id = original
AND shadow = 'no'
AND sub NOT IN ($out)
ORDER BY ROWID DESC");
} elseif ( (!empty($in_subs)) ) {
$in = '';
$last = array_pop($in_subs);
foreach($in_subs as $in_sub) {
$str = "'" . $in_sub . "', ";
$in .= $str;
}
$in .= "'" . $last . "'";
$statement = $db->prepare("SELECT post_id, org_id, sub, text
FROM threads
WHERE org_id = original
AND shadow = 'no'
AND sub IN ($in)
ORDER BY ROWID DESC");
}
$result = $statement->execute();
while ($row = $result->fetchArray(SQLITE3_NUM)) {
$html_string = '<div class="message first">';
$counter++;
$post_id = "{$row[0]}";
$org_id = "{$row[1]}";
$sub = "{$row[2]}";
$text = "{$row[3]}";
$post_text = break_text(bbcode_to_html_mob($text, $settings));
$link_string_1 = "/mob/r/$sub/$org_id/op";
$link_string_2 = "/mob/r/$sub/$org_id";
$link_string_3 = "/mob/s/$sub";
$html_string .= "<a href='$link_string_3'>$sub</a> "
. "<a href='$link_string_1'>#$post_id</a>"
. "<br>$post_text<br>"
. "<a href='$link_string_2'>reply</a></div>";
echo "$html_string";
print_replies_mob($db, $sub, $post_id, $org_id, $settings);
echo '<br>';
}
return $counter;
}
// Print the hamburger menu with the links
function print_hamburger_menu($db, $settings, $sub, $total_posts, $page)
{
$html_string = '<div class="menu-container">'
. "<h3>$sub</h3>"
. '<input type="checkbox" id="menu-toggle"'
. ' class="menu-toggle">'
. '<label for="menu-toggle" class="hamburger">'
. '<div class="bar"></div>'
. '<div class="bar"></div>'
. '<div class="bar"></div>'
. '</label>'
. '<nav class="nav">'
. '<ul>';
if ( $sub != 'overboard' ){
$html_string .= '<li><a href="/mob/s/overboard">overboard</a></li>';
} elseif ( $sub != 'main' ){
$html_string .= '<li><a href="/mob/s/main">main</a></li>';
}
$html_string .= '<li><a href="/mob/su">navigation</a></li>'
. '<div class="bar"></div>'
. "<li><a href='/d/$sub'>save $sub</a></li>";
if ( ($total_posts > $settings['pagination']) && ($page != 'all') ) {
$number_first_message = ($page - 1) * $settings['pagination'] + 1;
$number_last_message =
$number_first_message + $settings['pagination'] - 1;
if ($number_last_message > $total_posts) {
$number_last_message = $total_posts;
}
$next_page = $page + 1;
$prev_page = $page - 1;
$pages_total = ceil($total_posts / $settings['pagination']);
$link_string_1 = "/mob/s/$sub/$next_page";
$link_string_2 = "/mob/s/$sub/$prev_page";
$link_string_3 = "/mob/s/$sub/all";
if ( ($number_first_message > 1)
&& ($number_last_message < $total_posts) ) {
$html_string .= "<li><a href='$link_string_1'>show older</a></li>"
. "<li><a href='$link_string_2'>show newer</a></li>"
. "<li><a href='$link_string_3'>show all</li>";
} elseif ($number_last_message == $total_posts) {
$html_string .= "<li><a href='$link_string_2'>show newer</a></li>"
. "<li><a href='$link_string_3'>show all</li>";
} else {
$html_string .= "<li><a href='$link_string_1'>show older</a></li>"
. "<li><a href='$link_string_3'>show all</li>";
}
}
$html_string .= '</ul></nav></div>';
echo "$html_string";
}
// Give all the http-headers to the client, mostly for opsec reasons.
// After, print the html header to open the document for the browser.
function print_header_mob()
{
// header( 'Content-Type: text/html; charset=utf-8');
// header( 'X-Frame-Options: DENY', FALSE);
// header( 'HTTP Cross-Origin-Opener-Policy: same-origin', FALSE);
// header( 'Cross-Origin-Resource-Policy: same-site', FALSE);
// header( 'Permissions-Policy: geolocation=(), camera=(), microphone=()',
// FALSE);
// header( 'Permissions-Policy: interest-cohort=()', FALSE);
// header( 'Server: webserver', FALSE);
// header( 'X-DNS-Prefetch-Control: off', FALSE);
// header( 'Cache-Control: no-cache', FALSE);
// header( 'Pragma: no-cache', FALSE);
// nginx used to throw an error with those, and gave back 502 - bad gateway
// everything worked in latest tests, but reasons are not understood.
// if problems, comment out all the lines above
$html_string = '<!DOCTYPE html><html lang="en"><head>'
. '<meta charset="UTF-8">'
. '<meta name="viewport" content="width=device-width,'
. ' initial-scale=1.0"><!-- Main stylesheet -->'
. ' <link rel="stylesheet" href="/css/mobile.css"> '
. '<!-- Themes are now modular and easy to modify -->'
. '<link rel="stylesheet" href="/css/dirtpathmobile.css">';
echo "$html_string";
}
// Show all replies to a given post
function print_replies_mob($db, $sub, $post_id, $org_id, $settings, $state)
{
$sub_statement = $db->prepare("SELECT post_id, org_id,
sub, text, timestamp,
name, tripcode
FROM threads
WHERE sub = '$sub'
AND org_id = '$org_id'
AND org_id != original
AND shadow = 'no'");
$sub_result = $sub_statement->execute();
$answers = array();
$counter = 0;
while ($row = $sub_result->fetchArray(SQLITE3_NUM)) {
$sub_post_id = "{$row[0]}";
$sub_org_id = "{$row[1]}";
$sub_text = "{$row[3]}";
$sub_timestamp = "{$row[4]}";
$sub_name = "{$row[5]}";
$sub_tripcode = "{$row[6]}";
if ($sub_post_id != $sub_org_id) {
$counter++;
$post = array();
$sub_post_text = break_text(bbcode_to_html_mob
($sub_text, $settings, $sub));
array_push($post, $sub_post_id);
array_push($post, $sub_org_id);
array_push($post, $sub_post_text);
array_push($post, $sub_timestamp);
array_push($post, $sub_name);
array_push($post, $sub_tripcode);
array_push($answers, $post);
}
}
$display_number = $counter - 1;
if ($counter == 0) {
// no replies exist for this message
return;
}
$last_answer = array_pop($answers);
$last_post_id = $last_answer[0];
$last_post_text = $last_answer[2];
$last_post_timestamp = $last_answer[3];
$last_post_name = $last_answer[4];
$last_post_tripcode = $last_answer[5];
$html_string = '';
if ($counter > 1) {
// we have at least one reply
if ($state == 'open') {
$html_string .= "<details open>";
} else {
$html_string .= "<details>";
}
$html_string .= "<summary>Show $display_number more replies</summary>";
foreach ($answers as $display_msg) {
$answer_post_id = $display_msg[0];
$answer_post_text = $display_msg[2];
$answer_post_timestamp = $display_msg[3];
$answer_post_name = $display_msg[4];
$answer_post_tripcode = $display_msg[5];
$link_string_1 = "/mob/r/$sub/$org_id/$answer_post_id/5";
$html_string .= "<div class='message replies'>"
. "<p id=\"$answer_post_id" . "_" . "$sub\"></p>"
. "<a href='$link_string_1'>#$answer_post_id</a>";
if ( !empty($answer_post_timestamp) &&
$settings['enable_timestamps'] ) {
$html_string .= "<small>:$answer_post_timestamp</small>";
}
$html_string .= "<br><br><code>$answer_post_text</code><br><br>";
if ( !empty($answer_post_name) &&
$settings['enable_edit']) {
$html_string .= "<a href='/e/$sub/$answer_post_id'>edit</a> ";
}
if ( !empty($answer_post_name) &&
$settings['enable_tripcodes']) {
$name_string = $answer_post_name;
$link_string_4 = "/mob/u/$name_string";
$html_string .= "<a href='$link_string_4'>$name_string</a>";
}
$html_string .= '</div>';
}
$html_string .= "</details>";
}
$link_string_1 = "/mob/r/$sub/$org_id/$last_post_id";
$html_string .= "<div class='message last'>"
. "<p id=\"$last_post_id" . "_" . "$sub\"></p>"
. "<a href='$link_string_1'>#$last_post_id</a>";
if ( !empty($last_post_timestamp) &&
$settings['enable_timestamps'] ) {
$html_string .= "<small>:$last_post_timestamp</small>";
}
$html_string .= "<br><br>$last_post_text<br><br>";
if ( !empty($last_post_name) &&
$settings['enable_edit']) {
$html_string .= "<a href='/mob/e/$sub/$last_post_id'>edit</a> ";
}
if ( !empty($last_post_name) &&
$settings['enable_tripcodes']) {
$name_string = $last_post_name;
$link_string_4 = "/mob/u/$name_string";
$html_string .= "<a href='$link_string_4'>$name_string</a>";
}
$html_string .= '</div>';
echo "$html_string";
}
// Show each post in a sub
function print_sub_mob($db, $sub, $settings, $page)
{
echo '<div class="posts" id="posts">';
$pagination = $settings['pagination'];
if ($page == 'all') {
$statement = $db->prepare("SELECT post_id, org_id, sub, text
FROM threads
WHERE sub = '$sub'
AND shadow = 'no'
AND original = org_id
ORDER BY ROWID DESC");
} elseif ($page > 0) {
// if the page is defined
$page_start = ($page - 1) * $settings['pagination'];
$statement = $db->prepare("SELECT post_id, org_id, sub, text
FROM threads
WHERE sub = '$sub'
AND shadow = 'no'
AND original = org_id
ORDER BY ROWID DESC
LIMIT '$page_start', '$pagination'");
} else {
$statement = $db->prepare("SELECT post_id, org_id, sub, text
FROM threads
WHERE sub = '$sub'
AND shadow = 'no'
AND original = org_id
ORDER BY ROWID DESC
LIMIT '$pagination'");
}
$result = $statement->execute();
while ($row = $result->fetchArray(SQLITE3_NUM)) {
$html_string = '<div class="message first">';
$post_id = "{$row[0]}";
$org_id = "{$row[1]}";
$text = "{$row[3]}";
$post_text = break_text(bbcode_to_html_mob($text, $settings));
$id_text = make_id_text($post_id);
$link_string_1 = "/mob/r/$sub/$org_id/op";
$link_string_2 = "/mob/r/$sub/$org_id";
$html_string .= "<a href='$link_string_1'>#$id_text</a>"
. "<br>$post_text<br>"
. "<a href='$link_string_2'>reply</a></div>";
echo "$html_string";
if ($page == 'all') {
print_replies_mob($db, $sub, $post_id, $org_id,
$settings, 'open');
} else {
print_replies_mob($db, $sub, $post_id, $org_id,
$settings, 'closed');
}
echo '<hr /><hr />';
}
echo "</div>";
}
// In case of replies, check which post we are replying to
// (based on the pretty vars in GET requests)
function set_org_id_mob()
{
$org_id = read_pretty_vars(4, 'number', 10);
// we read from the third position, and a message does not need more
// than 10 digits (=max 9 999 999 999 messages)
return $org_id;
}
// Get the page if it is defined, otherwise set to 1
function set_page_mob()
{
$page = read_pretty_vars(4, 'number', 10);
// read from fourth position, and a page does not need more
// than 10 digits
if ( ($page < 1) ) {
// if the page is zero, it means we did not
// get a number before
$page = read_pretty_vars(4, 'alnum', 3);
// read from the third position, and "all" has three letters
if ( ($page != 'all') ) {
$page = 1;
// if page is not "all", we start with the first
}
}
return $page;
}
// Get the quote, if there is one.
function set_quote_mob()
{
if (get_pretty_vars_count() == 7) {
$quote = read_pretty_vars(5, 'alnum', 10);
// read from fourth position, and a post id does not need more
// than 10 digits
} else {
$quote = '';
}
return $quote;
}
// Determine which sub we use currently, first read from POST,
// than from the pretty vars (GET)
function set_sub_mob($settings)
{
$sub = '';
if ( (!empty($_POST['sub'])) ) {
$sub = filter($_POST['sub'], 'alnum', $settings['max_name_sub']);
} elseif (get_pretty_vars_count() > 1) {
$sub = read_pretty_vars(3, 'alnum', $settings['max_name_sub']);
// read the sub from the third position
}
if ($sub == '') {
$sub = 'main';
}
return $sub;
}
// Show the postform with or without the captcha (according to setting),
// if on main show also the field to create new subs
function show_post_form_mob($db, $msg, $sub, $settings, $org_id, $quote, $ip)
{
if ( (check_free_space($db, $settings) == FALSE) ) {
echo '<h3>No posting possible, no space on filesystem</h3>';
return;
}
if ( (post_block_user($db, $settings, $ip) != TRUE) ) {
echo '<h3>Max posts exhausted. Retry later.</h3>';
return;
}
$html_string = '<form action="/mob/p" method="POST" class="box-input">';
if ( ($sub != 'main') ) {
$html_string .= "<input type='hidden' name='sub' value='$sub'>";
}
if ( (!empty($org_id)) ) {
$html_string .= "<input type='hidden' name='org_id' value='$org_id'>";
}
$token = make_token(250, 'alnum');
$html_string .= "<input type='hidden' name='post_token' value='$token'>"
. '<textarea id="text" name="text"'
. ' placeholder="Say something"></textarea>'
. '<button type="submit" id="send-button">Send</button>'
. '</form>';
$current = time();
$hash = hash('sha512', $token);
$statement = $db->prepare("INSERT OR IGNORE INTO captchas(hash, unix_timestamp)
VALUES ('$hash', '$current')");
$statement->execute();
echo "$html_string";
}
// Show the existing subs to a user, including their count
// Differentiates between subs with > 10 posts (high-traffic)
// and lower (low-traffic). Also shows the last five subs that
// were posted to.
function show_subs_count_mob($db, $settings)
{
$out = '';
if ( (!empty($settings['no_overboard'])) ) {
$last = array_pop($settings['no_overboard']);
foreach($settings['no_overboard'] as $no_overboard) {
$str = "'" . $no_overboard . "', ";
$out .= $str;
}
$out .= "'" . $last . "'";
}
$statement = $db->prepare("SELECT post_id
FROM threads
WHERE sub NOT IN ($out)
AND shadow = 'no'");
$result = $statement->execute();
$counter = 0;
while ($row = $result->fetchArray(SQLITE3_NUM)) {
$counter++;
}
$statement = $db->prepare("SELECT post_id
FROM threads
WHERE sub NOT IN ($out)
AND shadow = 'no'
AND post_id = org_id");
$result = $statement->execute();
$counter_org = 0;
while ($row = $result->fetchArray(SQLITE3_NUM)) {
$counter_org++;
}
$replies = $counter - $counter_org;
$html_string = "<h3> Subs with some traffic:</h3>"
. '<div class="message first">'
. "<a href=/mob/s/overboard>overboard"
. "($counter_org/$replies)</a></div>";
$statement = $db->prepare("SELECT DISTINCT sub
FROM threads
WHERE shadow = 'no'
ORDER BY sub
COLLATE NOCASE");
$result = $statement->execute();
$high_traffic_subs = array();
$low_traffic_subs = array();
while ($row = $result->fetchArray(SQLITE3_NUM)) {
$display_sub = array();
$sub = "{$row[0]}";
$total_posts = give_total_posts($db, $sub, FALSE, $settings);
$total_org_posts = give_total_posts($db, $sub, TRUE, $settings);
$replies = $total_posts - $total_org_posts;
array_push($display_sub, $sub);
array_push($display_sub, $total_org_posts);
array_push($display_sub, $replies);
if ( ($total_posts > 10) ) {
// we define any sub with more than ten messages as high traffic
// anything below as low traffic
array_push($high_traffic_subs, $display_sub);
} else {
array_push($low_traffic_subs, $display_sub);
}
}
foreach($high_traffic_subs as $display_sub) {
$html_string .= '<div class="message first">'
. "<a href=/mob/s/$display_sub[0]>$display_sub[0]"
. "($display_sub[1]/$display_sub[2])</a></div>";
}
$html_string .= '<br><br><br><h3>Other subs:</h3>';
$temp = array_reverse($low_traffic_subs);
$first_display_sub = array_pop($temp);
$low_traffic_subs = array_reverse($temp);
$html_string .= '<div class="message first">'
. "<a href=/mob/s/$first_display_sub[0]>"
. "$first_display_sub[0]"
. "($first_display_sub[1]/$first_display_sub[2])</a></div>";
foreach($low_traffic_subs as $display_sub) {
$html_string .= '<div class="message first">'
. "<a href=/mob/s/$display_sub[0]>$display_sub[0]"
. "($display_sub[1]/$display_sub[2])</a></div>";
}
$statement = $db->prepare("SELECT DISTINCT sub
FROM threads
WHERE shadow = 'no'
ORDER BY ROWID DESC
LIMIT 5");
$result = $statement->execute();
$html_string .= '<br><br><br><h3>Subs with recent posts:</h3>';
while ($row = $result->fetchArray(SQLITE3_NUM)) {
$sub = "{$row[0]}";
$html_string .= '<div class="message first">'
. "<a href=/mob/s/$sub>$sub</a></div>";
}
echo "$html_string";
}
// Show the existing subs to a user, without the count
function show_subs_no_count_mob($db)
{
$html_string = "<h3><a href=/mob/s/overboard>overboard</a>";
$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]}";
if ( ($sub != '') ) {
$html_string .= " | <a href=/mob/s/$sub>$sub</a>";
}
}
$html_string .= '</h3>';
echo "$html_string";
}
// EOF