init commit

This commit is contained in:
bckelley
2024-01-25 09:52:59 -06:00
commit a979c73924
33 changed files with 1870 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
Options -Indexes
+25
View File
@@ -0,0 +1,25 @@
<?PHP
/*
* Explanation:
* - The code loads the configuration file, which typically contains constants and settings.
* - It includes helper files for URL and session-related functions.
* - The spl_autoload_register function is used to automatically load class files when needed.
* - The anonymous function within spl_autoload_register dynamically requires the class file based on its name.
* - This allows for a more organized and modular structure in loading core libraries.
*/
// Load Config
require_once 'config/config.php';
// Include URL Helper Functions
require_once 'helpers/url.php';
// Include Session Helper Functions
require_once 'helpers/sessions.php';
// Autoload Core Libraries using spl_autoload_register
spl_autoload_register(function ($className) {
// Require the specified class file from the libraries directory
require_once 'libraries/' . $className . '.php';
});
+21
View File
@@ -0,0 +1,21 @@
<?php
// DB Params
define('DBHOST', 'localhost');
define('DBUSER', 'root');
define('DBPASS', '');
define('DBNAME', 'nomadmvc');
// App Root
define('APP_ROOT', dirname(dirname(__FILE__)));
// URL Root
define('URL_ROOT', 'https://routeeasemvc.local');
// Site Name
define('SITENAME', 'RouteEase MVC');
// App Version
/**
* TODO: make APP_VERSION a protected class
*/
define('APP_VERSION', '0.0.1');
+53
View File
@@ -0,0 +1,53 @@
<?php
/**
* Pages Controller Class
*
* This class handles the main pages of the application.
*/
class Pages extends Controller {
/**
* Constructor method.
*/
public function __construct(){
// Constructor logic (if any)
}
/**
* Index Method
*
* Handles the homepage of the application.
*/
public function index(){
// Check if the user is logged in
if (isLoggedIn()) {
// Redirect to the posts index page
redirect('/posts/index');
}
// Data for the view
$data = [
'title' => 'Home',
'description' => '',
];
// Load the view with the specified data
$this->view('pages/index', $data);
}
/**
* About Method
*
* Handles the about us page of the application.
*/
public function about(){
// Data for the view
$data = [
'title' => 'About Us',
'description' => '',
'version' => APP_VERSION,
];
// Load the view with the specified data
$this->view('pages/about', $data);
}
}
+222
View File
@@ -0,0 +1,222 @@
<?php
/**
* Posts Controller Class
*
* This class handles the functionality related to posts in the application.
*/
class Posts extends Controller {
private $postModel;
private $userModel;
/**
* Constructor method.
*/
public function __construct() {
// Check if the user is logged in
if (!isLoggedIn()) {
// Redirect to the login page if not logged in
redirect('/users/login');
}
// Initialize models
$this->postModel = $this->model('Post');
$this->userModel = $this->model('User');
}
/**
* Index Method
*
* Displays a list of posts.
*/
public function index() {
// Get all posts
$posts = $this->postModel->getPosts();
// Data for the view
$data = [
'posts' => $posts,
];
// Load the view with the specified data
$this->view('/posts/index', $data);
}
/**
* Show Method
*
* Displays a single post.
*
* @param int $id Post ID
*/
public function show($id) {
// Get post and user information
$post = $this->postModel->getPost($id);
$user = $this->userModel->getUserById($post->user_id);
// Data for the view
$data = [
'post' => $post,
'user' => $user,
];
// Load the view with the specified data
$this->view('/posts/show', $data);
}
/**
* Add Method
*
* Adds a new post.
*/
public function add() {
// Check if the form is submitted
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// Sanitize input data
$_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_SPECIAL_CHARS);
// Extract form data
$data = [
'title' => trim($_POST['title']),
'summary' => trim($_POST['summary']),
'body' => trim($_POST['body']),
'userId' => $_SESSION['userId'],
'titleErr' => '',
'summaryErr' => '',
'bodyErr' => '',
];
// Validate form data
if (empty($data['title'])) {
$data['titleErr'] = 'Please enter a title.';
}
if (empty($data['summary'])) {
$data['summaryErr'] = 'Please enter a summary.';
}
if (empty($data['body'])) {
$data['bodyErr'] = 'Please enter a body.';
}
// Check for errors
if (empty($data['titleErr']) && empty($data['summaryErr']) && empty($data['bodyErr'])) {
// Add post to the database
if ($this->postModel->addPost($data)) {
message('post_message', 'Your post has been added.', 'alert alert-success');
redirect('/posts/index');
} else {
die('Something went wrong.');
}
} else {
// Load the view with the specified data and errors
$this->view('/posts/add', $data);
}
} else {
// Display the form
$data = [
'title' => '',
'summary' => '',
'body' => '',
];
// Load the view with the specified data
$this->view('/posts/add', $data);
}
}
/**
* Edit Method
*
* Edits an existing post.
*
* @param int $id Post ID
*/
public function edit($id) {
// Check if the form is submitted
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// Sanitize input data
$_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_SPECIAL_CHARS);
// Extract form data
$data = [
'id' => $id,
'title' => trim($_POST['title']),
'summary' => trim($_POST['summary']),
'body' => trim($_POST['body']),
'userId' => $_SESSION['userId'],
'titleErr' => '',
'summaryErr' => '',
'bodyErr' => '',
];
// Validate form data
if (empty($data['title'])) {
$data['titleErr'] = 'Please enter a title.';
}
if (empty($data['summary'])) {
$data['summaryErr'] = 'Please enter a summary.';
}
if (empty($data['body'])) {
$data['bodyErr'] = 'Please enter a body.';
}
// Check for errors
if (empty($data['titleErr']) && empty($data['summaryErr']) && empty($data['bodyErr'])) {
// Update post in the database
if ($this->postModel->updatePost($data)) {
message('post_message', 'Your post has been updated.', 'alert alert-success');
redirect('/posts/index');
} else {
die('Something went wrong.');
}
} else {
// Load the view with the specified data and errors
$this->view('/posts/edit', $data);
}
} else {
// Display the form with existing post data
$post = $this->postModel->getPost($id);
// Check if the user is authorized to edit the post
if ($post->user_id != $_SESSION['userId']) {
redirect('/posts/index');
}
// Data for the view
$data = [
'id' => $id,
'title' => $post->title,
'summary' => $post->summary,
'body' => $post->body,
];
// Load the view with the specified data
$this->view('/posts/edit', $data);
}
}
/**
* Delete Method
*
* Deletes a post.
*
* @param int $id Post ID
*/
public function delete($id) {
// Check if the form is submitted
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// Delete post from the database
if ($this->postModel->deletePost($id)) {
message('post_message', 'Your post has been removed.');
redirect('/posts/index');
} else {
die('Something went wrong');
}
} else {
// Redirect to the posts index page if form is not submitted
redirect('/posts/index');
}
}
}
+204
View File
@@ -0,0 +1,204 @@
<?php
/**
* Users Controller Class
*
* This class handles user-related functionality such as registration, login, and logout.
*/
class Users extends Controller {
private $userModel;
/**
* Constructor method.
*/
public function __construct() {
// Initialize the user model
$this->userModel = $this->model('User');
}
/**
* Register Method
*
* Handles user registration.
*/
public function register() {
// Check if the form is submitted
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// Sanitize input data
$_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_SPECIAL_CHARS);
// Extract form data
$data = [
'username' => trim($_POST['username']),
'email' => trim($_POST['email']),
'password' => trim($_POST['password']),
'again' => trim($_POST['again']),
'usernameErr' => '',
'emailErr' => '',
'passErr' => '',
'againErr' => '',
];
// Validate form data
if (empty($data['email'])) {
$data['emailErr'] = 'Please provide an email.';
} else {
if ($this->userModel->findUserByEmail($data['email'])) {
$data['emailErr'] = 'Email exists.';
}
}
if (empty($data['username'])) {
$data['usernameErr'] = 'Please provide a valid username.';
}
if (empty($data['password'])) {
$data['passErr'] = 'Please provide a valid password.';
} elseif (strlen($data['password']) < 6) {
$data['passErr'] = 'Please provide a password 6 or more characters in length.';
}
if (empty($data['again'])) {
$data['againErr'] = 'Please confirm your password.';
} else {
if ($data['password'] != $data['again']) {
$data['passErr'] = 'Passwords do not match.';
}
}
// Check for errors
if (empty($data['usernameErr']) && empty($data['emailErr']) &&
empty($data['passErr']) && empty($data['againErr'])) {
// Hash the password
$data['password'] = password_hash($data['password'], PASSWORD_BCRYPT);
// Register the user
if ($this->userModel->register($data)) {
message('reg_success', 'You are now registered and can login.', 'alert alert-success');
redirect('/users/login');
} else {
die('Something went wrong.');
}
} else {
// Load the view with the specified data and errors
$this->view('users/register', $data);
}
} else {
// Display the registration form
$data = [
'username' => '',
'email' => '',
'password' => '',
'again' => '',
'usernameErr' => '',
'emailErr' => '',
'passErr' => '',
'againErr' => '',
];
// Load the view with the specified data
$this->view('users/register', $data);
}
}
/**
* Login Method
*
* Handles user login.
*/
public function login() {
// Check if the form is submitted
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// Sanitize input data
$_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_SPECIAL_CHARS);
// Extract form data
$data = [
'email' => trim($_POST['email']),
'password' => trim($_POST['password']),
'emailErr' => '',
'passErr' => '',
];
// Validate form data
if (empty($data['email'])) {
$data['emailErr'] = 'Please provide an email.';
}
if (empty($data['password'])) {
$data['passErr'] = 'Please provide a valid password.';
} elseif (strlen($data['password']) < 6) {
$data['passErr'] = 'Please provide a password 6 or more characters in length.';
}
// Check if the user exists
if ($this->userModel->findUserByEmail($data['email'])) {
} else {
$data['emailErr'] = 'No user found.';
}
// Check for errors
if (empty($data['emailErr']) && empty($data['passErr'])) {
// Attempt to log in the user
$loggedIn = $this->userModel->login($data['email'], $data['password']);
if ($loggedIn) {
$this->createUserSession($loggedIn);
} else {
$data['passErr'] = 'Password was incorrect.';
}
} else {
// Load the view with the specified data and errors
$this->view('users/login', $data);
}
} else {
// Display the login form
$data = [
// 'username' => '',
'email' => '',
'password' => '',
// 'usernameErr' => '',
'emailErr' => '',
'passErr' => '',
];
// Load the view with the specified data
$this->view('users/login', $data);
}
}
/**
* createUserSession Method
*
* Creates a user session upon successful login.
*
* @param object $user User object
*/
public function createUserSession($user) {
// Set session variables
$_SESSION['userId'] = $user->id;
$_SESSION['username'] = $user->name;
$_SESSION['userEmail'] = $user->email;
// Redirect to the posts index page
redirect('/posts/index');
}
/**
* Logout Method
*
* Logs out the user.
*/
public function logout() {
// Unset session variables
unset($_SESSION['userId']);
unset($_SESSION['username']);
unset($_SESSION['userEmail']);
// Redirect to the login page
redirect('/users/login');
}
}
+57
View File
@@ -0,0 +1,57 @@
<?php
/**
* Start Session
*
* Start the PHP session.
*/
session_start();
/**
* Message Function
*
* Set or display a flash message.
*
* @param string $name Name of the message session variable
* @param string $msg Message content
* @param string $class CSS class for styling the message (default: 'alert alert-primary')
*/
function message($name='', $msg='', $class='alert alert-primary') {
if (!empty($name)) {
if (!empty($msg) && empty($_SESSION[$name])) {
// Set the message and its class in the session
if (!empty($_SESSION[$name])) {
unset($_SESSION[$name]);
}
if (!empty($_SESSION[$name . '_class'])) {
unset($_SESSION[$name . '_class']);
}
$_SESSION[$name] = $msg;
$_SESSION[$name . '_class'] = $class;
} elseif (empty($msg) && !empty($_SESSION[$name])) {
// Display the message and its class
$class = !empty($_SESSION[$name . '_class']) ? $_SESSION[$name . '_class'] : '';
echo '<div class="'. $class .'" id="route-msg">' . $_SESSION[$name] . '</div>';
// Clear the session variables
unset($_SESSION[$name]);
unset($_SESSION[$name . '_class']);
}
}
}
/**
* Is Logged In Function
*
* Check if a user is logged in.
*
* @return bool Returns true if the user is logged in, false otherwise.
*/
function isLoggedIn() {
if (isset($_SESSION['userId'])) {
return true;
} else {
return false;
}
}
+12
View File
@@ -0,0 +1,12 @@
<?php
/**
* Redirect Function
*
* Redirect the user to a specified page.
*
* @param string $page The page to redirect to
*/
function redirect($page) {
// Use the header function to perform the redirection
header('Location: ' . URL_ROOT . $page);
}
+43
View File
@@ -0,0 +1,43 @@
<?php
/**
* Base Controller Class
*
* This class serves as the base controller, responsible for loading models and views.
*/
class Controller {
/**
* Load Model Method
*
* Loads and instantiates the specified model.
*
* @param string $model The name of the model to be loaded
* @return object An instance of the specified model
*/
public function model($model) {
// Require the model file
require_once '../app/models/' . $model . '.php';
// Instantiate the model
return new $model();
}
/**
* Load View Method
*
* Loads the specified view file and passes data to it.
*
* @param string $view The name of the view file to be loaded
* @param array $data Data to be passed to the view (default: [])
* @param array $class Additional classes to be applied to the view (default: [])
*/
public function view($view, $data = [], $class = []) {
// Check if the view file exists
if (file_exists('../app/views/' . $view . '.php')) {
// Require the view file
require_once '../app/views/' . $view . '.php';
} else {
// View does not exist
die('View does not exist');
}
}
}
+68
View File
@@ -0,0 +1,68 @@
<?php
/**
* App Core Class
*
* This class creates the URL and loads the core controller.
* URL FORMAT - /controller/method/params
*/
class Core {
protected $currentController = 'Pages';
protected $currentMethod = 'index';
protected $params = [];
/**
* Constructor method.
*/
public function __construct() {
// Get the URL
$url = $this->getUrl();
// Look in controllers for the first value
if (!empty($url[0])) {
if (file_exists('../app/controllers/' . ucwords($url[0]) . '.php')) {
// If exists, set as controller
$this->currentController = ucwords($url[0]);
// Unset 0 Index
unset($url[0]);
}
}
// Require the controller
require_once '../app/controllers/' . $this->currentController . '.php';
// Instantiate the controller class
$this->currentController = new $this->currentController;
// Check for the second part of the URL
if (isset($url[1])) {
// Check to see if the method exists in the controller
if (method_exists($this->currentController, $url[1])) {
$this->currentMethod = $url[1];
// Unset 1 index
unset($url[1]);
}
}
// Get params
$this->params = $url ? array_values($url) : [];
// Call a callback with an array of params
call_user_func_array([$this->currentController, $this->currentMethod], $this->params);
}
/**
* Get URL Method
*
* Gets the URL and prepares it for processing.
*
* @return array An array representing the URL
*/
public function getUrl() {
if (isset($_GET['url'])) {
$url = rtrim($_GET['url'], '/');
$url = filter_var($url, FILTER_SANITIZE_URL);
$url = explode('/', $url);
return $url;
}
}
}
+123
View File
@@ -0,0 +1,123 @@
<?php
/**
* PDO Database Class
*
* This class is responsible for connecting to the database, creating prepared statements,
* binding values, and returning rows and results.
*/
class Database {
private $host = DBHOST;
private $user = DBUSER;
private $pass = DBPASS;
private $dbname = DBNAME;
private $dbh; // PDO instance
private $stmt; // Prepared statement
private $error; // Error message
/**
* Constructor method.
*/
public function __construct() {
// Set DSN
$dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;
$options = array(
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
);
// Create PDO instance
try {
$this->dbh = new PDO($dsn, $this->user, $this->pass, $options);
} catch (PDOException $e) {
$this->error = $e->getMessage();
echo $this->error;
}
}
/**
* Query Method
*
* Prepares a statement with the provided SQL query.
*
* @param string $sql The SQL query
*/
public function query($sql) {
$this->stmt = $this->dbh->prepare($sql);
}
/**
* Bind Method
*
* Binds a value to a parameter in the prepared statement.
*
* @param mixed $param The parameter to bind
* @param mixed $value The value to bind
* @param string $type The data type (default: null)
*/
public function bind($param, $value, $type = null) {
if (is_null($type)) {
switch (true) {
case is_int($value):
$type = PDO::PARAM_INT;
break;
case is_bool($value):
$type = PDO::PARAM_BOOL;
break;
case is_null($value):
$type = PDO::PARAM_NULL;
break;
default:
$type = PDO::PARAM_STR;
}
}
$this->stmt->bindValue($param, $value, $type);
}
/**
* Execute Method
*
* Executes the prepared statement.
*
* @return bool Returns true on success, false on failure
*/
public function execute() {
return $this->stmt->execute();
}
/**
* ResultSet Method
*
* Gets the result set as an array of objects.
*
* @return array An array of objects representing the result set
*/
public function resultSet() {
$this->execute();
return $this->stmt->fetchAll(PDO::FETCH_OBJ);
}
/**
* Single Method
*
* Gets a single record as an object.
*
* @return object An object representing a single record
*/
public function single() {
$this->execute();
return $this->stmt->fetch(PDO::FETCH_OBJ);
}
/**
* RowCount Method
*
* Gets the row count of the result set.
*
* @return int The number of rows affected by the last SQL statement
*/
public function rowCount() {
return $this->stmt->rowCount();
}
}
+117
View File
@@ -0,0 +1,117 @@
<?php
/**
* Post Class
*
* This class is responsible for handling post-related database operations.
*/
class Post {
private $db; // Database instance
/**
* Constructor method.
*/
public function __construct() {
$this->db = new Database;
}
/**
* GetPosts Method
*
* Fetches all posts from the database.
*
* @return array An array of post objects
*/
public function getPosts() {
$this->db->query('SELECT *, posts.id as postId,
users.id as userId,
posts.created_at as postCreated,
users.created_at as userCreated
FROM posts INNER JOIN users ON posts.user_id = users.id ORDER BY posts.created_at DESC');
$res = $this->db->resultSet();
return $res;
}
/**
* GetPost Method
*
* Fetches a single post by its ID.
*
* @param int $id The ID of the post
* @return object An object representing a single post
*/
public function getPost($id) {
$this->db->query('SELECT * FROM posts WHERE id = :id');
$this->db->bind(':id', $id);
$row = $this->db->single();
return $row;
}
/**
* AddPost Method
*
* Inserts a new post into the database.
*
* @param array $data An associative array containing post data
* @return bool Returns true on success, false on failure
*/
public function addPost($data) {
$this->db->query('INSERT INTO posts (user_id, title, summary, body) VALUES(:userId, :title, :summary, :body)');
$this->db->bind(':userId', $data['userId']);
$this->db->bind(':title', $data['title']);
$this->db->bind(':summary', $data['summary']);
$this->db->bind(':body', $data['body']);
if ($this->db->execute()) {
return true;
} else {
return false;
}
}
/**
* UpdatePost Method
*
* Updates an existing post in the database.
*
* @param array $data An associative array containing post data
* @return bool Returns true on success, false on failure
*/
public function updatePost($data) {
$this->db->query('UPDATE posts SET title=:title, summary=:summary, body=:body WHERE id=:id');
$this->db->bind(':id', $data['id']);
$this->db->bind(':title', $data['title']);
$this->db->bind(':summary', $data['summary']);
$this->db->bind(':body', $data['body']);
if ($this->db->execute()) {
return true;
} else {
return false;
}
}
/**
* DeletePost Method
*
* Deletes a post from the database by its ID.
*
* @param int $id The ID of the post
* @return bool Returns true on success, false on failure
*/
public function deletePost($id) {
$this->db->query('DELETE FROM posts WHERE id = :id');
$this->db->bind(':id', $id);
if ($this->db->execute()) {
return true;
} else {
return false;
}
}
}
+99
View File
@@ -0,0 +1,99 @@
<?php
/**
* User Class
*
* This class is responsible for handling user-related database operations.
*/
class User {
private $db; // Database instance
/**
* Constructor method.
*/
public function __construct() {
$this->db = new Database;
}
/**
* GetUserById Method
*
* Fetches a user by their ID.
*
* @param int $id The ID of the user
* @return object An object representing the user
*/
public function getUserById($id) {
$this->db->query('SELECT * FROM users WHERE id = :id');
$this->db->bind(':id', $id);
$row = $this->db->single();
return $row;
}
/**
* FindUserByEmail Method
*
* Checks if a user with the given email exists.
*
* @param string $email The email of the user
* @return bool Returns true if the user exists, false otherwise
*/
public function findUserByEmail($email) {
$this->db->query('SELECT * FROM users WHERE email = :email');
$this->db->bind(':email', $email);
$row = $this->db->single();
if ($this->db->rowCount() > 0) {
return true;
} else {
return false;
}
}
/**
* Register Method
*
* Registers a new user in the database.
*
* @param array $data An associative array containing user data
* @return bool Returns true on success, false on failure
*/
public function register($data) {
$this->db->query('INSERT INTO users (name, email, password) VALUES(:name, :email, :password)');
$this->db->bind(':name', $data['username']);
$this->db->bind(':email', $data['email']);
$this->db->bind(':password', $data['password']);
if ($this->db->execute()) {
return true;
} else {
return false;
}
}
/**
* Login Method
*
* Performs user login based on email and password.
*
* @param string $email The email of the user
* @param string $password The password of the user
* @return mixed Returns the user object on success, false on failure
*/
public function login($email, $password) {
$this->db->query('SELECT * FROM users WHERE email = :email');
$this->db->bind(':email', $email);
$row = $this->db->single();
$hashedPassword = $row->password;
if (password_verify($password, $hashedPassword)) {
return $row;
} else {
return false;
}
}
}
+9
View File
@@ -0,0 +1,9 @@
</div>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.12.9/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<script src="<?php echo URL_ROOT; ?>/js/main.js"></script>
</body>
</html>
+24
View File
@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="<?php echo URL_ROOT; ?>/css/style.css">
<title><?php echo SITENAME; ?></title>
</head>
<body>
<?php require APP_ROOT . '/views/inc/navbar.php' ?>
<div class="container">
+53
View File
@@ -0,0 +1,53 @@
<nav class="navbar navbar-expand-lg navbar-dark bg-dark mb-3">
<div class="container">
<!-- Brand Logo and Link -->
<a class="navbar-brand" href="<?php echo URL_ROOT ?>"><?php echo SITENAME ?></a>
<!-- Navbar Toggler Button for Responsive Design -->
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#topNavbarMain" aria-controls="topNavbarMain" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<?php
// TODO: Add bootstrap active class dynamically based on the current page
?>
<!-- Navbar Links -->
<div class="collapse navbar-collapse" id="topNavbarMain">
<ul class="navbar-nav mr-auto">
<!-- Home Link -->
<li class="nav-item">
<a class="nav-link" href="<?php echo URL_ROOT ?>">Home</a>
</li>
<!-- About Link -->
<li class="nav-item">
<a class="nav-link" href="<?php echo URL_ROOT ?>/pages/about">About</a>
</li>
<!-- Posts Link -->
<li class="nav-item">
<a class="nav-link" href="<?php echo URL_ROOT ?>/posts/">Posts</a>
</li>
</ul>
<!-- Right-aligned Navbar Links -->
<ul class="navbar-nav ml-auto">
<?php if (isset($_SESSION['userId'])) : ?>
<!-- Logout Link if User is Logged In -->
<li class="nav-item">
<a class="nav-link" href="<?php echo URL_ROOT ?>/users/logout">Logout</a>
</li>
<?php else : ?>
<!-- Register and Login Links if User is Not Logged In -->
<li class="nav-item">
<a class="nav-link" href="<?php echo URL_ROOT ?>/users/register">Register</a>
</li>
<li class="nav-item">
<a class="nav-link" href="<?php echo URL_ROOT ?>/users/login">Login</a>
</li>
<?php endif; ?>
</ul>
</div>
</div>
</nav>
+9
View File
@@ -0,0 +1,9 @@
<?php require APP_ROOT . '/views/inc/header.php'; ?>
<div class="jumbotron jumbotron-fluid text-center">
<div class="container">
<h1 class="display-3"><?PHP echo $data['title']; ?></h1>
<p class="lead"><?PHP echo $data['description'] ?></p>
<p class="lead"><span class="h5">Version: </span> <?PHP echo $data['version'] ?></p>
</div>
</div>
<?php require APP_ROOT . '/views/inc/footer.php'; ?>
+8
View File
@@ -0,0 +1,8 @@
<?php require APP_ROOT . '/views/inc/header.php'; ?>
<div class="jumbotron jumbotron-fluid text-center">
<div class="container">
<h1 class="display-3"><?php echo $data['title']; ?></h1>
<p class="lead"><?PHP echo $data['description'] ?></p>
</div>
</div>
<?php require APP_ROOT . '/views/inc/footer.php'; ?>
+28
View File
@@ -0,0 +1,28 @@
<?PHP require APP_ROOT.'/views/inc/header.php' ?>
<a href="<?PHP echo URL_ROOT ?>/posts/index" class="btn btn-secondary"><i class="fa fa-backward"></i> Back</a>
<div class="card card-body bg-light mt-5">
<h2>Add Post</h2>
<p>Create a new post.</p>
<form action="<?PHP echo URL_ROOT ?>/posts/add" method="post">
<div class="form-group">
<label for="title">Title: <sup class="is-invalid">*</sup></label>
<input type="text" name="title" id="" class="form-control form-control-lg <?PHP echo (!empty($data['titleErr'])) ? 'is-invalid' : '' ?>" value="<?PHP echo $data['title']?>" />
<span class="invalid-feedback"><?PHP echo $data['titleErr'] ?></span>
</div>
<div class="form-group">
<label for="summary">Summary: <sup class="is-invalid">*</sup></label>
<input type="text" name="summary" id="" class="form-control form-control-lg <?PHP echo (!empty($data['summaryErr'])) ? 'is-invalid' : '' ?>" value="<?PHP echo $data['summary']?>" />
<span class="invalid-feedback"><?PHP echo $data['summaryErr'] ?></span>
</div>
<div class="form-group">
<label for="body">Body: <sup class="is-invalid">*</sup></label>
<textarea name="body" id="" class="form-control form-control-lg <?PHP echo (!empty($data['bodyErr'])) ? 'is-invalid' : '' ?>"><?PHP echo $data['body']?></textarea>
<span class="invalid-feedback"><?PHP echo $data['bodyErr'] ?></span>
</div>
<input type="submit" class="btn btn-primary" value="Submit">
</form>
</div>
<?PHP require APP_ROOT.'/views/inc/footer.php' ?>
+28
View File
@@ -0,0 +1,28 @@
<?PHP require APP_ROOT.'/views/inc/header.php' ?>
<a href="<?PHP echo URL_ROOT ?>/posts/index" class="btn btn-secondary"><i class="fa fa-backward"></i> Back</a>
<div class="card card-body bg-light mt-5">
<h2>Edit Post</h2>
<p>Create a new post.</p>
<form action="<?PHP echo URL_ROOT ?>/posts/edit/<?PHP echo $data['id'] ?>" method="post">
<div class="form-group">
<label for="title">Title: <sup class="is-invalid">*</sup></label>
<input type="text" name="title" id="" class="form-control form-control-lg <?PHP echo (!empty($data['titleErr'])) ? 'is-invalid' : '' ?>" value="<?PHP echo $data['title']?>" />
<span class="invalid-feedback"><?PHP echo $data['titleErr'] ?></span>
</div>
<div class="form-group">
<label for="summary">Summary: <sup class="is-invalid">*</sup></label>
<input type="text" name="summary" id="" class="form-control form-control-lg <?PHP echo (!empty($data['summaryErr'])) ? 'is-invalid' : '' ?>" value="<?PHP echo $data['summary']?>" />
<span class="invalid-feedback"><?PHP echo $data['summaryErr'] ?></span>
</div>
<div class="form-group">
<label for="body">Body: <sup class="is-invalid">*</sup></label>
<textarea name="body" id="" class="form-control form-control-lg <?PHP echo (!empty($data['bodyErr'])) ? 'is-invalid' : '' ?>"><?PHP echo $data['body']?></textarea>
<span class="invalid-feedback"><?PHP echo $data['bodyErr'] ?></span>
</div>
<input type="submit" class="btn btn-primary" value="Submit">
</form>
</div>
<?PHP require APP_ROOT.'/views/inc/footer.php' ?>
+23
View File
@@ -0,0 +1,23 @@
<?php require APP_ROOT . '/views/inc/header.php'; ?>
<?PHP echo message('post_message'); ?>
<div class="row mb-3">
<div class="col-md-6">
<h1>Posts</h1>
</div>
<div class="col-md-6">
<a href="<?PHP echo URL_ROOT; ?>/posts/add" class="btn btn-primary pull-right">
<i class="fa fa-pencil"></i> Add Post
</a>
</div>
</div>
<?PHP foreach ($data['posts'] as $post) : ?>
<div class="card card-body mb-3">
<h4 class="card-title"><?PHP echo $post->title ?></h4>
<div class="bg-light p-2 mb-3">
written by: <?PHP echo $post->name ?> on <?PHP echo $post->postCreated ?>
</div>
<p class="card-text"><?PHP echo $post->summary ?></p>
<a href="<?PHP echo URL_ROOT ?>/posts/show/<?PHP echo $post->postId ?>" class="btn btn-dark">Read More</a>
</div>
<?PHP endforeach; ?>
<?php require APP_ROOT . '/views/inc/footer.php'; ?>
+21
View File
@@ -0,0 +1,21 @@
<?PHP require APP_ROOT.'/views/inc/header.php' ?>
<a href="<?PHP echo URL_ROOT ?>/posts/index" class="btn btn-secondary"><i class="fa fa-backward"></i> Back</a>
<div class="card card-body bg-light mt-5">
<h1><?PHP echo $data['post']->title ?></h1>
<div class="bg-secondary text-white p-2 mb-3">
Written by <?PHP echo $data['user']->name ?> on <?PHP echo $data['post']->created_at ?></div>
</div>
<p><?PHP echo $data['post']->body ?></p>
<?PHP if ($data['post']->user_id == $_SESSION['userId']) : ?>
<hr>
<a href="<?PHP echo URL_ROOT ?>/posts/edit/<?PHP echo $data['post']->id ?>" class="btn btn-dark"><i class="fa fa-edit"></i> Edit Post</a>
<form method="post" action="<?PHP echo URL_ROOT ?>/posts/delete/<?PHP echo $data['post']->id ?>" class="pull-right">
<input type="submit" value="Delete Post" class="btn btn-danger">
</form>
<?PHP endif;?>
<?PHP require APP_ROOT.'/views/inc/footer.php' ?>
+35
View File
@@ -0,0 +1,35 @@
<?PHP require APP_ROOT.'/views/inc/header.php' ?>
<div class="row">
<div class="col-md-6 mx-auto">
<div class="card card-body bg-light mt-5">
<?PHP echo message('reg_success') ?>
<h2>Login to your Account</h2>
<p>Fill in your information to continue.</p>
<form action="<?PHP echo URL_ROOT ?>/users/login" method="post">
<div class="form-group">
<label for="email">Email: <sup class="is-invalid">*</sup></label>
<input type="email" name="email" id="" class="form-control form-control-lg <?PHP echo (!empty($data['emailErr'])) ? 'is-invalid' : '' ?>" value="<?PHP echo $data['email']?>" />
<span class="invalid-feedback"><?PHP echo $data['emailErr'] ?></span>
</div>
<div class="form-group">
<label for="password">Password: <sup class="is-invalid">*</sup></label>
<input type="password" name="password" id="" class="form-control form-control-lg <?PHP echo (!empty($data['passErr'])) ? 'is-invalid' : '' ?>" value="<?PHP echo $data['password']?>" />
<span class="invalid-feedback"><?PHP echo $data['passErr'] ?></span>
</div>
<div class="row">
<div class="col">
<input type="submit" value="Login" class="btn btn-success btn-block" />
</div>
<div class="col">
<a href="<?PHP echo URL_ROOT ?>/users/register" class="btn btn-light btn-block">Register</a>
</div>
</div>
</form>
</div>
</div>
</div>
<?PHP require APP_ROOT.'/views/inc/footer.php' ?>
+42
View File
@@ -0,0 +1,42 @@
<?PHP require APP_ROOT.'/views/inc/header.php' ?>
<div class="row">
<div class="col-md-6 mx-auto">
<div class="card card-body bg-light mt-5">
<h2>Create an Account</h2>
<p>Fill out to Register</p>
<form action="<?PHP echo URL_ROOT ?>/users/register" method="post">
<div class="form-group">
<label for="username">Username: <sup class="is-invalid">*</sup></label>
<input type="text" name="username" id="" class="form-control form-control-lg <?PHP echo (!empty($data['usernameErr'])) ? 'is-invalid' : '' ?>" value="<?PHP echo $data['username']?>" />
<span class="invalid-feedback"><?PHP echo $data['usernameErr'] ?></span>
</div>
<div class="form-group">
<label for="email">Email: <sup class="is-invalid">*</sup></label>
<input type="text" name="email" id="" class="form-control form-control-lg <?PHP echo (!empty($data['emailErr'])) ? 'is-invalid' : '' ?>" value="<?PHP echo $data['email']?>" />
<span class="invalid-feedback"><?PHP echo $data['emailErr'] ?></span>
</div>
<div class="form-group">
<label for="password">Password: <sup class="is-invalid">*</sup></label>
<input type="password" name="password" id="" class="form-control form-control-lg <?PHP echo (!empty($data['passErr'])) ? 'is-invalid' : '' ?>" value="<?PHP echo $data['password']?>" />
<span class="invalid-feedback"><?PHP echo $data['passErr'] ?></span>
</div>
<div class="form-group">
<label for="again">Confirm: <sup class="is-invalid">*</sup></label>
<input type="password" name="again" id="" class="form-control form-control-lg <?PHP echo (!empty($data['againErr'])) ? 'is-invalid' : '' ?>" value="<?PHP echo $data['again']?>" />
<span class="invalid-feedback"><?PHP echo $data['againErr'] ?></span>
</div>
<div class="row">
<div class="col">
<input type="submit" value="Register" class="btn btn-success btn-block" />
</div>
<div class="col">
<a href="<?PHP echo URL_ROOT ?>/users/login" class="btn btn-light btn-block">Already Registered? Login</a>
</div>
</div>
</form>
</div>
</div>
</div>
<?PHP require APP_ROOT.'/views/inc/footer.php' ?>