From d50b8640826306ddeb39d706cb5830147db619fc Mon Sep 17 00:00:00 2001 From: Andreas Date: Thu, 12 Sep 2019 12:02:17 +0200 Subject: [PATCH] changed files to more updated version --- .gitattributes | 2 - .gitignore | 5 - .vscode/launch.json | 24 -- dev_mvc/.buildpath | 5 + dev_mvc/.project | 22 ++ dev_mvc/controller/ActionHandler.php | 16 - dev_mvc/controller/AssetHandler.php | 12 - dev_mvc/controller/Database.php | 286 ------------------ dev_mvc/controller/HUtils.php | 17 -- dev_mvc/controller/MVCController.php | 90 ++++++ dev_mvc/controller/UserSession.php | 238 ++++++++------- dev_mvc/controller/data/Reply.php | 38 --- dev_mvc/controller/data/Thread.php | 17 -- dev_mvc/controller/data/User.php | 33 -- dev_mvc/controller/db/DBBoard.php | 12 + dev_mvc/controller/db/DBReply.php | 39 +++ dev_mvc/controller/db/DBThread.php | 37 +++ dev_mvc/controller/db/DBUser.php | 134 ++++++++ dev_mvc/controller/db/Database.php | 172 +++++++++++ dev_mvc/index.php | 36 +-- dev_mvc/model/actions/model_create_reply.php | 15 + dev_mvc/model/actions/model_create_thread.php | 14 + dev_mvc/model/actions/model_destroy.php | 4 - .../model/{ => actions}/model_do_register.php | 15 +- dev_mvc/model/actions/model_empty.php | 3 + dev_mvc/model/actions/model_login.php | 59 ++++ dev_mvc/model/actions/model_signout.php | 2 + dev_mvc/model/classes/Reply.php | 0 dev_mvc/model/classes/Thread.php | 19 -- dev_mvc/model/classes/User.php | 0 dev_mvc/model/forum/Board.php | 13 + dev_mvc/model/forum/Reply.php | 102 +++++++ dev_mvc/model/forum/Thread.php | 143 +++++++++ dev_mvc/model/forum/User.php | 138 +++++++++ dev_mvc/model/model_create_topic.php | 11 - dev_mvc/model/model_do_login.php | 45 --- dev_mvc/tests/createdb/index.php | 79 ----- dev_mvc/tests/phpinfo/index.php | 4 - dev_mvc/view/content_pagetemplate.php | 25 ++ dev_mvc/view/css/main.css | 123 +++++++- dev_mvc/view/img/logo.png | Bin 58147 -> 0 bytes dev_mvc/view/pagecontent/content_404.php | 3 - .../pagecontent/content_attempt_login.php | 7 - .../pagecontent/content_attempt_logout.php | 3 - .../pagecontent/content_attempt_register.php | 3 - .../view/pagecontent/content_create_topic.php | 4 - dev_mvc/view/pagecontent/content_destroy.php | 3 - dev_mvc/view/pagecontent/content_header.php | 7 - dev_mvc/view/pagecontent/content_index.php | 3 - dev_mvc/view/pagecontent/content_login.php | 11 - dev_mvc/view/pagecontent/content_page.php | 35 --- dev_mvc/view/pagecontent/content_register.php | 12 - .../view/pagecontent/content_showboards.php | 8 - .../view/pagecontent/content_showtopics.php | 17 -- dev_mvc/view/pagecontent/content_verify.php | 16 - .../header/content_header_signedin.php | 7 - .../header/content_header_signedout.php | 7 - .../login/content_login_succesful.php | 3 - .../login/content_login_unsuccesful.php | 3 - .../view/pagecontent/modules/topbar_login.php | 8 - dev_mvc/view/webcontent/content_404.php | 6 + .../webcontent/content_account_inactive.php | 5 + dev_mvc/view/webcontent/content_boards.php | 7 + .../view/webcontent/content_createreply.php | 6 + .../view/webcontent/content_createthread.php | 7 + .../view/webcontent/content_error_login.php | 4 + dev_mvc/view/webcontent/content_header.php | 9 + dev_mvc/view/webcontent/content_home.php | 3 + dev_mvc/view/webcontent/content_register.php | 12 + dev_mvc/view/webcontent/content_reply.php | 1 + .../view/webcontent/content_showthread.php | 45 +++ dev_mvc/view/webcontent/content_signin.php | 6 + dev_mvc/view/webcontent/content_signout.php | 1 + dev_mvc/view/webcontent/content_verify.php | 2 + .../webcontent/header/header_signedin.php | 7 + .../webcontent/header/header_signedout.php | 8 + .../modules_boards/module_boardtable.php | 48 +++ dev_mvc/viewmodel/viewmodel_boards.php | 47 +++ dev_mvc/viewmodel/viewmodel_createreply.php | 5 + dev_mvc/viewmodel/viewmodel_home.php | 6 + dev_mvc/viewmodel/viewmodel_showthread.php | 37 +++ dev_mvc/viewmodel/viewmodel_signout.php | 5 + .../viewmodel_verify.php} | 3 +- globalvars.php | 4 - 84 files changed, 1560 insertions(+), 933 deletions(-) delete mode 100644 .gitattributes delete mode 100644 .gitignore delete mode 100644 .vscode/launch.json create mode 100644 dev_mvc/.buildpath create mode 100644 dev_mvc/.project delete mode 100644 dev_mvc/controller/ActionHandler.php delete mode 100644 dev_mvc/controller/AssetHandler.php delete mode 100644 dev_mvc/controller/Database.php create mode 100644 dev_mvc/controller/MVCController.php delete mode 100644 dev_mvc/controller/data/Reply.php delete mode 100644 dev_mvc/controller/data/Thread.php delete mode 100644 dev_mvc/controller/data/User.php create mode 100644 dev_mvc/controller/db/DBBoard.php create mode 100644 dev_mvc/controller/db/DBReply.php create mode 100644 dev_mvc/controller/db/DBThread.php create mode 100644 dev_mvc/controller/db/DBUser.php create mode 100644 dev_mvc/controller/db/Database.php create mode 100644 dev_mvc/model/actions/model_create_reply.php create mode 100644 dev_mvc/model/actions/model_create_thread.php delete mode 100644 dev_mvc/model/actions/model_destroy.php rename dev_mvc/model/{ => actions}/model_do_register.php (69%) create mode 100644 dev_mvc/model/actions/model_empty.php create mode 100644 dev_mvc/model/actions/model_login.php delete mode 100644 dev_mvc/model/classes/Reply.php delete mode 100644 dev_mvc/model/classes/Thread.php delete mode 100644 dev_mvc/model/classes/User.php create mode 100644 dev_mvc/model/forum/Board.php create mode 100644 dev_mvc/model/forum/Reply.php create mode 100644 dev_mvc/model/forum/Thread.php create mode 100644 dev_mvc/model/forum/User.php delete mode 100644 dev_mvc/model/model_create_topic.php delete mode 100644 dev_mvc/model/model_do_login.php delete mode 100644 dev_mvc/tests/createdb/index.php delete mode 100644 dev_mvc/tests/phpinfo/index.php create mode 100644 dev_mvc/view/content_pagetemplate.php delete mode 100644 dev_mvc/view/img/logo.png delete mode 100644 dev_mvc/view/pagecontent/content_404.php delete mode 100644 dev_mvc/view/pagecontent/content_attempt_login.php delete mode 100644 dev_mvc/view/pagecontent/content_attempt_logout.php delete mode 100644 dev_mvc/view/pagecontent/content_attempt_register.php delete mode 100644 dev_mvc/view/pagecontent/content_create_topic.php delete mode 100644 dev_mvc/view/pagecontent/content_destroy.php delete mode 100644 dev_mvc/view/pagecontent/content_header.php delete mode 100644 dev_mvc/view/pagecontent/content_index.php delete mode 100644 dev_mvc/view/pagecontent/content_login.php delete mode 100644 dev_mvc/view/pagecontent/content_page.php delete mode 100644 dev_mvc/view/pagecontent/content_register.php delete mode 100644 dev_mvc/view/pagecontent/content_showboards.php delete mode 100644 dev_mvc/view/pagecontent/content_showtopics.php delete mode 100644 dev_mvc/view/pagecontent/content_verify.php delete mode 100644 dev_mvc/view/pagecontent/header/content_header_signedin.php delete mode 100644 dev_mvc/view/pagecontent/header/content_header_signedout.php delete mode 100644 dev_mvc/view/pagecontent/login/content_login_succesful.php delete mode 100644 dev_mvc/view/pagecontent/login/content_login_unsuccesful.php delete mode 100644 dev_mvc/view/pagecontent/modules/topbar_login.php create mode 100644 dev_mvc/view/webcontent/content_404.php create mode 100644 dev_mvc/view/webcontent/content_account_inactive.php create mode 100644 dev_mvc/view/webcontent/content_boards.php create mode 100644 dev_mvc/view/webcontent/content_createreply.php create mode 100644 dev_mvc/view/webcontent/content_createthread.php create mode 100644 dev_mvc/view/webcontent/content_error_login.php create mode 100644 dev_mvc/view/webcontent/content_header.php create mode 100644 dev_mvc/view/webcontent/content_home.php create mode 100644 dev_mvc/view/webcontent/content_register.php create mode 100644 dev_mvc/view/webcontent/content_reply.php create mode 100644 dev_mvc/view/webcontent/content_showthread.php create mode 100644 dev_mvc/view/webcontent/content_signin.php create mode 100644 dev_mvc/view/webcontent/content_signout.php create mode 100644 dev_mvc/view/webcontent/content_verify.php create mode 100644 dev_mvc/view/webcontent/header/header_signedin.php create mode 100644 dev_mvc/view/webcontent/header/header_signedout.php create mode 100644 dev_mvc/view/webcontent/modules/modules_boards/module_boardtable.php create mode 100644 dev_mvc/viewmodel/viewmodel_boards.php create mode 100644 dev_mvc/viewmodel/viewmodel_createreply.php create mode 100644 dev_mvc/viewmodel/viewmodel_home.php create mode 100644 dev_mvc/viewmodel/viewmodel_showthread.php create mode 100644 dev_mvc/viewmodel/viewmodel_signout.php rename dev_mvc/{model/actions/model_verify.php => viewmodel/viewmodel_verify.php} (66%) delete mode 100644 globalvars.php diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index dfe0770..0000000 --- a/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -# Auto detect text files and perform LF normalization -* text=auto diff --git a/.gitignore b/.gitignore deleted file mode 100644 index e915029..0000000 --- a/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -################################################################################ -# This .gitignore file was automatically created by Microsoft(R) Visual Studio. -################################################################################ - -/.vs diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index abe5e15..0000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "Listen for XDebug", - "type": "php", - "request": "launch", - "port": 9000 - }, - { - "name": "Launch currently open script", - "type": "php", - "request": "launch", - "program": "${file}", - "cwd": "${fileDirname}", - "port": 9000 - } - ], - "php.executablePath": "C:/xampp/php/php.exe", - "php.suggest.basic": "false" -} \ No newline at end of file diff --git a/dev_mvc/.buildpath b/dev_mvc/.buildpath new file mode 100644 index 0000000..8bcb4b5 --- /dev/null +++ b/dev_mvc/.buildpath @@ -0,0 +1,5 @@ + + + + + diff --git a/dev_mvc/.project b/dev_mvc/.project new file mode 100644 index 0000000..3b1a44b --- /dev/null +++ b/dev_mvc/.project @@ -0,0 +1,22 @@ + + + dev + + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.eclipse.dltk.core.scriptbuilder + + + + + + org.eclipse.php.core.PHPNature + + diff --git a/dev_mvc/controller/ActionHandler.php b/dev_mvc/controller/ActionHandler.php deleted file mode 100644 index 56f9eb7..0000000 --- a/dev_mvc/controller/ActionHandler.php +++ /dev/null @@ -1,16 +0,0 @@ - \ No newline at end of file diff --git a/dev_mvc/controller/AssetHandler.php b/dev_mvc/controller/AssetHandler.php deleted file mode 100644 index 0718470..0000000 --- a/dev_mvc/controller/AssetHandler.php +++ /dev/null @@ -1,12 +0,0 @@ -'; - } - else{ - echo 'prepare("SELECT * FROM users where email = :email"); - //Bind parameters - $query->bindParam(':email', $email, PDO::PARAM_STR, 256); - //Voer de query uit - $query->execute(); - //Check de hoeveelheid rijen die de database returnt. - if($query->rowCount() == 0){ - //Email adres is niet in gebruik, return false - return false; - } - else{ - //Email is al in gebruik of komt meer dan een keer voor. Beide gevallen zijn een probleem dus return true. - return true; - } - } - //Controleert of de gebruikersnaam al in de database voorkomt. Returnt true indien wel. - static function checkUsedUsername($username){ - $con = Database::connectToDB(); - //Bereid query voor - $query = $con->prepare("SELECT * FROM users where username = :username"); - //Bind parameters - $query->bindParam(':username', $username, PDO::PARAM_STR, 256); - //Voer de query uit - $query->execute(); - //Check de hoeveelheid rijen die de database returnt. - if($query->rowCount() == 0){ - //Username adres is niet in gebruik, return false - return false; - } - else{ - //Username is al in gebruik of komt meer dan een keer voor. Beide gevallen zijn een probleem dus return true. - return true; - } - } - //Registreert een gebruiker. Neemt als invoer email, wachtwoord, gebruikersnaam. en email activation key. Nog niet volledig geimplementeerd - static function registerUser($email, $password, $username){ - $ip = $_SERVER['REMOTE_ADDR']; - //Initit db connection - $con = Database::connectToDB(); - //Bereid query voor - $query = $con->prepare("INSERT INTO users (username, email, password, reg_ip) VALUES (:username, :email, :password, :ip)"); - //Bind parameters - $query->bindParam(':username', $username, PDO::PARAM_STR, 256); - $query->bindParam(':email', $email, PDO::PARAM_STR, 256); - $query->bindParam(':password', $password, PDO::PARAM_STR, 256); - $query->bindParam(':ip', $ip, PDO::PARAM_STR, 256); - //Voer query uit - $query->execute(); - } - //Check of gegeven login info in de database voorkomt - static function isLoginValid($email, $password){ - //Init db connection - $con = Database::connectToDB(); - //Bereid query voor - $query = $con->prepare("SELECT * FROM users where email = :email AND password = :password"); - //Bind params - $query->bindParam(':email', $email, PDO::PARAM_STR, 256); - $query->bindParam(':password', $password, PDO::PARAM_STR, 256); - //Voer query it - $query->execute(); - //Check hoeveelheid teruggestuurde rijen - if($query->rowCount() == 1){ - //login correct (komt voor in de db) - return true; - } - else{ - //Incorrect - return false; - } - } - //Vraag gebruikers ID op doormiddel van email en pass - static function getUID($email, $password){ - //Init db connection - $con = Database::connectToDB(); - //Bereid query voor - $query = $con->prepare("SELECT id FROM users where email = :email AND password = :password"); - //Bind params - $query->bindParam(':email', $email, PDO::PARAM_STR, 256); - $query->bindParam(':password', $password, PDO::PARAM_STR, 256); - //Voer query it - $query->execute(); - //Check hoeveelheid teruggestuurde rijen - if($query->rowCount() == 1){ - //login correct, return uid - $result = $query->fetch(PDO::FETCH_COLUMN); - return $result; - } - else{ - //something went wrong, return -1 - return -1; - } - } - static function getUsername($uid){ - $con = Database::connectToDB(); - $query = $con->prepare("SELECT username FROM users where id = :uid"); - $query->bindParam(':uid', $uid, PDO::PARAM_STR, 256); - $query->execute(); - if($query->rowCount() == 1){ - //login correct, return uid - $result = $query->fetch(PDO::FETCH_COLUMN); - return $result; - } - else{ - //something went wrong, return -1 - return "db_user_invalid"; - } - } - - /*** - * ______ __ __ _____ _ _____ _______ _______ __ _______ _____ ____ _ _ - * | ____| \/ | /\ |_ _| | /\ / ____|__ __|_ _\ \ / /\|__ __|_ _/ __ \| \ | | - * | |__ | \ / | / \ | | | | / \ | | | | | | \ \ / / \ | | | || | | | \| | - * | __| | |\/| | / /\ \ | | | | / /\ \| | | | | | \ \/ / /\ \ | | | || | | | . ` | - * | |____| | | |/ ____ \ _| |_| |____ / ____ \ |____ | | _| |_ \ / ____ \| | _| || |__| | |\ | - * |______|_| |_/_/ \_\_____|______| /_/ \_\_____| |_| |_____| \/_/ \_\_| |_____\____/|_| \_| - * - * - ***/ - - //Kijk of de user activation key al bestaat in de databse. - static function doesUserActivationKeyExist($activationKey){ - $con = Database::connectToDB(); - $query = $con->prepare("SELECT * FROM email_activation_keys WHERE activationkey = :activationKey"); - $query->bindParam(':activationKey', $activationKey, PDO::PARAM_STR, 256); - $query->execute(); - if($query->rowCount() == 0){ - //bestaat nog niet - return false; - } - else{ - //bestaat al - return true; - } - } - static function registerActivationKey($users_id, $activationKey){ - $con = Database::connectToDB(); - $query = $con->prepare("INSERT INTO email_activation_keys (users_id, activationkey) VALUES (:users_id, :activationkey)"); - $query->bindParam(':users_id', $users_id); - $query->bindParam(':activationkey', $activationKey); - $query->execute(); - } - - - - //Activeer gebruiker en verwijder activation key uit de activation key tabel - static function activateUser($activationKey){ - $con = Database::connectToDb(); - $query = $con->prepare("SELECT users_id FROM email_activation_keys WHERE activationKey = :activationKey"); - $query->bindParam('activationKey', $activationKey); - $query->execute(); - $result = -1; - if($query->rowCount() == 1){ - //login correct, return uid - $result = $query->fetch(PDO::FETCH_COLUMN); - } - else{ - //activation key komt niet voor in de db, return -1 - return -1; - } - $id = $result; - $query = null; - $query = $con->prepare("UPDATE users SET active = 1 WHERE id = :id and active = 0"); - $query->bindParam(':id',$id,PDO::PARAM_INT); - $query->execute(); - } - - /*** - * _____ ______ _____ _____ _____ ____ _ _ _______ ____ _ ________ _ _ _____ - * / ____| ____|/ ____/ ____|_ _/ __ \| \ | | |__ __/ __ \| |/ / ____| \ | |/ ____| - * | (___ | |__ | (___| (___ | || | | | \| | | | | | | | ' /| |__ | \| | (___ - * \___ \| __| \___ \\___ \ | || | | | . ` | | | | | | | < | __| | . ` |\___ \ - * ____) | |____ ____) |___) |_| || |__| | |\ | | | | |__| | . \| |____| |\ |____) | - * |_____/|______|_____/_____/|_____\____/|_| \_| |_| \____/|_|\_\______|_| \_|_____/ - * - ***/ - - - static function isSessionTokenInUse($token){ - //Init db connection - $con = Database::connectToDB(); - //Bereid query voor - $query = $con->prepare("SELECT * FROM usersessions where token = :token"); - //Bind params - $query->bindParam(':token', $token, PDO::PARAM_STR, 256); - //Voer query it - $query->execute(); - //Check hoeveelheid teruggestuurde rijen - if($query->rowCount() == 0){ - return false; - } - else{ - return true; - } - } - static function registerNewSession($uid, $token, $expires){ - //Init db connection - $con = Database::connectToDB(); - //Bereid query voor - $query = $con->prepare("INSERT INTO usersessions (uid, token, expires) VALUES (:uid, :token, :expires)"); - //Bind params - $query->bindParam(':uid', $uid, PDO::PARAM_INT); - $query->bindParam(':token', $token, PDO::PARAM_STR, 256); - $query->bindParam(':expires', $expires, PDO::PARAM_STR); - //Voer query it - $query->execute(); - } - static function isSessionValid($token, $uid){ - //Init db connection - $con = Database::connectToDB(); - //Bereid query voor - $query = $con->prepare("SELECT * FROM usersessions where token = :token AND uid = :uid AND expires > NOW()"); - //Bind params - $query->bindParam(':token', $token, PDO::PARAM_STR, 256); - $query->bindParam(':uid', $uid, PDO::PARAM_STR, 256); - //Voer query it - $query->execute(); - //Check hoeveelheid teruggestuurde rijen - if($query->rowCount() == 1){ - return true; - } - else{ - return false; - } - } - static function invalidateSession($token){ - //Init db connection - $con = Database::connectToDB(); - //Bereid query voor - $query = $con->prepare("DELETE FROM usersessions WHERE token = :token"); - //Bind params - $query->bindParam(':token', $token, PDO::PARAM_STR, 256); - //Voer query it - $query->execute(); - } - static function invalidateSessionByUID($uid){ - //Init db connection - $con = Database::connectToDB(); - //Bereid query voor - $query = $con->prepare("DELETE FROM usersessions WHERE uid = :uid"); - //Bind params - $query->bindParam(':token', $uid, PDO::PARAM_INT); - //Voer query it - $query->execute(); - } - static function deleteExpiredSessions(){ - $con = Database::connectToDB(); - //Bereid query voor - $query = $con->prepare("DELETE FROM usersessions WHERE expires < NOW()"); - $query->execute(); - } - static function getSessionExpiryDate($token){ - $con = Database::connectToDB(); - $query = $con->prepare("SELECT expires FROM usersessions where token = :token"); - $query->bindParam(':token', $token, PDO::PARAM_STR, 256); - $query->execute(); - if($query->rowCount() == 1){ - //login correct, return uid - $result = $query->fetch(PDO::FETCH_COLUMN); - return $result; - } - else{ - //something went wrong, return an invalid date. - return "2000-01-01 00:00:00"; - } - } -} -?> \ No newline at end of file diff --git a/dev_mvc/controller/HUtils.php b/dev_mvc/controller/HUtils.php index 1b77853..abab026 100644 --- a/dev_mvc/controller/HUtils.php +++ b/dev_mvc/controller/HUtils.php @@ -1,7 +1,5 @@ view = "./view/webcontent/content_".$_GET['p'].".php"; + $this->viewmodel = "./viewmodel/viewmodel_".$_GET['p'].".php"; + } + else{ + $this->view = "./view/webcontent/content_home.php"; + $this->viewmodel = "./viewmodel/viewmodel_home.php"; + } + + //prepare current action model + if(isset($_POST['action'])){ + $this->model = "./model/actions/model_".$_POST['action'].".php"; + } + else if(isset($_GET['action'])){ + $this->model = "./model/actions/model_".$_GET['action'].".php"; + } + else{ + $this->model = "./model/actions/model_empty.php"; + } + } + static function getMVCController():MVCController + { + return self::$mvcController; + } + function overrideView($view_target):void + { + $this->view = "./view/webcontent/content_".$view_target.".php"; + $this->viewmodel = "./viewmodel/viewmodel_".$view_target.".php"; + $this->viewOverridden = true; + } + function executeAction():void + { + //check if action model is valid + if(file_exists($this->model)){ + //execute action model + include_once($this->model); + } + //model doesn't exist and will not be called + else{ + //debug message + echo("caught call on non-existant model file."); + } + + } + function executeViewmodel():void + { + if(file_exists($this->viewmodel)) + { + include_once($this->viewmodel); + } + } + function executeModel():void + { + $this->executeAction(); + //check if the view was overridden by action. + if($this->viewOverridden){ + //don't need to run the viewmodel twice if it was overridden by action + $this->viewOverridden = false; + } + //run viewmodel + $this->executeViewmodel(); + //run viewmodel again if overridden by viewmodel + if($this->viewOverridden) + { + $this->executeViewmodel(); + } + } + function loadView(){ + if(file_exists($this->view)){ + include_once($this->view); + } + else{ + include_once("./view/webcontent/content_404.php"); + echo("view: ".$this->view." not found."); + } + } +} +?> \ No newline at end of file diff --git a/dev_mvc/controller/UserSession.php b/dev_mvc/controller/UserSession.php index 53dc21e..6d3de70 100644 --- a/dev_mvc/controller/UserSession.php +++ b/dev_mvc/controller/UserSession.php @@ -1,121 +1,125 @@ uid = $uid; - $this->token = $token; - $this->setExpiry(); - //echo($loginSessionToken); - $_SESSION['usersession'] = $this; - setcookie('usersession', $this->token); - setcookie('uid', $this->uid); - } - public function setSessionToken($token){ - $this->token = $token; - } - public function getSessionToken(){ - return $this->token; - } - public function getFormattedExpiry(){ - return $this->expires->format('Y-m-d H:i:s'); - } - public function setExpiry(){ - $this->expires = new DateTime(); - $this->expires->modify("+ 1 hour"); - } - public static function generateToken(){ - $chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - $token = ""; - for ($i=0; $i < 32 ; $i++) { - $token .= $chars[rand(0, strlen($chars) - 1)]; - } - return $token; - } - public static function isSessionValid(){ - if(isset($_SESSION['usersession'])){ - if(!Database::isSessionValid($_SESSION['usersession']->token, $_SESSION['usersession']->uid)){ - return false; - } - if(!UserSession::isSessionExpired($_SESSION['usersession'])){ - //check if session also exists in database - return true; - } - } - else{ - if(isset($_COOKIE['usersession'])){ - $token = $_COOKIE['usersession']; - $uid = $_COOKIE['uid']; - if(Database::isSessionValid($token,$uid)){ - $session = new UserSession($uid, $token); - $session->expires = new DateTime(Database::getSessionExpiryDate($token)); - } - else{ - return false; - } - if(!UserSession::isSessionExpired($session)){ - return true; - } - } - return false; - } - } - public static function getSession() - { - return $_SESSION['usersession']; - } - public static function isSessionExpired($session){ - //session is expired - if(new DateTime() > $session->expires){ - return true; - } - //session is not expired - else{ - return false; - } - } - public static function isUserSignedIn(){ - /* - if(UserSession::isSessionValid()){ - if(!UserSession::isSessionExpired(UserSession::getSession())){ - if(Database::isSessionValid(UserSession::getSession()->token, UserSession::getSession()->uid)){ - return true; - } - - } - else{ - return false; - } - } - else{ - return false; - } - */ - //session exists, no need to do anything - if(isset($_SESSION['usersession'])){ - return true; - } - else{ - if(isset($_COOKIE['usersession'])){ - //check if the session exists in the database - if(Database::isSessionTokenInUse($_COOKIE['usersession'])){ - //check if database expiration datetime is still valid - $expirationDateTime = Database::getSessionExpiryDate($_COOKIE['usersession']); - if(new DateTime($expirationDateTime) >= new DateTime()){ - //user is signed in. Restore session - $userSession = new UserSession($_COOKIE['uid'], $_COOKIE['usersession']); - return true; - } - else{ - //remove session from the database - Database::invalidateSession($_COOKIE['usersession']); - } - } - } - } - //session either doesn't exist, doesn't exist in cookie, doesn't exist in database, or is expired in the database. - return false; - } + public $uid = -1; + public $token = "undefined"; + public $expires; + public static $session; + public function UserSession($uid, $token = "undefined"){ + $this->uid = $uid; + $this->token = $token; + $this->setExpiry(); + //echo($loginSessionToken); + $_SESSION['usersession'] = $this; + setcookie('usersession', $this->token); + setcookie('uid', $this->uid); + } + public function setSessionToken($token){ + $this->token = $token; + } + public function getSessionToken(){ + return $this->token; + } + public function getFormattedExpiry(){ + return $this->expires->format('Y-m-d H:i:s'); + } + public function setExpiry(){ + $this->expires = new DateTime(); + $this->expires->modify("+ 1 hour"); + } + public static function generateToken(){ + $chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + $token = ""; + for ($i=0; $i < 32 ; $i++) { + $token .= $chars[rand(0, strlen($chars) - 1)]; + } + return $token; + } + public static function isSessionValid(){ + if(isset($_SESSION['usersession'])){ + if(!Database::isSessionValid($_SESSION['usersession']->token, $_SESSION['usersession']->uid)){ + return false; + } + if(!UserSession::isSessionExpired($_SESSION['usersession'])){ + //check if session also exists in database + return true; + } + } + else{ + if(isset($_COOKIE['usersession'])){ + $token = $_COOKIE['usersession']; + $uid = $_COOKIE['uid']; + if(Database::isSessionValid($token,$uid)){ + $session = new UserSession($uid, $token); + $session->expires = new DateTime(Database::getSessionExpiryDate($token)); + } + else{ + return false; + } + if(!UserSession::isSessionExpired($session)){ + return true; + } + } + return false; + } + } + public static function getSession() + { + if(isset($_SESSION['usersession'])){ + return $_SESSION['usersession']; + } + } + public static function isSessionExpired($session){ + //session is expired + if(new DateTime() > $session->expires){ + return true; + } + //session is not expired + else{ + return false; + } + } + public static function isUserSignedIn(){ + /* + if(UserSession::isSessionValid()){ + if(!UserSession::isSessionExpired(UserSession::getSession())){ + if(Database::isSessionValid(UserSession::getSession()->token, UserSession::getSession()->uid)){ + return true; + } + + } + else{ + return false; + } + } + else{ + return false; + } + */ + //session exists, no need to do anything + if(isset($_SESSION['usersession'])){ + return true; + } + else{ + if(isset($_COOKIE['usersession'])){ + //check if the session exists in the database + if(Database::isSessionTokenInUse($_COOKIE['usersession'])){ + //check if database expiration datetime is still valid + $expirationDateTime = Database::getSessionExpiryDate($_COOKIE['usersession']); + if(new DateTime($expirationDateTime) >= new DateTime()){ + //user is signed in. Restore session + $userSession = new UserSession($_COOKIE['uid'], $_COOKIE['usersession']); + return true; + } + else{ + //remove session from the database + Database::invalidateSession($_COOKIE['usersession']); + } + } + } + } + //session either doesn't exist, doesn't exist in cookie, doesn't exist in database, or is expired in the database. + return false; + } } ?> \ No newline at end of file diff --git a/dev_mvc/controller/data/Reply.php b/dev_mvc/controller/data/Reply.php deleted file mode 100644 index 06eb89e..0000000 --- a/dev_mvc/controller/data/Reply.php +++ /dev/null @@ -1,38 +0,0 @@ -id = $id; - $this->user = $user; - $this->thread = $thread; - $this->text = $text; - } - public function getId(){ - return $this->id; - } - public function setId($id){ - $this->id = $id; - } - public function getUser(){ - return $this->user; - } - public function setUser($user){ - $this->user = $user; - } - public function getThread(){ - return $this->thread; - } - public function setThread($thread){ - $this->thread = $thread; - } - public function getText(){ - return $this->text; - } - public function setText($text){ - $this->text = $text; - } -} -?> \ No newline at end of file diff --git a/dev_mvc/controller/data/Thread.php b/dev_mvc/controller/data/Thread.php deleted file mode 100644 index 7551e74..0000000 --- a/dev_mvc/controller/data/Thread.php +++ /dev/null @@ -1,17 +0,0 @@ -id = $id; - $this->titel = $titel; - $this->text = $text; - $this->user = $user; - array_push(Thread::$threadArray, $this); - } -} -?> \ No newline at end of file diff --git a/dev_mvc/controller/data/User.php b/dev_mvc/controller/data/User.php deleted file mode 100644 index 69b8e60..0000000 --- a/dev_mvc/controller/data/User.php +++ /dev/null @@ -1,33 +0,0 @@ -id = $id; - $this->username = $username; - $this->email = $email; - $this->password = $password; - array_push(User::$userArray, $this); - } - public function getId(){ - return $this->id; - } - public function setId($id){ - $this->id = $id; - } - public function getUsername(){ - return $this->username; - } - public function setUsername($username){ - $this->username = $username; - } - public function getEmail(){ - return $this->email; - } - public function setEmail($email){ - $this->email = $email; - } -} -?> \ No newline at end of file diff --git a/dev_mvc/controller/db/DBBoard.php b/dev_mvc/controller/db/DBBoard.php new file mode 100644 index 0000000..f9e4afe --- /dev/null +++ b/dev_mvc/controller/db/DBBoard.php @@ -0,0 +1,12 @@ +prepare("SELECT * FROM board"); + $query->execute(); + return $query->fetchAll(PDO::FETCH_BOTH); + } + +} \ No newline at end of file diff --git a/dev_mvc/controller/db/DBReply.php b/dev_mvc/controller/db/DBReply.php new file mode 100644 index 0000000..5ac91b3 --- /dev/null +++ b/dev_mvc/controller/db/DBReply.php @@ -0,0 +1,39 @@ +prepare("INSERT INTO reply (thread_ID, users_ID, content) VALUES (:tid, :uid, :content);"); + $query->bindParam(":uid", $uid); + $query->bindParam(":tid", $threadID); + $query->bindParam(":content", $content); + echo "$uid, $threadID, $content"; + $query->execute(); + } + static function getReplyByID($id):array + { + $con = self::connectToDB(); + $query = $con->prepare("SELECT * FROM reply WHERE id = :id"); + $query->bindParam(":id", $id); + $query->execute(); + return $query->fetch(PDO::FETCH_BOTH); + + } + static function getRepliesByThreadID($tid):array + { + $con = self::connectToDB(); + $query = $con->prepare("SELECT * FROM reply WHERE thread_ID = :tid"); + $query->bindParam(":tid", $tid); + $query->execute(); + return $query->fetchAll(PDO::FETCH_BOTH); + } + static function getLastReplyByThreadID():array + { + $con = self::connectToDB(); + $query = $con->prepare("SELECT * FROM reply WHERE thread_ID = :tid ORDER BY date_created DESC LIMIT 1"); + $query->bindParam(":tid", $tid); + $query->execute(); + return $query->fetch(PDO::FETCH_BOTH); + } +} \ No newline at end of file diff --git a/dev_mvc/controller/db/DBThread.php b/dev_mvc/controller/db/DBThread.php new file mode 100644 index 0000000..3ca65e2 --- /dev/null +++ b/dev_mvc/controller/db/DBThread.php @@ -0,0 +1,37 @@ +prepare("SELECT * FROM thread WHERE ID = :id"); + $query->bindParam(":id", $id); + $query->execute(); + return $query->fetch(PDO::FETCH_BOTH); + } + static function getThreadsByBoard($boardID){ + $con = self::connectToDB(); + $query = $con->prepare("SELECT * FROM thread WHERE board_ID = :boardID"); + $query->bindParam(":boardID", $boardID); + $query->execute(); + return $query->fetchAll(PDO::FETCH_BOTH); + } + static function createThread($threadObject){ + $con = self::connectToDB(); + $query = $con->prepare( "INSERT INTO thread" . + "(users_ID, board_ID, title, text)" . + "VALUES (:uid, :bid, :title, :content);"); + + $uid = $threadObject->getUserID(); + $bid = $threadObject->getBoardID(); + $title = $threadObject->getTitle(); + $content = $threadObject->getContent(); + + $query->bindParam(":uid", $uid); + $query->bindParam(":bid", $bid); + $query->bindParam(":title", $title); + $query->bindParam(":content", $content); + $query->execute(); + } + +} + diff --git a/dev_mvc/controller/db/DBUser.php b/dev_mvc/controller/db/DBUser.php new file mode 100644 index 0000000..b9d6b22 --- /dev/null +++ b/dev_mvc/controller/db/DBUser.php @@ -0,0 +1,134 @@ +prepare("SELECT * FROM users WHERE ID = :uid"); + $query->bindParam(":uid", $uid); + $query->execute(); + return $query->fetch(PDO::FETCH_BOTH); + } + + + //Controleert of het email adres al in de database voorkomt. Returnt true indien wel. + static function checkUsedEmail($email){ + //Verbind met de database + $con = Database::connectToDB(); + //Bereid query voor + $query = $con->prepare("SELECT * FROM users where email = :email"); + //Bind parameters + $query->bindParam(':email', $email, PDO::PARAM_STR, 256); + //Voer de query uit + $query->execute(); + //Check de hoeveelheid rijen die de database returnt. + if($query->rowCount() == 0){ + //Email adres is niet in gebruik, return false + return false; + } + else{ + //Email is al in gebruik of komt meer dan een keer voor. Beide gevallen zijn een probleem dus return true. + return true; + } + } + //Controleert of de gebruikersnaam al in de database voorkomt. Returnt true indien wel. + static function checkUsedUsername($username){ + $con = Database::connectToDB(); + //Bereid query voor + $query = $con->prepare("SELECT * FROM users where username = :username"); + //Bind parameters + $query->bindParam(':username', $username, PDO::PARAM_STR, 256); + //Voer de query uit + $query->execute(); + //Check de hoeveelheid rijen die de database returnt. + if($query->rowCount() == 0){ + //Username adres is niet in gebruik, return false + return false; + } + else{ + //Username is al in gebruik of komt meer dan een keer voor. Beide gevallen zijn een probleem dus return true. + return true; + } + } + //Registreert een gebruiker. Neemt als invoer email, wachtwoord, gebruikersnaam. en email activation key. Nog niet volledig geimplementeerd + static function registerUser($email, $password, $username){ + $ip = $_SERVER['REMOTE_ADDR']; + //Initit db connection + $con = Database::connectToDB(); + //Bereid query voor + $query = $con->prepare("INSERT INTO users (username, email, password, reg_ip) VALUES (:username, :email, :password, :ip)"); + //Bind parameters + $query->bindParam(':username', $username, PDO::PARAM_STR, 256); + $query->bindParam(':email', $email, PDO::PARAM_STR, 256); + $query->bindParam(':password', $password, PDO::PARAM_STR, 256); + $query->bindParam(':ip', $ip, PDO::PARAM_STR, 256); + //Voer query uit + $query->execute(); + } + //Check of gegeven login info in de database voorkomt + static function isLoginValid($email, $password){ + //Init db connection + $con = Database::connectToDB(); + //Bereid query voor + $query = $con->prepare("SELECT * FROM users where email = :email AND password = :password"); + //Bind params + $query->bindParam(':email', $email, PDO::PARAM_STR, 256); + $query->bindParam(':password', $password, PDO::PARAM_STR, 256); + //Voer query it + $query->execute(); + //Check hoeveelheid teruggestuurde rijen + if($query->rowCount() == 1){ + //login correct (komt voor in de db) + return true; + } + else{ + //Incorrect + return false; + } + } + //Vraag gebruikers ID op doormiddel van email en pass + static function getUID($email, $password){ + //Init db connection + $con = Database::connectToDB(); + //Bereid query voor + $query = $con->prepare("SELECT id FROM users where email = :email AND password = :password"); + //Bind params + $query->bindParam(':email', $email, PDO::PARAM_STR, 256); + $query->bindParam(':password', $password, PDO::PARAM_STR, 256); + //Voer query it + $query->execute(); + //Check hoeveelheid teruggestuurde rijen + if($query->rowCount() == 1){ + //login correct, return uid + $result = $query->fetch(PDO::FETCH_COLUMN); + return $result; + } + else{ + //something went wrong, return -1 + return -1; + } + } + static function getUsername($uid){ + $con = Database::connectToDB(); + $query = $con->prepare("SELECT username FROM users where id = :uid"); + $query->bindParam(':uid', $uid, PDO::PARAM_STR, 256); + $query->execute(); + if($query->rowCount() == 1){ + //login correct, return uid + $result = $query->fetch(PDO::FETCH_COLUMN); + return $result; + } + else{ + //something went wrong, return -1 + return "db_user_invalid"; + } + } +} \ No newline at end of file diff --git a/dev_mvc/controller/db/Database.php b/dev_mvc/controller/db/Database.php new file mode 100644 index 0000000..d7e856c --- /dev/null +++ b/dev_mvc/controller/db/Database.php @@ -0,0 +1,172 @@ +prepare("SELECT * FROM email_activation_keys WHERE activationkey = :activationKey"); + $query->bindParam(':activationKey', $activationKey, PDO::PARAM_STR, 256); + $query->execute(); + if($query->rowCount() == 0){ + //bestaat nog niet + return false; + } + else{ + //bestaat al + return true; + } + } + static function registerActivationKey($users_id, $activationKey){ + $con = Database::connectToDB(); + $query = $con->prepare("INSERT INTO email_activation_keys (users_id, activationkey) VALUES (:users_id, :activationkey)"); + $query->bindParam(':users_id', $users_id); + $query->bindParam(':activationkey', $activationKey); + $query->execute(); + } + + + + //Activeer gebruiker en verwijder activation key uit de activation key tabel + static function activateUser($activationKey){ + $con = Database::connectToDb(); + $query = $con->prepare("SELECT users_id FROM email_activation_keys WHERE activationKey = :activationKey"); + $query->bindParam('activationKey', $activationKey); + $query->execute(); + $result = -1; + if($query->rowCount() == 1){ + //login correct, return uid + $result = $query->fetch(PDO::FETCH_COLUMN); + } + else{ + //activation key komt niet voor in de db, return -1 + return -1; + } + $id = $result; + $query = null; + $query = $con->prepare("UPDATE users SET active = 1 WHERE id = :id and active = 0"); + $query->bindParam(':id',$id,PDO::PARAM_INT); + $query->execute(); + } + + /*** + * _____ ______ _____ _____ _____ ____ _ _ _______ ____ _ ________ _ _ _____ + * / ____| ____|/ ____/ ____|_ _/ __ \| \ | | |__ __/ __ \| |/ / ____| \ | |/ ____| + * | (___ | |__ | (___| (___ | || | | | \| | | | | | | | ' /| |__ | \| | (___ + * \___ \| __| \___ \\___ \ | || | | | . ` | | | | | | | < | __| | . ` |\___ \ + * ____) | |____ ____) |___) |_| || |__| | |\ | | | | |__| | . \| |____| |\ |____) | + * |_____/|______|_____/_____/|_____\____/|_| \_| |_| \____/|_|\_\______|_| \_|_____/ + * + ***/ + + + static function isSessionTokenInUse($token){ + //Init db connection + $con = Database::connectToDB(); + //Bereid query voor + $query = $con->prepare("SELECT * FROM usersessions where token = :token"); + //Bind params + $query->bindParam(':token', $token, PDO::PARAM_STR, 256); + //Voer query it + $query->execute(); + //Check hoeveelheid teruggestuurde rijen + if($query->rowCount() == 0){ + return false; + } + else{ + return true; + } + } + static function registerNewSession($uid, $token, $expires){ + //Init db connection + $con = Database::connectToDB(); + //Bereid query voor + $query = $con->prepare("INSERT INTO usersessions (uid, token, expires) VALUES (:uid, :token, :expires)"); + //Bind params + $query->bindParam(':uid', $uid, PDO::PARAM_INT); + $query->bindParam(':token', $token, PDO::PARAM_STR, 256); + $query->bindParam(':expires', $expires, PDO::PARAM_STR); + //Voer query it + $query->execute(); + } + static function isSessionValid($token, $uid){ + //Init db connection + $con = Database::connectToDB(); + //Bereid query voor + $query = $con->prepare("SELECT * FROM usersessions where token = :token AND uid = :uid AND expires > NOW()"); + //Bind params + $query->bindParam(':token', $token, PDO::PARAM_STR, 256); + $query->bindParam(':uid', $uid, PDO::PARAM_STR, 256); + //Voer query it + $query->execute(); + //Check hoeveelheid teruggestuurde rijen + if($query->rowCount() == 1){ + return true; + } + else{ + return false; + } + } + static function invalidateSession($token){ + //Init db connection + $con = Database::connectToDB(); + //Bereid query voor + $query = $con->prepare("DELETE FROM usersessions WHERE token = :token"); + //Bind params + $query->bindParam(':token', $token, PDO::PARAM_STR, 256); + //Voer query it + $query->execute(); + } + static function invalidateSessionByUID($uid){ + //Init db connection + $con = Database::connectToDB(); + //Bereid query voor + $query = $con->prepare("DELETE FROM usersessions WHERE uid = :uid"); + //Bind params + $query->bindParam(':token', $uid, PDO::PARAM_INT); + //Voer query it + $query->execute(); + } + static function deleteExpiredSessions(){ + $con = Database::connectToDB(); + //Bereid query voor + $query = $con->prepare("DELETE FROM usersessions WHERE expires < NOW()"); + $query->execute(); + } + static function getSessionExpiryDate($token){ + $con = Database::connectToDB(); + $query = $con->prepare("SELECT expires FROM usersessions where token = :token"); + $query->bindParam(':token', $token, PDO::PARAM_STR, 256); + $query->execute(); + if($query->rowCount() == 1){ + //login correct, return uid + $result = $query->fetch(PDO::FETCH_COLUMN); + return $result; + } + else{ + //something went wrong, return an invalid date. + return "2000-01-01 00:00:00"; + } + } +} \ No newline at end of file diff --git a/dev_mvc/index.php b/dev_mvc/index.php index 9eb02bd..9d9c4db 100644 --- a/dev_mvc/index.php +++ b/dev_mvc/index.php @@ -1,33 +1,9 @@ executeModel(); +include_once("./view/content_pagetemplate.php"); ?> \ No newline at end of file diff --git a/dev_mvc/model/actions/model_create_reply.php b/dev_mvc/model/actions/model_create_reply.php new file mode 100644 index 0000000..4a44c17 --- /dev/null +++ b/dev_mvc/model/actions/model_create_reply.php @@ -0,0 +1,15 @@ +uid; +if(HUtils::issetPost(['thread', 'content'])); +{ + $reply = new Reply(-1, $_POST['thread'], $uid, $_POST['content']); + print_r($reply); + DBReply::createReply($reply->getUserid(), $reply->getThreadID(), $reply->getContent()); +} +?> diff --git a/dev_mvc/model/actions/model_create_thread.php b/dev_mvc/model/actions/model_create_thread.php new file mode 100644 index 0000000..36c2e23 --- /dev/null +++ b/dev_mvc/model/actions/model_create_thread.php @@ -0,0 +1,14 @@ +uid; +if(HUtils::issetPost(['title', 'content', 'board'])); +{ + $thread = new Thread(-1, $uid, $_POST['board'], $_POST['title'], $_POST['content']); + DBThread::createThread($thread); +} +?> diff --git a/dev_mvc/model/actions/model_destroy.php b/dev_mvc/model/actions/model_destroy.php deleted file mode 100644 index 10da7af..0000000 --- a/dev_mvc/model/actions/model_destroy.php +++ /dev/null @@ -1,4 +0,0 @@ - \ No newline at end of file diff --git a/dev_mvc/model/model_do_register.php b/dev_mvc/model/actions/model_do_register.php similarity index 69% rename from dev_mvc/model/model_do_register.php rename to dev_mvc/model/actions/model_do_register.php index 053392d..2883168 100644 --- a/dev_mvc/model/model_do_register.php +++ b/dev_mvc/model/actions/model_do_register.php @@ -1,7 +1,8 @@ \ No newline at end of file diff --git a/dev_mvc/model/actions/model_login.php b/dev_mvc/model/actions/model_login.php new file mode 100644 index 0000000..c2f7798 --- /dev/null +++ b/dev_mvc/model/actions/model_login.php @@ -0,0 +1,59 @@ +getSessionToken(); + echo "
"; + echo $a->uid; + echo "
"; + echo $a->username; + } + //clean up expired sessions from ANY users + Database::deleteExpiredSessions(); + Database::registerNewSession($a->uid, $a->token, $a->getFormattedExpiry()); + //logged in, time to continue with other stuff + } + else{ + MVCController::getMVCController()->overrideView("account_inactive"); + $skipoverride = true; + echo('ree'); + } + } + else{ + echo "uid returned -1 from db interface"; + } + } + else{ + echo("login invalid"); + } + } +} +else{ + //we're done, don't even need to log in, session already active +} + +if(!UserSession::isUserSignedIn() &&!$skipoverride){ + MVCController::getMVCController()->overrideView("error_login"); +} + +?> \ No newline at end of file diff --git a/dev_mvc/model/actions/model_signout.php b/dev_mvc/model/actions/model_signout.php index 2db1a67..9db085f 100644 --- a/dev_mvc/model/actions/model_signout.php +++ b/dev_mvc/model/actions/model_signout.php @@ -1,4 +1,6 @@ \ No newline at end of file diff --git a/dev_mvc/model/classes/Reply.php b/dev_mvc/model/classes/Reply.php deleted file mode 100644 index e69de29..0000000 diff --git a/dev_mvc/model/classes/Thread.php b/dev_mvc/model/classes/Thread.php deleted file mode 100644 index dd3d92d..0000000 --- a/dev_mvc/model/classes/Thread.php +++ /dev/null @@ -1,19 +0,0 @@ - \ No newline at end of file diff --git a/dev_mvc/model/classes/User.php b/dev_mvc/model/classes/User.php deleted file mode 100644 index e69de29..0000000 diff --git a/dev_mvc/model/forum/Board.php b/dev_mvc/model/forum/Board.php new file mode 100644 index 0000000..877bf99 --- /dev/null +++ b/dev_mvc/model/forum/Board.php @@ -0,0 +1,13 @@ +id = $id; + $this->name = $name; + $this->permLevel = $permLevel; + } + +} + diff --git a/dev_mvc/model/forum/Reply.php b/dev_mvc/model/forum/Reply.php new file mode 100644 index 0000000..87fe3a1 --- /dev/null +++ b/dev_mvc/model/forum/Reply.php @@ -0,0 +1,102 @@ +id = $id; + $this->threadID = $threadID; + $this->userID = $userID; + $this->content = $content; + $dateTime = new DateTime($date); + $this->date = $dateTime; + } + /** + * @return mixed + */ + public function getOwner():User { + return $this->owner; + } + + /** + * @param mixed $owner + */ + public function setOwner($owner) { + $this->owner = $owner; + } + /** + * @return mixed + */ + public function getId() { + return $this->id; + } + + /** + * @return mixed + */ + public function getThreadID() { + return $this->threadID; + } + + /** + * @return mixed + */ + public function getUserID() { + return $this->userID; + } + + /** + * @return mixed + */ + public function getContent() { + return $this->content; + } + + /** + * @return mixed + */ + public function getDate() { + return $this->date; + } + + /** + * @param mixed $id + */ + public function setId($id) { + $this->id = $id; + } + + /** + * @param mixed $threadID + */ + public function setThreadID($threadID) { + $this->threadID = $threadID; + } + + /** + * @param mixed $userID + */ + public function setUserID($userID) { + $this->userID = $userID; + } + + /** + * @param mixed $content + */ + public function setContent($content) { + $this->content = $content; + } + + /** + * @param mixed $date + */ + public function setDate($date) { + $this->date = $date; + } + +} + diff --git a/dev_mvc/model/forum/Thread.php b/dev_mvc/model/forum/Thread.php new file mode 100644 index 0000000..223dc84 --- /dev/null +++ b/dev_mvc/model/forum/Thread.php @@ -0,0 +1,143 @@ +id = $id; + $this->title = $title; + $this->boardID = $boardID; + $this->userID = $userID; + $this->content = $content; + + $dateTime = new DateTime($date_created); + $this->date_created = $dateTime; + + /* + if(isset($threadData)){ + $this->id = $threadData['id']; + $this->title = $threadData['title']; + $this->boardID = $threadData['boardID']; + $this->userID = $threadData['userID']; + $this->content = $threadData['content']; + } + */ + } + /** + * @return multitype: + */ + public function getReplies() { + return $this->replies; + } + + /** + * @return mixed + */ + public function getOwner():User { + return $this->owner; + } + + /** + * @param multitype: $replies + */ + public function setReplies($replies) { + $this->replies = $replies; + } + + /** + * @param mixed $owner + */ + public function setOwner($owner) { + $this->owner = $owner; + } + public function getId():int { + return $this->id; + } + + /** + * @return string $title + */ + public function getTitle():string { + return $this->title; + } + + /** + * @return int $boardID + */ + public function getBoardID():int { + return $this->boardID; + } + + /** + * @return int $userID + */ + public function getUserID():int { + return $this->userID; + } + + /** + * @return string $content + */ + public function getContent():string { + return $this->content; + } + + /** + * @param string $id + */ + public function setId($id) { + $this->id = $id; + } + + /** + * @param string $title + */ + public function setTitle($title) { + $this->title = $title; + } + + /** + * @param string $boardID + */ + public function setBoardID($boardID) { + $this->boardID = $boardID; + } + + /** + * @param string $userID + */ + public function setUserID($userID) { + $this->userID = $userID; + } + + /** + * @param string $content + */ + public function setContent($content) { + $this->content = $content; + } + /** + * @return DateTime + */ + public function getDate_created() { + return $this->date_created; + } + + /** + * @param DateTime $date_created + */ + public function setDate_created($date_created) { + $this->date_created = $date_created; + } + +} + diff --git a/dev_mvc/model/forum/User.php b/dev_mvc/model/forum/User.php new file mode 100644 index 0000000..294dc55 --- /dev/null +++ b/dev_mvc/model/forum/User.php @@ -0,0 +1,138 @@ +id = $id; + $this->username = $username; + $this->email = $email; + $this->password = $password; + $this->reg_date = $reg_date; + $this->login_date = $login_date; + $this->reg_ip=$reg_ip; + $this->permissions=$permissions; + } + /** + * @return mixed + */ + public function getId() { + return $this->id; + } + + /** + * @return mixed + */ + public function getUsername() { + return $this->username; + } + + /** + * @return mixed + */ + public function getEmail() { + return $this->email; + } + + /** + * @return mixed + */ + public function getPassword() { + return $this->password; + } + + /** + * @return mixed + */ + public function getReg_date() { + return $this->reg_date; + } + + /** + * @return mixed + */ + public function getLogin_date() { + return $this->login_date; + } + + /** + * @return mixed + */ + public function getReg_ip() { + return $this->reg_ip; + } + + /** + * @return mixed + */ + public function getPermissions() { + return $this->permissions; + } + + /** + * @param mixed $id + */ + public function setId($id) { + $this->id = $id; + } + + /** + * @param mixed $username + */ + public function setUsername($username) { + $this->username = $username; + } + + /** + * @param mixed $email + */ + public function setEmail($email) { + $this->email = $email; + } + + /** + * @param mixed $password + */ + public function setPassword($password) { + $this->password = $password; + } + + /** + * @param mixed $reg_date + */ + public function setReg_date($reg_date) { + $this->reg_date = $reg_date; + } + + /** + * @param mixed $login_date + */ + public function setLogin_date($login_date) { + $this->login_date = $login_date; + } + + /** + * @param mixed $reg_ip + */ + public function setReg_ip($reg_ip) { + $this->reg_ip = $reg_ip; + } + + /** + * @param mixed $permissions + */ + public function setPermissions($permissions) { + $this->permissions = $permissions; + } + + + + +} + diff --git a/dev_mvc/model/model_create_topic.php b/dev_mvc/model/model_create_topic.php deleted file mode 100644 index ac1dafc..0000000 --- a/dev_mvc/model/model_create_topic.php +++ /dev/null @@ -1,11 +0,0 @@ - \ No newline at end of file diff --git a/dev_mvc/model/model_do_login.php b/dev_mvc/model/model_do_login.php deleted file mode 100644 index a913762..0000000 --- a/dev_mvc/model/model_do_login.php +++ /dev/null @@ -1,45 +0,0 @@ -getSessionToken(); - echo "
"; - echo $a->uid; - echo "
"; - echo $a->username; - } - //clean up expired sessions from ANY users - Database::deleteExpiredSessions(); - Database::registerNewSession($a->uid, $a->token, $a->getFormattedExpiry()); - //logged in, time to continue with other stuff - } - else{ - echo "uid returned -1 from db interface"; - } - } - else{ - echo("login invalid"); - } - } -} -else{ - //we're done, don't even need to log in, session already active -} -?> \ No newline at end of file diff --git a/dev_mvc/tests/createdb/index.php b/dev_mvc/tests/createdb/index.php deleted file mode 100644 index fd6e004..0000000 --- a/dev_mvc/tests/createdb/index.php +++ /dev/null @@ -1,79 +0,0 @@ -exec("CREATE DATABASE `$db`; - CREATE USER '$user'@'localhost' IDENTIFIED BY '$pass'; - GRANT ALL ON `$db`.* TO '$user'@'localhost'; - FLUSH PRIVILEGES;") - or die(print_r($dbh->errorInfo(), true)); - - } catch (PDOException $e) { - die("DB ERROR: ". $e->getMessage()); - } - - try { - $dsn = "mysql:host=$host;dbname=$db"; - //Maak verbinding - $con = new PDO($dsn, $root, $root_password); - $con->exec("CREATE TABLE `board` ( - `ID` int(16) NOT NULL AUTO_INCREMENT, - `name` varchar(256) NOT NULL, - `description` text NOT NULL, - `permLevel` int(16) NOT NULL DEFAULT '0', - PRIMARY KEY (`ID`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1"); - $con->exec("CREATE TABLE `email_activation_keys` ( - `id` int(16) NOT NULL AUTO_INCREMENT, - `users_id` int(16) NOT NULL, - `activationkey` varchar(256) NOT NULL, - PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1"); - $con->exec("CREATE TABLE `reply` ( - `ID` int(16) NOT NULL AUTO_INCREMENT, - `thread_ID` int(16) NOT NULL, - `users_ID` int(16) NOT NULL, - `content` text NOT NULL, - `date_created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - PRIMARY KEY (`ID`) ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1"); - $con->exec("CREATE TABLE `thread` ( - `ID` int(16) NOT NULL AUTO_INCREMENT, - `users_ID` int(16) NOT NULL, - `board_ID` int(16) NOT NULL, - `title` varchar(256) NOT NULL, - `text` text NOT NULL, - `date_created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - PRIMARY KEY (`ID`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1"); - $con->exec("CREATE TABLE `users` ( - `ID` int(11) NOT NULL AUTO_INCREMENT, - `username` varchar(256) NOT NULL, - `email` varchar(256) NOT NULL, - `password` varchar(256) NOT NULL, - `reg_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - `login_date` datetime NOT NULL, - `reg_ip` varchar(256) NOT NULL, - `permissions` int(11) NOT NULL DEFAULT '-1', - `active` tinyint(1) DEFAULT '0', - PRIMARY KEY (`ID`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=latin1"); - $con->exec("CREATE TABLE `usersessions` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `uid` int(11) NOT NULL, - `token` varchar(256) NOT NULL, - `expires` datetime NOT NULL, - PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=latin1"); - } - catch (PDOException $e) { - die("DB ERROR: ". $e->getMessage()); - } - - - -?> \ No newline at end of file diff --git a/dev_mvc/tests/phpinfo/index.php b/dev_mvc/tests/phpinfo/index.php deleted file mode 100644 index 804702b..0000000 --- a/dev_mvc/tests/phpinfo/index.php +++ /dev/null @@ -1,4 +0,0 @@ - \ No newline at end of file diff --git a/dev_mvc/view/content_pagetemplate.php b/dev_mvc/view/content_pagetemplate.php new file mode 100644 index 0000000..fb9617b --- /dev/null +++ b/dev_mvc/view/content_pagetemplate.php @@ -0,0 +1,25 @@ + + + + + + + +
+ +
+
+loadView(); +?> +
+ + + \ No newline at end of file diff --git a/dev_mvc/view/css/main.css b/dev_mvc/view/css/main.css index 03d944d..1bac85d 100644 --- a/dev_mvc/view/css/main.css +++ b/dev_mvc/view/css/main.css @@ -1,4 +1,123 @@ *{ - font-family: Arial, Helvetica, sans-serif; - + font-family: Arial, Helvetica, sans-serif; +} +html, body{ + + width: 100%; + height: 100%; + padding: 0; + margin: 0; + display: flex; + flex-direction: column; + align-items: center; + background-color: #333333; +} +body{ + +} + +loginForm{ + +} +.logo{ + height: 100px; + width: 100px; + box-sizing: border-box; + border-radius: 10px; + justify-self: left; + font-size: 50pt; + padding: 10pt; + color: white; + margin-right: 10px; + /* Permalink - use to edit and share this gradient: https://colorzilla.com/gradient-editor/#1e5799+0,45427a+100 */ + background: #1e5799; /* Old browsers */ + background: -moz-linear-gradient(-45deg, #1e5799 0%, #45427a 100%); /* FF3.6-15 */ + background: -webkit-linear-gradient(-45deg, #1e5799 0%,#45427a 100%); /* Chrome10-25,Safari5.1-6 */ + background: linear-gradient(135deg, #1e5799 0%,#45427a 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#1e5799', endColorstr='#45427a',GradientType=1 ); /* IE6-9 fallback on horizontal gradient */ + + -webkit-touch-callout: none; /* iOS Safari */ + -webkit-user-select: none; /* Safari */ + -khtml-user-select: none; /* Konqueror HTML */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* Internet Explorer/Edge */ + user-select: none; /* Non-prefixed version, currently supported by Chrome and Opera */ + box-shadow: 0px 0px 20px black; +} +.row{ + display: flex; + flex-direction: row; + flex-basis: auto; +} +header{ + margin-top: 10px; +} +nav{ + border-radius: 10px; + display:flex; + flex-direction: flex-row; + flex-basis: auto; + flex-shrink: 0; + flex-grow: 0; + background-color: gray; + width: 80%; + height: 100px; + max-height: 100px; + + + + align-items: center; + justify-items: center; + align-content: center; + justify-content: center; + align-self: center; + justify-self: center; + box-shadow: 0px 0px 20px black; +} +nav a{ + padding-left: 10px; + padding-right: 10px; + text-decoration: none; + font-size: 20pt; + font-weight: bold; + color: white; +} +.main{ + border-radius: 15px; + margin-top: 10px; + display: flex; + flex-direction: column; + flex-grow: 0; + flex-shrink: 1; + background-color: white; + padding: 15px; + margin-bottom: 20px; + box-shadow: 0px 0px 20px black; +} +input{ + padding: 5px; + margin: 5px; +} +textarea{ + padding: 5px; + margin: 5px; + resize: none; + width: 50vw; + height: 20vw; +} +table { + font-family: arial, sans-serif; + border-collapse: collapse; + width: 100%; + width: 80vw; +} + +td, th { + border: 1px solid #dddddd; + text-align: left; + padding: 8px; +} + +tr:nth-child(even) { + background-color: #dddddd; } diff --git a/dev_mvc/view/img/logo.png b/dev_mvc/view/img/logo.png deleted file mode 100644 index 583765116e122e7317c82f4101370a467c0892e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 58147 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 diff --git a/dev_mvc/view/pagecontent/content_404.php b/dev_mvc/view/pagecontent/content_404.php deleted file mode 100644 index ceb7af1..0000000 --- a/dev_mvc/view/pagecontent/content_404.php +++ /dev/null @@ -1,3 +0,0 @@ -

-

This page does not exist!

-
\ No newline at end of file diff --git a/dev_mvc/view/pagecontent/content_attempt_login.php b/dev_mvc/view/pagecontent/content_attempt_login.php deleted file mode 100644 index 0b12f34..0000000 --- a/dev_mvc/view/pagecontent/content_attempt_login.php +++ /dev/null @@ -1,7 +0,0 @@ - \ No newline at end of file diff --git a/dev_mvc/view/pagecontent/content_attempt_logout.php b/dev_mvc/view/pagecontent/content_attempt_logout.php deleted file mode 100644 index 6a047ec..0000000 --- a/dev_mvc/view/pagecontent/content_attempt_logout.php +++ /dev/null @@ -1,3 +0,0 @@ -
-

You've been succesfully logged out

-
\ No newline at end of file diff --git a/dev_mvc/view/pagecontent/content_attempt_register.php b/dev_mvc/view/pagecontent/content_attempt_register.php deleted file mode 100644 index f8b887e..0000000 --- a/dev_mvc/view/pagecontent/content_attempt_register.php +++ /dev/null @@ -1,3 +0,0 @@ -
-

Successfully registered!

-
\ No newline at end of file diff --git a/dev_mvc/view/pagecontent/content_create_topic.php b/dev_mvc/view/pagecontent/content_create_topic.php deleted file mode 100644 index 71b2f4b..0000000 --- a/dev_mvc/view/pagecontent/content_create_topic.php +++ /dev/null @@ -1,4 +0,0 @@ - \ No newline at end of file diff --git a/dev_mvc/view/pagecontent/content_destroy.php b/dev_mvc/view/pagecontent/content_destroy.php deleted file mode 100644 index dc3cd8b..0000000 --- a/dev_mvc/view/pagecontent/content_destroy.php +++ /dev/null @@ -1,3 +0,0 @@ -
-

You're still signed in thanks to our cookies!

-
\ No newline at end of file diff --git a/dev_mvc/view/pagecontent/content_header.php b/dev_mvc/view/pagecontent/content_header.php deleted file mode 100644 index 184e0d0..0000000 --- a/dev_mvc/view/pagecontent/content_header.php +++ /dev/null @@ -1,7 +0,0 @@ - \ No newline at end of file diff --git a/dev_mvc/view/pagecontent/content_index.php b/dev_mvc/view/pagecontent/content_index.php deleted file mode 100644 index 852160d..0000000 --- a/dev_mvc/view/pagecontent/content_index.php +++ /dev/null @@ -1,3 +0,0 @@ -
-

Welkom op hForumPHP. Log in of registreer om iets te doen.

-
\ No newline at end of file diff --git a/dev_mvc/view/pagecontent/content_login.php b/dev_mvc/view/pagecontent/content_login.php deleted file mode 100644 index fa81455..0000000 --- a/dev_mvc/view/pagecontent/content_login.php +++ /dev/null @@ -1,11 +0,0 @@ -
-
- E-mail:
- Password:
- - -
-
- \ No newline at end of file diff --git a/dev_mvc/view/pagecontent/content_page.php b/dev_mvc/view/pagecontent/content_page.php deleted file mode 100644 index 2b88bba..0000000 --- a/dev_mvc/view/pagecontent/content_page.php +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - <?=HUtils::getSiteTitle();?> - - - - - -
- -
-
- -
- - \ No newline at end of file diff --git a/dev_mvc/view/pagecontent/content_register.php b/dev_mvc/view/pagecontent/content_register.php deleted file mode 100644 index f04a213..0000000 --- a/dev_mvc/view/pagecontent/content_register.php +++ /dev/null @@ -1,12 +0,0 @@ - -
-
- Username:
- E-mail:
- Password:
- Verify Password:
- - -
-
-
\ No newline at end of file diff --git a/dev_mvc/view/pagecontent/content_showboards.php b/dev_mvc/view/pagecontent/content_showboards.php deleted file mode 100644 index 3b860be..0000000 --- a/dev_mvc/view/pagecontent/content_showboards.php +++ /dev/null @@ -1,8 +0,0 @@ - \ No newline at end of file diff --git a/dev_mvc/view/pagecontent/content_showtopics.php b/dev_mvc/view/pagecontent/content_showtopics.php deleted file mode 100644 index 1e1f5b1..0000000 --- a/dev_mvc/view/pagecontent/content_showtopics.php +++ /dev/null @@ -1,17 +0,0 @@ -

TOPICS:

-'.$topics[$i][1].' - Gestart door: '.Database::getUsername($topics[$i][2]); - echo '
'; - - } - //test - //echo('aaa'); -} - -?> \ No newline at end of file diff --git a/dev_mvc/view/pagecontent/content_verify.php b/dev_mvc/view/pagecontent/content_verify.php deleted file mode 100644 index 9cc92e0..0000000 --- a/dev_mvc/view/pagecontent/content_verify.php +++ /dev/null @@ -1,16 +0,0 @@ - Go here: Resend email verification -
- - "); -} - - - -?> \ No newline at end of file diff --git a/dev_mvc/view/pagecontent/header/content_header_signedin.php b/dev_mvc/view/pagecontent/header/content_header_signedin.php deleted file mode 100644 index 5d052ec..0000000 --- a/dev_mvc/view/pagecontent/header/content_header_signedin.php +++ /dev/null @@ -1,7 +0,0 @@ - - \ No newline at end of file diff --git a/dev_mvc/view/pagecontent/header/content_header_signedout.php b/dev_mvc/view/pagecontent/header/content_header_signedout.php deleted file mode 100644 index 02bda45..0000000 --- a/dev_mvc/view/pagecontent/header/content_header_signedout.php +++ /dev/null @@ -1,7 +0,0 @@ - - \ No newline at end of file diff --git a/dev_mvc/view/pagecontent/login/content_login_succesful.php b/dev_mvc/view/pagecontent/login/content_login_succesful.php deleted file mode 100644 index f86a96c..0000000 --- a/dev_mvc/view/pagecontent/login/content_login_succesful.php +++ /dev/null @@ -1,3 +0,0 @@ -
-

Successfully logged in!

-
\ No newline at end of file diff --git a/dev_mvc/view/pagecontent/login/content_login_unsuccesful.php b/dev_mvc/view/pagecontent/login/content_login_unsuccesful.php deleted file mode 100644 index a9a1ae8..0000000 --- a/dev_mvc/view/pagecontent/login/content_login_unsuccesful.php +++ /dev/null @@ -1,3 +0,0 @@ -
-

UNEXPECTED LOGIN ERROR. OUR CODEMONKEYS DID SOMETHING VERY WRONG :(

-
\ No newline at end of file diff --git a/dev_mvc/view/pagecontent/modules/topbar_login.php b/dev_mvc/view/pagecontent/modules/topbar_login.php deleted file mode 100644 index 653b5ba..0000000 --- a/dev_mvc/view/pagecontent/modules/topbar_login.php +++ /dev/null @@ -1,8 +0,0 @@ -
-
- E-mail: - Password: - - -
-
\ No newline at end of file diff --git a/dev_mvc/view/webcontent/content_404.php b/dev_mvc/view/webcontent/content_404.php new file mode 100644 index 0000000..11ec629 --- /dev/null +++ b/dev_mvc/view/webcontent/content_404.php @@ -0,0 +1,6 @@ + +

+404 +

\ No newline at end of file diff --git a/dev_mvc/view/webcontent/content_account_inactive.php b/dev_mvc/view/webcontent/content_account_inactive.php new file mode 100644 index 0000000..068797f --- /dev/null +++ b/dev_mvc/view/webcontent/content_account_inactive.php @@ -0,0 +1,5 @@ + +

+ Your account appears to be inactive. Check your email for the verification mail. +

\ No newline at end of file diff --git a/dev_mvc/view/webcontent/content_boards.php b/dev_mvc/view/webcontent/content_boards.php new file mode 100644 index 0000000..6bcb0ff --- /dev/null +++ b/dev_mvc/view/webcontent/content_boards.php @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/dev_mvc/view/webcontent/content_createreply.php b/dev_mvc/view/webcontent/content_createreply.php new file mode 100644 index 0000000..c18cec1 --- /dev/null +++ b/dev_mvc/view/webcontent/content_createreply.php @@ -0,0 +1,6 @@ +
+
+ + + +
\ No newline at end of file diff --git a/dev_mvc/view/webcontent/content_createthread.php b/dev_mvc/view/webcontent/content_createthread.php new file mode 100644 index 0000000..1fdaeb5 --- /dev/null +++ b/dev_mvc/view/webcontent/content_createthread.php @@ -0,0 +1,7 @@ +
+
+
+ + "> + +
\ No newline at end of file diff --git a/dev_mvc/view/webcontent/content_error_login.php b/dev_mvc/view/webcontent/content_error_login.php new file mode 100644 index 0000000..13d6cda --- /dev/null +++ b/dev_mvc/view/webcontent/content_error_login.php @@ -0,0 +1,4 @@ +Incorrect Email or Password. + \ No newline at end of file diff --git a/dev_mvc/view/webcontent/content_header.php b/dev_mvc/view/webcontent/content_header.php new file mode 100644 index 0000000..2e9369e --- /dev/null +++ b/dev_mvc/view/webcontent/content_header.php @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/dev_mvc/view/webcontent/content_home.php b/dev_mvc/view/webcontent/content_home.php new file mode 100644 index 0000000..a48a9b9 --- /dev/null +++ b/dev_mvc/view/webcontent/content_home.php @@ -0,0 +1,3 @@ +

+ Please sign in to access our forum +

\ No newline at end of file diff --git a/dev_mvc/view/webcontent/content_register.php b/dev_mvc/view/webcontent/content_register.php new file mode 100644 index 0000000..9411e07 --- /dev/null +++ b/dev_mvc/view/webcontent/content_register.php @@ -0,0 +1,12 @@ + +
+
+
+
+
+
+ + +
+
+
\ No newline at end of file diff --git a/dev_mvc/view/webcontent/content_reply.php b/dev_mvc/view/webcontent/content_reply.php new file mode 100644 index 0000000..b3d9bbc --- /dev/null +++ b/dev_mvc/view/webcontent/content_reply.php @@ -0,0 +1 @@ +getReplies(); +?> + +

+ getTitle()?> +

+ + + + + + + + + + +getOwner()->getUsername(); + $content = $reply->getContent(); + $date_created = $reply->getDate()->format("Y M d H:i:s"); + echo(""); + echo(""); + echo(""); + echo(""); + echo(""); +} +?> +
usercontentdate
+ getOwner()->getUsername();?> + + getContent()?> + + getDate_created()->format("Y M d H:i:s")?> +
$owner$content$date_created
+getId(); +echo "Create Reply" +?> \ No newline at end of file diff --git a/dev_mvc/view/webcontent/content_signin.php b/dev_mvc/view/webcontent/content_signin.php new file mode 100644 index 0000000..48b427e --- /dev/null +++ b/dev_mvc/view/webcontent/content_signin.php @@ -0,0 +1,6 @@ +
+
+
+ + +
\ No newline at end of file diff --git a/dev_mvc/view/webcontent/content_signout.php b/dev_mvc/view/webcontent/content_signout.php new file mode 100644 index 0000000..3b0d91d --- /dev/null +++ b/dev_mvc/view/webcontent/content_signout.php @@ -0,0 +1 @@ +Signed out succesfully! \ No newline at end of file diff --git a/dev_mvc/view/webcontent/content_verify.php b/dev_mvc/view/webcontent/content_verify.php new file mode 100644 index 0000000..03097a9 --- /dev/null +++ b/dev_mvc/view/webcontent/content_verify.php @@ -0,0 +1,2 @@ + + hF + + \ No newline at end of file diff --git a/dev_mvc/view/webcontent/header/header_signedout.php b/dev_mvc/view/webcontent/header/header_signedout.php new file mode 100644 index 0000000..f0e3f4d --- /dev/null +++ b/dev_mvc/view/webcontent/header/header_signedout.php @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/dev_mvc/view/webcontent/modules/modules_boards/module_boardtable.php b/dev_mvc/view/webcontent/modules/modules_boards/module_boardtable.php new file mode 100644 index 0000000..aeae4b4 --- /dev/null +++ b/dev_mvc/view/webcontent/modules/modules_boards/module_boardtable.php @@ -0,0 +1,48 @@ +

name?>

+ Create Thread + + + + + + +getBoardID() == $board->id){ + $currentRow = []; + $currentRow['threadID'] = $thread->getID(); + $currentRow['threadTitle'] = $thread->getTitle(); + foreach(MVCController::$viewData['users'] as $user){ + if($user->getID() == $thread->getUserID()){ + $currentRow['username'] = $user->getUsername(); + break; + } + } + foreach(MVCController::$viewData['replies'] as $reply){ + if(isset($reply)){ + if($reply->getThreadID() == $thread->getId()) + { + break; + }else{ + $currentRow['lastUpdated'] = $thread->getDate_created()->format("Y M d H:i:s"); + } + } + } + ?> + + + + + + +
ThreadStarted byLast reply
+ + + + + + +
diff --git a/dev_mvc/viewmodel/viewmodel_boards.php b/dev_mvc/viewmodel/viewmodel_boards.php new file mode 100644 index 0000000..4a582be --- /dev/null +++ b/dev_mvc/viewmodel/viewmodel_boards.php @@ -0,0 +1,47 @@ +getId()){ + $skipUser = true; + } + } + if(!$skipUser){ + array_push($users, new User($row['ID'], $row['username'], $row['email'], $row['password'], $row['reg_date'], $row['login_date'], $row['reg_ip'], $row['permissions'])); + } +} + + + +//MVCController::$viewData['boards'] = [new Board(0, "General", 0),new Board(1, "Admin board", 10)]; +MVCController::$viewData['boards'] = $boards; +MVCController::$viewData['threads'] = $threads; +MVCController::$viewData['users'] = $users; +MVCController::$viewData['replies'] = [new Reply(0, 0, 0, "op is gay","01-01-1990")]; +?> \ No newline at end of file diff --git a/dev_mvc/viewmodel/viewmodel_createreply.php b/dev_mvc/viewmodel/viewmodel_createreply.php new file mode 100644 index 0000000..09aec04 --- /dev/null +++ b/dev_mvc/viewmodel/viewmodel_createreply.php @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/dev_mvc/viewmodel/viewmodel_home.php b/dev_mvc/viewmodel/viewmodel_home.php new file mode 100644 index 0000000..ca17b06 --- /dev/null +++ b/dev_mvc/viewmodel/viewmodel_home.php @@ -0,0 +1,6 @@ +overrideView("boards"); +} \ No newline at end of file diff --git a/dev_mvc/viewmodel/viewmodel_showthread.php b/dev_mvc/viewmodel/viewmodel_showthread.php new file mode 100644 index 0000000..68dc5cf --- /dev/null +++ b/dev_mvc/viewmodel/viewmodel_showthread.php @@ -0,0 +1,37 @@ +getUserID()); + $replyOwner = new User($replyOwnerData['ID'], $replyOwnerData['username'], $replyOwnerData['email'], $replyOwnerData['password'], $replyOwnerData['reg_date'], $replyOwnerData['login_date'], $replyOwnerData['reg_ip'], $replyOwnerData['permissions']); + $reply->setOwner($replyOwner); +} + +// get the person who started the thread +$threadOwnerData = DBUser::getUserByUID($thread->getUserID()); +// create user object +$threadOwner = new User($threadOwnerData['ID'], $threadOwnerData['username'], $threadOwnerData['email'], $threadOwnerData['password'], $threadOwnerData['reg_date'], $threadOwnerData['login_date'], $threadOwnerData['reg_ip'], $threadOwnerData['permissions']); +// assign owner and replies +$thread->setReplies($replies); +$thread->setOwner($threadOwner); + +// Store data so it can be used in the view +MVCController::$viewData['thread'] = $thread; +?> \ No newline at end of file diff --git a/dev_mvc/viewmodel/viewmodel_signout.php b/dev_mvc/viewmodel/viewmodel_signout.php new file mode 100644 index 0000000..2896d01 --- /dev/null +++ b/dev_mvc/viewmodel/viewmodel_signout.php @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/dev_mvc/model/actions/model_verify.php b/dev_mvc/viewmodel/viewmodel_verify.php similarity index 66% rename from dev_mvc/model/actions/model_verify.php rename to dev_mvc/viewmodel/viewmodel_verify.php index 0c2a780..a46d161 100644 --- a/dev_mvc/model/actions/model_verify.php +++ b/dev_mvc/viewmodel/viewmodel_verify.php @@ -1,5 +1,6 @@ \ No newline at end of file