Show toolbar

2014年5月2日 星期五

A Message Board Homework

標題:留言板作業
PHP (index.php):
<?php
/**************************************************
 File:index.php
 Name:首頁
 Explain:首頁功能
****************************************By QQBoxy*/
require('session.php');
require('database.php');
require('common.php');
$output = "";
$p = !empty($_GET['p']) ? $_GET['p'] : 'signin';
$main = new main();
$output .= $main->htmlHeader();
switch($p) {
    case 'install': //安裝,第一次可以把註解拿掉用來安裝,之後請把註解補回去。
        //$output .= $main->install();
        break;
    case 'signin': //登入
        $output .= $main->signin();
        break;
    case 'signin_jump': //登入跳轉
        $output .= $main->signin_jump();
        break;
    case 'signup': //註冊
        $output .= $main->signup();
        break;
    case 'signup_jump': //註冊跳轉
        $output .= $main->signup_jump();
        break;
    case 'logout': //登出跳轉
        $output .= $main->logout_jump();
        break;
    case 'chatroom': //聊天室
        $output .= $main->chatroom();
        break;
    case 'profile': //聊天室
        $output .= $main->profile();
        break;
    default:
        $output .= $main->signin();
        break;
}
$output .= $main->htmlFooter();
echo $output;
?>

PHP (common.php):
<?php
/**************************************************
 File:common.php
 Name:功能函式
 Explain:實現功能函式
****************************************By QQBoxy*/
class main {
    //安裝
    public function install() {
        $sql = new sql();
        $sql->create();
        return "Done.";
    }
    //登入表單
    public function signin() {
        $output = <<< EOT
<section>
    <div class="msgbox">
        <h1>Sign in</h1>
        or <a href="index.php?p=signup">create account</a><br />
        <form action="index.php?p=signin_jump" method="post">
            <input class="inputbox" type="text" name="name" placeholder="Name" /><br />
            <input class="inputbox" type="password" name="password" placeholder="Password" /><br />
            <input class="button" type="submit" value="Sign in" />
        </form>
    </div>
</section>
EOT;
        return $output;
    }
    //登入跳轉
    public function signin_jump() {
        $output = <<< EOT
<section>
    <div class="msgbox">

EOT;
        $name     = !empty($_POST['name']) ? $_POST['name'] : null;
        $password = !empty($_POST['password']) ? $_POST['password'] : null;
        if($name && $password) {
            $sql = new sql();
            $result = $sql->signin($name);
            if($password == $result['password']) { //登入成功
                $session = new session();
                $session->login();
                $_SESSION['uid']   = $result['uid'];
                $_SESSION['name']  = $result['name'];
                $user = $sql->getuser($result['uid']); //取得使用者資料
                $_SESSION['email'] = $user['email'];
                $output .= <<< EOT
        <h1>Successful</h1>
        <span class="welldone">
            Done.
        </span>
        <br />
        <a href="index.php?p=chatroom"><button class="button">Enter chatroom</button></a>
EOT;
            } else { //登入失敗 - 密碼錯誤
                $output .= <<< EOT
        <h1>Error</h1>
        <span class="warning">
            Fail connection, your password is incorrect.
        </span>
        <br />
        <a href="index.php?p=signin"><button class="button">Back to sign in</button></a>
EOT;
            }
        } else { //登入失敗 - 資訊不足
            $output .= <<< EOT
        <h1>Error</h1>
        <span class="warning">
            Fail connection, your account or password is invalid.
        </span>
        <br />
        <a href="index.php?p=signin"><button class="button">Back to sign in</button></a>
EOT;
        }
        $output .= <<< EOT

    </div>
</section>
EOT;
        return $output;
    }
    //註冊表單
    public function signup() {
        $output = <<< EOT
<section>
    <div class="msgbox">
        <h1>Create account</h1>
        or <a href="index.php?p=signin">sign in</a><br />
        <form action="index.php?p=signup_jump" method="post">
            <input class="inputbox" type="text" name="name" placeholder="Name" /><br />
            <input class="inputbox" type="password" name="password" placeholder="Password" /><br />
            <input class="inputbox" type="text" name="email" placeholder="Email address" /><br />
            <input class="button" type="submit" value="Create account" />
        </form>
    </div>
</section>
EOT;
        return $output;
    }
    //註冊跳轉
    public function signup_jump() {
        $output = <<< EOT
<section>
    <div class="msgbox">

EOT;
        $name     = !empty($_POST['name']) ? $_POST['name'] : null;
        $password = !empty($_POST['password']) ? $_POST['password'] : null;
        $email    = !empty($_POST['email']) ? $_POST['email'] : null;
        if($name && $password && $email) { //註冊成功
            $sql = new sql();
            $sql->signup($name, $password, $email);
            $output .= <<< EOT
        <h1>Successful</h1>
        <span class="welldone">Well Done.</span>
        <br />
        <a href="index.php?p=signin"><button class="button">Back to sign in</button></a>
EOT;
        } else { //註冊失敗 - 資訊不足
            $output .= <<< EOT
        <h1>Error</h1>
        <span class="warning">
            Information incorrect, your account, password or email is not allowed.
        </span>
        <br />
        <a href="index.php?p=signup"><button class="button">Back to create account</button></a>
EOT;
        }
        $output .= <<< EOT

    </div>
</section>
EOT;
        return $output;
    }
    //登出跳轉
    public function logout_jump() {
        $session = new session();
        $session->logout();
        $output = <<< EOT
<section>
    <div class="msgbox">
        <h1>Logout</h1>
        <span class="welldone">
            You have been logged out successfully.
        </span>
        <br />
        <a href="index.php?p=signin"><button class="button">Back to sign in</button></a>
    </div>
</section>

EOT;
        return $output;
    }
    //文章處理
    protected function postContent($content) {
        $content = str_replace("<", "<", $content);
        $content = str_replace(">", ">", $content);
        $content = str_replace("\r\n", "<br />", $content);
        return $content;
    }
    //聊天室檢視
    public function chatroom() {
        $output = "";
        $session = new session();
        if(!$session->check()) { //檢查聊天室權限
            $output .= <<< EOT
<section>
    <div class="msgbox">
        <h1>Error</h1>
        <span class="warning">
            You don’t have permission to access on this page.
        </span>
        <br />
        <a href="index.php?p=signin"><button class="button">Back to sign in</button></a>
    </div>
</section>

EOT;
            return $output;
        }
        //聊天室方法
        $sql = new sql();
        $m = !empty($_POST['m']) ? $_POST['m'] : null; //方法
        $content = !empty($_POST['content']) ? $_POST['content'] : null;
        switch($m) {
            case 'newpost':
                $sql->newpost($_SESSION['uid'], false, $content);
                break;
            case 'reply':
                $pid = !empty($_POST['pid']) ? $_POST['pid'] : null;
                $sql->newpost($_SESSION['uid'], $pid, $content);
                break;
            case 'like':
                $pid = !empty($_POST['pid']) ? $_POST['pid'] : null;
                if(!$sql->getlike($_SESSION['uid'], $pid)) { //檢查是否已 Like
                    $sql->newlike($_SESSION['uid'], $pid);
                }
                break;
            case 'profile':
                $name     = !empty($_POST['name']) ? $_POST['name'] : null;
                $password = !empty($_POST['password']) ? $_POST['password'] : null;
                $email    = !empty($_POST['email']) ? $_POST['email'] : null;
                if($password && $email) {
                    $sql->userupdate($_SESSION['name'], $password, $email);
                }
                break;
            default:
                break;
        }
        $output .= <<< EOT
<nav>
    <div class="rightbar">
        <a href="index.php?p=profile">{$_SESSION['name']}</a> | <a href="index.php?p=logout">Logout</a>
    </div>
    <div>Posts</div>
</nav>
<section>
    <form action="index.php?p=chatroom" method="post">
        <input type="hidden" name="m" value="newpost" />
        <textarea class="postarea" name="content" cols="40" rows="2" placeholder="Write something..."></textarea>
        <input class="button" type="submit" value="Post!" />
    </form>
EOT;
        //文章模式
        $posts = $sql->getposts(false); //取得發文資料
        foreach($posts as $post) {
            $user = $sql->getuser($post['uid']); //取得發文者的資訊
            $dis = ($sql->getlike($_SESSION['uid'], $post['pid']))?" disabled=\"disabled\"":""; //禁用 Like
            $output .= <<< EOT
    <div class="postheading">{$user['name']}</div>
    <div class="postgroup">
        <div class="post level1">
            <div class="postcontent">{$this->postContent($post['content'])}</div>
        </div>
        <div class="postlike">
            <form action="index.php?p=chatroom" method="post">
                <input type="hidden" name="m" value="like" />
                <input type="hidden" name="pid" value="{$post['pid']}" />
                <span class="postinfo"> – </span>
                <input type="submit" value="like {$sql->getlikesnum($post['pid'])}"{$dis} />
            </form>
        </div>
EOT;
            //回覆模式
            $replies = $sql->getposts($post['pid']); //取得回覆資料
            foreach($replies as $reply) {
                $user = $sql->getuser($reply['uid']); //取得回覆者的資訊
                $dis = ($sql->getlike($_SESSION['uid'], $reply['pid']))?" disabled=\"disabled\"":""; //禁用 Like
                $output .= <<< EOT
        <div class="post level2">
            <div class="postcontent">{$this->postContent($reply['content'])}</div>
            <div class="postlike">
                <form action="index.php?p=chatroom" method="post">
                    <input type="hidden" name="m" value="like" />
                    <input type="hidden" name="pid" value="{$reply['pid']}" />
                    <span class="postinfo"> – {$user['name']}</span>
                    <input type="submit" value="like {$sql->getlikesnum($reply['pid'])}"{$dis} />
                </form>
            </div>
        </div>
EOT;
            }
            //回覆模式 END
            $output .= <<< EOT
        <div>
            <form action="index.php?p=chatroom" method="post">
                <input type="hidden" name="m" value="reply" />
                <input type="hidden" name="pid" value="{$post['pid']}" />
                <input class="comment" name="content" />
                <input class="commentbutton" type="submit" value="comment" />
            </form>
        </div>
    </div>
EOT;
        }
        $output .= <<< EOT

</section>
EOT;
        return $output;
    }
    //個人資料表單
    public function profile() {
        $session = new session();
        if(!$session->check()) { //檢查權限
            $output .= <<< EOT
<section>
    <div class="msgbox">
        <h1>Error</h1>
        <span class="warning">
            You don’t have permission to access on this page.
        </span>
        <br />
        <a href="index.php?p=signin"><button class="button">Back to sign in</button></a>
    </div>
</section>

EOT;
        }
        $output = <<< EOT
<section>
    <div class="msgbox">
        <h1>Profile</h1>
        or <a href="index.php?p=signin">sign in</a><br />
        <form action="index.php?p=chatroom" method="post">
            <input type="hidden" name="m" value="profile" />
            <input class="inputbox" type="text" name="name" value="{$_SESSION['name']}" disabled="disabled" /><br />
            <input class="inputbox" type="password" name="password" placeholder="Password" /><br />
            <input class="inputbox" type="text" name="email" value="{$_SESSION['email']}" /><br />
            <input class="button" type="submit" value="Update" />
            <input class="cancelbutton" type="button" onclick="javascript:location.href='index.php?p=chatroom'" value="Cancel" />
        </form>
    </div>
</section>
EOT;
        return $output;
    }
    //HTML頁標頭
    public function htmlHeader() {
        $output = <<< EOT
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh-TW" xml:lang="zh-TW">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>PHPChatBoxy</title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<article>

EOT;
        return $output;
    }
    //HTML頁尾
    public function htmlFooter() {
        $output = <<< EOT

</article>
</body>
</html>
EOT;
        return $output;
    }
}
?>

PHP (database.php):
<?php
/**************************************************
 File:database.php
 Name:資料庫
 Explain:資料庫CRUD功能
****************************************By QQBoxy*/
class sql {
    protected $con;
    //連接SQL
    protected function connect() {
        $account = 'YOUR_ACCOUNT'; //資料庫帳號
        $password = 'YOUR_PASSWORD'; //資料庫密碼
        $database = 'YOUR_DATABASE'; //資料庫名稱
        $this->con = mysqli_connect('localhost', $account, $password, $database, 3306);
        if(!$this->con) {
            die('SQL connect error: '.mysqli_connect_error());
        }
        mysqli_query($this->con, 'SET NAMES utf8');
    }
    //斷開SQL
    protected function close() {
        mysqli_close($this->con);
    }
    //建立資料表
    public function create() {
        $this->connect();
        //使用者
        mysqli_query($this->con,
            "CREATE TABLE persons (
                uid INT(11) NOT NULL AUTO_INCREMENT,
                name VARCHAR(30) NOT NULL,
                password VARCHAR(30) NOT NULL,
                email VARCHAR(50) NOT NULL,
                PRIMARY KEY (uid),
                UNIQUE KEY (name, email)
            )"
        );
        //文章
        mysqli_query($this->con,
            "CREATE TABLE posts (
                pid INT(11) NOT NULL AUTO_INCREMENT,
                uid INT(11) NOT NULL,
                quote INT(11),
                content TEXT,
                PRIMARY KEY (pid)
            )"
        );
        //喜歡
        mysqli_query($this->con,
            "CREATE TABLE likes (
                lid INT(11) NOT NULL AUTO_INCREMENT,
                uid INT(11) NOT NULL,
                pid INT(11) NOT NULL,
                PRIMARY KEY (lid)
            )"
        );
        $this->close();
    }
    //使用者登入
    public function signin($name) {
        $this->connect();
        $result = mysqli_query($this->con, "SELECT * FROM persons WHERE name='{$name}'");
        $row = mysqli_fetch_array($result);
        $this->close();
        return $row;
    }
    //使用者註冊
    public function signup($name, $password, $email) {
        $this->connect();
        mysqli_query($this->con, "INSERT INTO persons (name, password, email) VALUES ('{$name}', '{$password}', '{$email}')");
        $this->close();
    }
    //使用者更新
    public function userupdate($name, $password, $email) {
        $this->connect();
        mysqli_query($this->con, "UPDATE persons SET password='{$password}', email='{$email}' WHERE name='{$name}'");
        $this->close();
    }
    //查詢使用者
    public function getuser($uid) {
        $this->connect();
        $result = mysqli_query($this->con, "SELECT * FROM persons WHERE uid='{$uid}'");
        $row = mysqli_fetch_array($result);
        $this->close();
        return $row;
    }
    //新文章
    public function newpost($uid, $quote, $content) {
        $this->connect();
        if($quote) { //已引用,回覆模式
            mysqli_query($this->con, "INSERT INTO posts (uid, quote, content) VALUES ('{$uid}', '{$quote}', '{$content}')");
        } else { //未引用,文章模式
            mysqli_query($this->con, "INSERT INTO posts (uid, content) VALUES ('{$uid}', '{$content}')");
        }
        $this->close();
    }
    //查詢文章
    public function getposts($quote) {
        $arr = array();
        $this->connect();
        if($quote) { //已引用,回覆模式
            //$result = mysqli_query($this->con, "SELECT * FROM posts WHERE quote='{$quote}' ORDER BY pid DESC LIMIT 0, 10");
            $result = mysqli_query($this->con, "SELECT * FROM posts WHERE quote='{$quote}' ORDER BY pid DESC");
        } else { //未引用,文章模式
            //$result = mysqli_query($this->con, "SELECT * FROM posts WHERE quote IS NULL ORDER BY pid DESC LIMIT 0, 10");
            $result = mysqli_query($this->con, "SELECT * FROM posts WHERE quote IS NULL ORDER BY pid DESC");
        }
        while($row = mysqli_fetch_array($result)) {
            array_push($arr, $row);
        }
        $this->close();
        return $arr;
    }
    //新喜歡
    public function newlike($uid, $pid) {
        $this->connect();
        mysqli_query($this->con, "INSERT INTO likes (uid, pid) VALUES ('{$uid}', '{$pid}')");
        $this->close();
    }
    //查詢喜歡數
    public function getlikesnum($pid) {
        $num = 0;
        $this->connect();
        $result = mysqli_query($this->con, "SELECT * FROM likes WHERE pid='{$pid}'");
        while($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
            $num += 1;
        }
        $this->close();
        return $num;
    }
    //查詢喜歡
    public function getlike($uid, $pid) {
        $islike = true; //已 Like,不能再 Like
        $this->connect();
        $result = mysqli_query($this->con, "SELECT * FROM likes WHERE uid='{$uid}' AND pid='{$pid}'");
        if(mysqli_fetch_array($result, MYSQLI_ASSOC)) {
            $islike = true;
        } else {
            $islike = false;
        }
        $this->close();
        return $islike;
    }
}
?>

PHP (session.php):
<?php
/**************************************************
 File:session.php
 Name:Session
 Explain:用於實現SESSION功能
****************************************By QQBoxy*/
session_start();
class session {
    function refresh() { //刷新登入狀態
        $_SESSION['start'] = time();
        $_SESSION['expire'] = $_SESSION['start'] + 30 * 60; //設定30分鐘
        //$_SESSION['expire'] = time() + 5; //Test
    }
    function login() {
        $this->refresh();
    }
    function check() { //檢查登入狀態
        $now = time();
        if(!empty($_SESSION['start']) && $_SESSION['expire'] > $now) { //登入狀態未過期
            $this->refresh();
            return true;
        } else if(!empty($_SESSION['start'])) { //登入狀態已過期
            session_destroy();
        }
        return false;
    }
    function logout() {
        session_destroy();
    }
}
?>

CSS (style.css):
body {
    margin: 0 auto 0px;
}
h1 {
    font-weight: bold;
}
a {
    color: #4096ee;
}
nav {
    margin: 0 auto 0px;
    padding: 3px 10px;
    box-shadow: 0px 10px 10px -10px gray;
}
nav div.rightbar {
    float: right;
}
section {
    margin: 0 auto 0px;
    padding: 10px 10px;
}
.msgbox {
    position: absolute;
    left: 50%;
    top: 20%;
    width: 300px;
    margin-left: -170px;
    padding: 20px;
    float: left;
    border-radius: 10px;
    -moz-border-radius: 10px;
    -webkit-border-radius: 10px;
    box-shadow: 0px 0px 10px gray;
}
.inputbox {
    margin: 7px 1px;
    padding-left: 5px;
    width: 200px;
    height: 25px;
}
.button {
    margin: 7px 0;
    padding: 10px;
    color: #fff;
    background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzdhYmNmZiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjQ0JSIgc3RvcC1jb2xvcj0iIzYwYWJmOCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiM0MDk2ZWUiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
    border-width: 1px;
    border-radius: 7px;
    -moz-border-radius: 7px;
    -webkit-border-radius: 7px;
}
.warning {
    color: #ff5c5c;
}
.welldone {
    color: #a5c956;
}
.postgroup {
    margin: 0px;
    border-left: 5px solid #eee;
}
.postheading {
    margin-top: 30px;
    font-weight: bold;
}
.postarea {
    margin: 0 0 -15px 0;
}
.post {
    margin-top: 10px;
    padding: 5px 10px;
    position: relative;
    overflow: hidden;
}
.level1 {
    background-color: #f5f5f5;
    margin-left: 20px;
}
.level2 {
    border-left: 5px solid #eee;
    margin-left: 20px;
}
.postlike {
    margin-left: 20px;
}
.postlike input {
    border: 1px solid gray;
    background-color: #fff;
    border-radius: 5px;
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
}
.postinfo {
    color: gray;
}
.comment {
    margin: 0px 0px 0px 20px;
    width: 250px;
    height: 22px;
    border-radius: 5px 0px 0px 5px;
    -moz-border-radius: 5px 0px 0px 5px;
    -webkit-border-radius: 5px 0px 0px 5px;
}
.commentbutton {
    margin: 10px 0px 0px -5px;
    padding: 5px;
    height: 28px;
    color: #fff;
    background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzdhYmNmZiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjQ0JSIgc3RvcC1jb2xvcj0iIzYwYWJmOCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiM0MDk2ZWUiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
    border-width: 1px;
    border-radius: 0px 5px 5px 0px;
    -moz-border-radius: 0px 5px 5px 0px;
    -webkit-border-radius: 0px 5px 5px 0px;
}
.cancelbutton {
    margin: 7px 0;
    padding: 10px;
    color: gray;
    background-color: #fff;
    border-width: 1px;
    border-radius: 7px;
    -moz-border-radius: 7px;
    -webkit-border-radius: 7px;
}

說明:
就只是一份學校作業,沒有太多的安全性設計,希望各位不要拿來實戰阿!!!

沒有留言:

張貼留言