Entrance Events! Chat Gallery Search Everyone Wiki Login Register

Welcome, Guest. Please login or register. - Thinking of joining the forum??
April 01, 2025 - @50.61 (what is this?)
Activity rating: One Star Posts & Arts: 2/1k.beats Unread Topics | Unread Replies | My Stuff | Random Topic | Recent Posts Start New Topic  Submit Art
News: :happy: Open the all windows! Your mind needs storms and air! :happy: Super News: Upload a banner!

+  MelonLand Forum
|-+  World Wild Web
| |-+  ♺ ∙ Web Crafting Materials
| | |-+  PHP code to make your own simple BBS system!


« previous next »
Pages: [1] Print
Author Topic: PHP code to make your own simple BBS system!  (Read 64 times)
angelhanachi
Casual Poster ⚓︎
*


making nu metal in 14/4 time cuz I'm bored

⛺︎ My Room
SpaceHey: Friend Me!
PicMix: angel_hanachi

View Profile WWWArt

Ribbon of FriendshipJoined 2025!
« on: March 08, 2025 @817.74 »

This is heavily modified code originally made by Baccyflap, he asked for a copy of this code too lol

Modifications made by me! Credit isn't need as it's just a modification of someone else's code but also because Baccyflap didn't require credit either so I will share alike! I just want to give a lil something to the community as a newbie :)

Code
<html><head>
<title>bbs</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<meta name="viewport" content="width=device-width, user-scalable=yes">
<?php
$data = 'data.txt';
date_default_timezone_set('Asia/Tokyo');
$contents = file_exists($data) ? file_get_contents($data) : '';
if (!empty($contents)) {
 $lines = explode("\n", $contents);
 $posts = array();
 foreach ($lines as $line) {
  $parts = explode(',', $line);
  if (count($parts) > 1) {
   $posts[] = array('user' => $parts[0],
   'time' => date('Y/m/d h:iA', $parts[1]),
   'message' =>  $parts[2],
   'title' => $parts[3],
   'image' => $parts[4],
   'idnum' => $parts[5],
   'replyidnum' => $parts[6]);
  }
 }
}

$error = false;

if (isset($_POST['userpost']) && empty($_POST['email'])) {
 $name = trim($_POST['userpost']);
 $name = str_replace(',', '&#44;', $name);
 $name = filter_var($_POST['userpost'], FILTER_SANITIZE_STRING);
 
 $url = filter_var($_POST['urlpost'], FILTER_SANITIZE_STRING);
 $url = trim($url);
 $url = str_replace('http://','',$url);
 $url = str_replace('https://','',$url);
 $url = rtrim($url,"/");

 $time = time();

 $message = filter_var($_POST['messagepost'], FILTER_SANITIZE_STRING);
 $message = str_replace("\r\n", "<br>", $message);
 $message = str_replace(',', '&#44;', $message);

 $title = filter_var($_POST['titlepost'], FILTER_SANITIZE_STRING);
 $title = str_replace("\r\n", "<br>", $title);
 $title = str_replace(',', '&#44;', $title);

 $image = filter_var($_POST['imagepost'], FILTER_SANITIZE_STRING);
 $image = str_replace("\r\n", "<br>", $image);
 $image = str_replace(',', '&#44;', $image);
 
$idnum = 'A' . time() . count($posts);

 $replyidnum = filter_var($_POST['replypost'], FILTER_SANITIZE_STRING);
         if (empty($replyidnum)) {
            $replyidnum = 'null';
        }

//no link
 if (($name != '') AND ($message != '') AND ($title != '')
 ) {
//to add admins, moderators and special users, use this code here
  if(($name == 'INSERT NAME HERE') AND ($url == 'SPECIAL CODE HERE')) {
   $user = '<a href="LINK HERE" target="_blank" class="verified" title="moderator/admin">NAME HERE</a>';
  }
  else if (!empty($url)) {
   $user = '<a href="http://' . $url . '" target="_blank">' . $name . '</a>';
  }
   else {
   $user = $name;
  }

//line system format
  $line = $user . ',' . $time . ',' . $message . ',' . $title . ',' . $image . ',' . $idnum . ',' . $replyidnum . ',' . "\n";

//  uncomment the two lines below and add your email address if you want to receive an email when you get a new message
$mailline = "a message by " . $name . " @ " . date('Y-m-d H:i', $time) . "\n" . $url .  "\n\n" . $_POST['messagepost'];
mail('EMAIL', 'bbs entry', $mailline);

  header('Location:./');
  $file = fopen($data, 'a');
  if (!fwrite($file, $line)) {
   $error = '<div class="mssg">SEVERSIDE ERROR</div>';
  }
  fclose($file);
  unset($_POST);
 } else {
  $error = '<div class="mssg">ERROR BY LACK OF NAME, TITLE OR MESSAGE</div>';
 }
}

?>

<style>

.verified:after{
    content: url(VERIFICATION ICON HERE);
    position: relative;
    bottom: -10px;
}

label{
 font-size: 17px;
 }

 .reply-button {
  font-size: 18px;
}

button:hover {
  cursor: pointer;
}

.small{
  background-color: rgba(255,255,255,0.4);
  font-size: 13px;
  text-align: left;
  }

a{
 font-size: inherit!important;
 color: inherit!important;
 }

.titletext{
  background-color: rgba(255,255,255,0.4);
  font-size: 30px;
  text-align: left;
  }

  .nametext{
  font-size: 23px;
  text-align: left;
  }

  .desc{
  width: 850px;
  background-color: rgba(255,255,255,0.4);
  font-size: 20px;
  text-align: left;
  margin: auto;
  }

  h2{
  background-color: rgba(255,255,255,0.4);
  font-size: 80px;
  text-align: center;
  margin: 10px;
  }

.mssg{
  width: 830px;
  min-height: 100px;
  display: block;
  height: fit-content;
  margin-top: -10px!important;
  margin: 30px auto;
  border: black dotted 2px;
  padding-left: 10px;
  height: fit-content;
  background-color: rgba(255,255,255,0.4);
  font-size: 17px;
  text-align: left;
  }

.mssgreply{
  width: 760px;
  margin-left: 100px!important;
  min-height: 50px;
  display: block;
  height: fit-content;
  margin-top: -20px!important;
  margin-bottom: 30px!important;
  margin: 0px auto;
  border: black dotted 2px;
  padding-left: 10px;
  height: fit-content;
  background-color: rgba(255,255,255,0.4);
  font-size: 17px;
  text-align: left;
  }

  .entryform{
  width: 830px;
  display: block;
  height: fit-content;
  margin: 10px auto 30px auto;
  border-radius: 5px;
  border: black dotted 2px;
  padding-left: 10px;
  height: fit-content;
  background-color: rgba(255,255,255,0.4);
  }

  .replypack{
  margin-top: -20px;
  margin-bottom: 30px;
  }
  
  details{
  margin-top: -30px;
  margin-bottom: 30px;
  }

  summary{
      margin-left: 30px;
      font-size: 20px;
      text-align: left;
  }

  summary::after {
  content: '(click to view)';
  font-size: 20px;
  text-align: left;
}

details[open] summary:after {
  content: "";
}

.container{
  width: 1000px;
  height: fit-content;
  padding: auto;
  margin: auto;
  display: flex!important;
  }

#bbscontainer {
 width: 900px;
 padding: 10px auto;
 padding-bottom: 10px!important;
 margin: auto!important;
 }
</style>
</head><body>

<div class="container">

<div id="bbscontainer" class="panel">

<h2>BBS</h2>

<p class="desc">YOUR DESCRIPTION HERE</p>

<form class="entryform" action="./#message" method="post" id="t">
 <table style="width:100%; text-align:center">
  <tr>
   <td>
    <label id="message">MESSAGE<br>
    <textarea name="messagepost" style="width:500px; height:300px" maxlength="3000"><? if (isset($_POST['userpost'])) echo $_POST['messagepost']; ?></textarea></label>
   </td>
   <td>
    <label>NAME<br>
    <input type="text" name="userpost" maxlength="100" size="10"<? if (isset($_POST['userpost'])) echo 'value="' . $_POST['userpost'] . '"'; ?>></label><p>
    <label>TITLE<br>
    <input type="text" maxlength="100" name="titlepost" size="10"<? if (isset($_POST['userpost'])) echo 'value="' . $_POST['titlepost'] . '"'; ?>><br><p>
    <label>WEBSITE<span class="small">(IF YOU HAVE ONE)</span><br>
    <input type="text" maxlength="100" name="urlpost" size="10"<? if (isset($_POST['userpost'])) echo 'value="' . $_POST['urlpost'] . '"'; ?>><br>
    <span class="small"><i>NOT</i> YOUR EMAIL</span></label><p>
    <label>IMAGE URL<span class="small">(IF YOU HAVE ONE)</span><br>
    <input type="text" maxlength="100" name="imagepost" size="10"<? if (isset($_POST['userpost'])) echo 'value="' . $_POST['imagepost'] . '"'; ?>><br><p>
     <label>REPLY ID<span class="small">(IF YOU'RE REPLYING TO SOMEONE)</span><br>
    <input type="text" maxlength="100" name="replypost" size="10"<? if (isset($_POST['userpost'])) echo 'value="' . $_POST['replypost'] . '"'; ?>><br><p>
    <input type="submit" name="submit" value="POST" style="margin-top: 0px; margin-bottom: 10px;">
    <label style="position:absolute; left:-5000px">anti-spam field, do not fill<br><input type="text" name="email" style="position:absolute; left:-5000px" size="10"<? if (isset($_POST['email'])) echo 'value="' . $_POST['email'] . '"'; ?>></label>
   </td>
  </tr>
 </table>
</form>



<?php
if ($error !== false): echo $error;
endif;

if (!empty($contents)) {

    $replies = [];

    foreach ($posts as $post) {
        if ($post['replyidnum'] !== 'null') {
            $replies[$post['replyidnum']][] = $post;
        }
    }

    $posts = array_reverse($posts);

    function displayReplies($postId, $replies, $posts) {

        if (isset($replies[$postId])) {
            usort($replies[$postId], function ($a, $b) {
                return strtotime($a['time']) - strtotime($b['time']);
            });

            foreach ($replies[$postId] as $reply) {

                $parentTitle = '';

                if ($reply['replyidnum'] !== 'null') {
                    foreach ($posts as $parentPost) {
                        if ($parentPost['idnum'] == $reply['replyidnum']) {
                            $parentTitle = $parentPost['title'];
                            break;
                        }
                    }
                }

                echo '<div class="mssgreply">
                        <div>
                            <div><b class="titletext">' . $reply['title'] . 
                                ($reply['replyidnum'] !== 'null' ? '<span class="titletext" style="font-size: 18px;"> (Re: ' . $parentTitle . ')</span>' : '') . 
                            '</b></div>
                            <div class="small">
                                <span class="nametext" style="font-size: 19px!important;">by <b class="nametext">' . $reply['user'] . '</b></span> (' . $reply['time'] . ')
                            </div>
                        </div>
                        ' . stripslashes($reply['message']) . '<p><img src="' . stripslashes($reply['image']) . '"></p>
                        <p class="small">ID NO: ' . $reply['idnum'] . ' <button class="reply-button" data-id="' . $reply['idnum'] . '">REPLY</button></p>
                    </div>';


                displayReplies($reply['idnum'], $replies, $posts);
            }
        }
    }

    foreach ($posts as $post) {
        if ($post['replyidnum'] == 'null') {
            echo '<div class="mssg">
                    <div>
                        <div><b class="titletext">' . $post['title'] . '</b></div>
                        <div class="small">
                            <span class="nametext" style="font-size: 19px!important;">by <b class="nametext">' . $post['user'] . '</b></span> (' . $post['time'] . ')
                        </div>
                    </div>
                    ' . stripslashes($post['message']) . '<p><img src="' . stripslashes($post['image']) . '"></p>
                    <p class="small">ID NO: ' . $post['idnum'] . ' <button class="reply-button" data-id="' . $post['idnum'] . '">REPLY</button></p>
                </div>';

            if (isset($replies[$post['idnum']])) {
                echo '<details>
                        <summary>REPLIES</summary>
                        <div class="replypack">';
                
                displayReplies($post['idnum'], $replies, $posts);

                echo '</div>
                    </details>';
            }
        }
    }

} else {
    echo '<div class="mssg">SERVERSIDE ERROR</div>';
}
?>

<script>
document.addEventListener('DOMContentLoaded', function() {

    if (window.location.hash) {
        const postId = window.location.hash.substring(1);
        const targetPost = document.getElementById(postId);
        if (targetPost) {
            targetPost.scrollIntoView({ behavior: 'smooth' });
        }
    }

    document.querySelectorAll('.reply-button').forEach(button => {
        button.addEventListener('click', function() {
            const postId = this.getAttribute('data-id');
            document.querySelector('input[name="replypost"]').value = postId;
            document.getElementById('t').scrollIntoView({ behavior: 'smooth' });
        });
    });
});


document.querySelector('form').addEventListener('submit', function() {
    const replyId = document.querySelector('input[name="replypost"]').value;
    if (replyId) {
        window.location.hash = 'post-' + replyId;
    }
});
</script>


</div>
</div>
</body></html>

Do keep in mind, this is PHP so it'll only work on dynamic web hosts. So you can't host this code using Neocities or anything like this because it won't work. For free dynamic web hosts, I'm using Infinityfree at the moment. But it doesn't allow NSFW content so I'm looking for another host rn.

I originally made this for my own personal BBS system, so fans of my music could chat and stuff but I felt like it was too good to just keep to myself lol

To use this code you need to paste it in an index.php file and you must create a database .txt file and ensure that the directories in this part of the code links to that data file, wherever it may be and whatever is may be called:
Code
$data = 'data.txt';
In this case, it's just called data.txt and is in the same folder as the php file.

I don't recommend having a login or username and password system as data in this code is stored in plaintext and unless you have a .htaccess file with rules that deny client-side access in a specialized folder where your data.txt file is, you risk your users' info being found. But even if you aren't going to, I still strongly recommend storing and protecting your database in this way.

Here are all the features you have with this BBS:
  • Messages with a name with a site link, a title, a unique generated ID and  an optional image embed
  • Special roles and verification using secret codes that cannot be viewed by the client-side
  • Reply to messages by manually inputing reply-target's ID number or by clicking the reply button to autofill it
  • Replies are stored in a neat details tag that can be expanded and collapsed
  • Primitive anti-spam filter by a hidden form field called "email address" that only bots can see that will not post a message if it's filled

If you do not intend to use special roles in your BBS, please replace the code with the comment above it "no link" with this:
Code
//no link
if (!empty($url)) {
   $user = '<a href="http://' . $url . '" target="_blank">' . $name . '</a>';
  }
   else {
   $user = $name;
  }

Here's a working instance for example! But if you manage to find my personal instance with all my branding and design, please do not comment on it as I still want to edit it and change a little first.

And I think that should be it for all the info I need to tell you about the code before you use it.

Have fun making your own little community :)
« Last Edit: March 08, 2025 @830.56 by angelhanachi » Logged

BE KIND TO PEOPLE WHO TRY TO PISS YOU OFF

SCARE THE SHIT OUTTA THEM NOW
Pages: [1] Print 
« previous next »
 

Vaguely similar topics! (3)

GUIDE: Melon's Simple X3D World Tutorial

Started by MelooonBoard ♺ ∙ Web Crafting Materials

Replies: 5
Views: 5293
Last post February 17, 2022 @637.75
by demonologi
Deltarune Chapter 2 and The Goner Code

Started by DoctorScreechBoard ♖ ∙ Video Games

Replies: 0
Views: 3982
Last post December 03, 2021 @256.40
by DoctorScreech
GUIDE: How to fix links on a frame site! - MK Frame-Link System

Started by MelooonBoard ✁ ∙ Web Crafting

Replies: 11
Views: 12254
Last post February 14, 2025 @191.34
by bingus_baby

Melonking.Net © Always and ever was! SMF 2.0.19 | SMF © 2021 | Privacy Notice | ~ Send Feedback ~ Forum Guide | Rules | RSS | WAP | Mobile


MelonLand Badges and Other Melon Sites!

MelonLand Project! Visit the MelonLand Forum! Support the Forum
Visit Melonking.Net! Visit the Gif Gallery! Pixel Sea TamaNOTchi