mirror of
https://github.com/glmdev/eecs448-lab10
synced 2024-10-27 19:14:00 +00:00
Initial commit
This commit is contained in:
commit
5a54fe251d
17
AdminHome.html
Normal file
17
AdminHome.html
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require './configuration.php';
|
||||||
|
|
||||||
|
$page = new common\Page;
|
||||||
|
|
||||||
|
$page->title('EECS 448 Lab 10 - Exercise 4')
|
||||||
|
->header('Admin Home')
|
||||||
|
->writes("
|
||||||
|
<ul>
|
||||||
|
<li><a href=\"" . system_url('ViewUsers.php') . "\">View Users</a></li>
|
||||||
|
<li><a href=\"" . system_url('ViewUserPosts.html') . "\">View Posts by User</a></li>
|
||||||
|
<li><a href=\"" . system_url('DeletePost.html') . "\">Delete Posts</a></li>
|
||||||
|
</ul>
|
||||||
|
");
|
||||||
|
|
||||||
|
$page->write();
|
16
CreatePosts.html
Normal file
16
CreatePosts.html
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once './configuration.php';
|
||||||
|
|
||||||
|
$page = new common\Page;
|
||||||
|
|
||||||
|
$page->title('Exercise 3 - EECS 448 Lab 10')
|
||||||
|
->header('Create a New Post')
|
||||||
|
->div(function() use($page) {
|
||||||
|
$page->form(system_url('CreatePosts.php'), function() use($page) {
|
||||||
|
$page->writes('<input type="text" name="username" placeholder="Username" required/>')->line_break();
|
||||||
|
$page->writes('<textarea name="content" placeholder="Post content" required></textarea>')->line_break();
|
||||||
|
$page->submit();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
->write();
|
35
CreatePosts.php
Normal file
35
CreatePosts.php
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once './configuration.php';
|
||||||
|
|
||||||
|
$request = common\Request::capture();
|
||||||
|
$page = new common\Page;
|
||||||
|
$users = new app\UserRepository;
|
||||||
|
$posts = new app\PostRepository;
|
||||||
|
|
||||||
|
$page->title('Exercise 3 - EECS 448 Lab 10')
|
||||||
|
->header('Create a New Post');
|
||||||
|
|
||||||
|
if ( !$request->input('username') ) {
|
||||||
|
$page->fail_to('You must specify the username.', system_url('CreatePosts.html'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !$request->input('content') ) {
|
||||||
|
$page->fail_to('You must specify post content.', system_url('CreatePosts.html'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = $users->find_one([ 'username' => $request->input('username') ]);
|
||||||
|
if ( !$user ) {
|
||||||
|
$page->fail_to('Sorry, a user with that username does not exist.', system_url('CreatePosts.html'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$post = $posts->save([
|
||||||
|
'user_id' => $user['user_id'],
|
||||||
|
'content' => $request->input('content'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$page->div(function() use($page) {
|
||||||
|
$page->writes('Post created successfully.');
|
||||||
|
});
|
||||||
|
|
||||||
|
$page->write();
|
14
CreateUser.html
Normal file
14
CreateUser.html
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once './configuration.php';
|
||||||
|
|
||||||
|
$page = new common\Page();
|
||||||
|
|
||||||
|
$page->title('Exercise 2 - EECS 448 Lab 10')
|
||||||
|
->header('Create a New User')
|
||||||
|
->form(system_url('CreateUser.php'), function() use($page) {
|
||||||
|
$page->writes('<input type="text" placeholder="Username" name="username" required/>');
|
||||||
|
$page->submit();
|
||||||
|
});
|
||||||
|
|
||||||
|
$page->write();
|
29
CreateUser.php
Normal file
29
CreateUser.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once './configuration.php';
|
||||||
|
|
||||||
|
$request = common\Request::capture();
|
||||||
|
$page = new common\Page;
|
||||||
|
$users = new app\UserRepository;
|
||||||
|
|
||||||
|
$page->title('Exercise 2 - EECS 448 Lab 10')
|
||||||
|
->header('Create a New User');
|
||||||
|
|
||||||
|
if ( !$request->input('username') ) {
|
||||||
|
$page->fail_to('You must specify a username.', system_url('CreateUser.html'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$existing_user = $users->find_one([ 'username' => $request->input('username') ]);
|
||||||
|
if ( $existing_user ) {
|
||||||
|
$page->fail_to('A user with that username already exists.', system_url('CreateUser.html'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$new_user = $users->save([
|
||||||
|
'username' => $request->input('username'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$page->div(function() use($page, $new_user) {
|
||||||
|
$page->writes('User ' . $new_user['username'] . ' created successfully.');
|
||||||
|
});
|
||||||
|
|
||||||
|
$page->write();
|
41
DeletePost.html
Normal file
41
DeletePost.html
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require './configuration.php';
|
||||||
|
|
||||||
|
$db = new common\database\Connection;
|
||||||
|
$db->connect();
|
||||||
|
|
||||||
|
$page = new common\Page;
|
||||||
|
|
||||||
|
$page->title('EECS 448 Lab 10 - Exercise 7')
|
||||||
|
->header('Delete Posts');
|
||||||
|
|
||||||
|
$query = "SELECT post.post_id, user.username, post.content
|
||||||
|
FROM posts post
|
||||||
|
LEFT JOIN users user
|
||||||
|
ON user.user_id = post.post_id";
|
||||||
|
|
||||||
|
$results = $db->fetch($query);
|
||||||
|
|
||||||
|
$post_display = array_merge([
|
||||||
|
['Post ID', 'Username', 'Content', 'Delete?'],
|
||||||
|
], array_map(function($post) {
|
||||||
|
$id = 'post-' . $post['post_id'];
|
||||||
|
|
||||||
|
return [
|
||||||
|
$post['post_id'],
|
||||||
|
$post['username'],
|
||||||
|
$post['content'],
|
||||||
|
'<input type="checkbox" id="' . $id . '" name="' . $id . '" value="yes">
|
||||||
|
<label for="' . $id . '">Delete</label>'
|
||||||
|
];
|
||||||
|
}, $results));
|
||||||
|
|
||||||
|
$page->writes('<p>Select the posts you want to delete.')
|
||||||
|
->form(system_url('DeletePost.php'), function() use($page, $post_display) {
|
||||||
|
$page->table($post_display)
|
||||||
|
->writes('<br>')
|
||||||
|
->submit();
|
||||||
|
});
|
||||||
|
|
||||||
|
$page->write();
|
24
DeletePost.php
Normal file
24
DeletePost.php
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require './configuration.php';
|
||||||
|
|
||||||
|
$request = common\Request::capture();
|
||||||
|
$page = new common\Page;
|
||||||
|
$posts = new app\PostRepository;
|
||||||
|
|
||||||
|
$post_ids = [];
|
||||||
|
foreach ( $request->input() as $post_key => $value ) {
|
||||||
|
if ( $value !== 'yes' ) continue;
|
||||||
|
|
||||||
|
$post_id = explode('-', $post_key)[1];
|
||||||
|
$post_ids[] = $post_id;
|
||||||
|
|
||||||
|
$posts->delete(['post_id' => $post_id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$page->title('EECS 448 Lab 10 - Exercise 7')
|
||||||
|
->header('Posts Deleted')
|
||||||
|
->writes('<p>Posts with the following IDs were deleted: ' . implode(', ', $post_ids) . '</p>')
|
||||||
|
->writes('<a href="' . system_url('AdminHome.html') . '">Admin Home</a>');
|
||||||
|
|
||||||
|
$page->write();
|
26
ViewUserPosts.html
Normal file
26
ViewUserPosts.html
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require './configuration.php';
|
||||||
|
|
||||||
|
$page = new common\Page;
|
||||||
|
$users = new app\UserRepository;
|
||||||
|
|
||||||
|
// Generate the user options
|
||||||
|
$user_options = array_map(function($user) {
|
||||||
|
return '<option value="' . $user['user_id'] . '">' . $user['username'] . '</option>';
|
||||||
|
}, $users->find());
|
||||||
|
|
||||||
|
$page->title('EECS 448 Lab 10 - Exercise 6')
|
||||||
|
->header('View Posts by User')
|
||||||
|
->form(system_url('ViewUserPosts.php'), function() use($page, $user_options) {
|
||||||
|
$page->writes('
|
||||||
|
<label for="user-select">Select a user:</label>
|
||||||
|
<select name="user_id" id="user-select" style="min-width: 300px;" required>
|
||||||
|
' . implode("\n", $user_options) . '
|
||||||
|
</select>
|
||||||
|
');
|
||||||
|
|
||||||
|
$page->submit();
|
||||||
|
});
|
||||||
|
|
||||||
|
$page->write();
|
44
ViewUserPosts.php
Normal file
44
ViewUserPosts.php
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require './configuration.php';
|
||||||
|
|
||||||
|
$request = common\Request::capture();
|
||||||
|
$page = new common\Page;
|
||||||
|
$users = new app\UserRepository;
|
||||||
|
$posts = new app\PostRepository;
|
||||||
|
|
||||||
|
$page->title('EECS 448 Lab 10 - Exercise 6')
|
||||||
|
->header('View Posts by User');
|
||||||
|
|
||||||
|
if ( !$request->input('user_id') ) {
|
||||||
|
$page->fail_to('Please select a user.', system_url('ViewUserPosts.html'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = $users->find_by_id($request->input('user_id'));
|
||||||
|
|
||||||
|
if ( !$user ) {
|
||||||
|
$page->fail_to('Invalid user.', system_url('ViewUserPosts.html'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$user_posts = $posts->find([
|
||||||
|
'user_id' => $user['user_id'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$post_display = array_merge([
|
||||||
|
['Post ID', 'Post Content']
|
||||||
|
], array_map(function($post) {
|
||||||
|
return [$post['post_id'], $post['content']];
|
||||||
|
}, $user_posts));
|
||||||
|
|
||||||
|
|
||||||
|
$page->div(function() use($page, $user) {
|
||||||
|
$page->writes('<b>Posts by ' . $user['username'] . ':</b>');
|
||||||
|
});
|
||||||
|
|
||||||
|
$page->table($post_display);
|
||||||
|
|
||||||
|
$page->div(function() use($page) {
|
||||||
|
$page->writes('<a href="' . system_url('ViewUserPosts.html') . '">Select a different user</a>');
|
||||||
|
});
|
||||||
|
|
||||||
|
$page->write();
|
23
ViewUsers.php
Normal file
23
ViewUsers.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require './configuration.php';
|
||||||
|
|
||||||
|
$page = new common\Page;
|
||||||
|
$users = new app\UserRepository;
|
||||||
|
|
||||||
|
$page->title('EECS 448 Lab 10 - Exercise 5')
|
||||||
|
->header('View Registered Users');
|
||||||
|
|
||||||
|
$registered_users = $users->find();
|
||||||
|
|
||||||
|
$table_display = array_merge([
|
||||||
|
// Add the table headers
|
||||||
|
['User ID', 'Username'],
|
||||||
|
], array_map(function($user) {
|
||||||
|
// Map from associative array to keyed
|
||||||
|
return array_values($user);
|
||||||
|
}, $registered_users));
|
||||||
|
|
||||||
|
$page->table($table_display);
|
||||||
|
|
||||||
|
$page->write();
|
11
app/PostRepository.php
Normal file
11
app/PostRepository.php
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app;
|
||||||
|
|
||||||
|
use common\database\Repository;
|
||||||
|
|
||||||
|
class PostRepository extends Repository {
|
||||||
|
protected $table = 'posts';
|
||||||
|
protected $primary_key = 'post_id';
|
||||||
|
protected $fields = ['post_id', 'user_id', 'content'];
|
||||||
|
}
|
11
app/UserRepository.php
Normal file
11
app/UserRepository.php
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app;
|
||||||
|
|
||||||
|
use common\database\Repository;
|
||||||
|
|
||||||
|
class UserRepository extends Repository {
|
||||||
|
protected $table = 'users';
|
||||||
|
protected $primary_key = 'user_id';
|
||||||
|
protected $fields = ['user_id', 'username'];
|
||||||
|
}
|
28
assets/common.css
Normal file
28
assets/common.css
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
table, th, td {
|
||||||
|
border: 1px solid darkgrey;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
th, td {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.common-page {
|
||||||
|
margin: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
padding: 5px;
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button[type=submit] {
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
margin: 10px;
|
||||||
|
padding: 5px;
|
||||||
|
min-width: 400px;
|
||||||
|
min-height: 200px;
|
||||||
|
}
|
208
common/Page.php
Normal file
208
common/Page.php
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace common;
|
||||||
|
|
||||||
|
class Page {
|
||||||
|
protected $_title;
|
||||||
|
protected $_writers = [];
|
||||||
|
protected $_wrote_pre = false;
|
||||||
|
protected $_wrote_post = false;
|
||||||
|
protected $_writing = false;
|
||||||
|
protected $_scripts = [];
|
||||||
|
protected $_styles = [];
|
||||||
|
|
||||||
|
public function calls(callable $writer) {
|
||||||
|
$this->_writers[] = $writer;
|
||||||
|
|
||||||
|
if ( $this->_writing ) {
|
||||||
|
$writer();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function writes($string) {
|
||||||
|
$this->calls(function() use($string) {
|
||||||
|
echo $string;
|
||||||
|
});
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function script($src) {
|
||||||
|
$this->_scripts[] = $src;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function stylesheet($src) {
|
||||||
|
$this->_styles[] = $src;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function title($title = null) {
|
||||||
|
if ( $title ) {
|
||||||
|
$this->_title = $title;
|
||||||
|
return $this;
|
||||||
|
} else {
|
||||||
|
return $this->_title;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function header($string = null) {
|
||||||
|
if ( !$string ) $string = $this->title();
|
||||||
|
|
||||||
|
return $this->writes('<h1>' . $string . '</h1>');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function form($submit, callable $inner) {
|
||||||
|
$this->writes('<form method="POST" action="' . $submit . '">');
|
||||||
|
$this->calls($inner);
|
||||||
|
$this->writes('</form>');
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function submit($text = 'Submit') {
|
||||||
|
$this->writes('<button type="submit">' . $text . '</button>');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function div(callable $inner) {
|
||||||
|
$this->writes('<div class="common-page">');
|
||||||
|
$this->calls($inner);
|
||||||
|
$this->writes('</div>');
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function line_break() {
|
||||||
|
$this->writes('<br/>');
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function table($nested_array) {
|
||||||
|
if ( is_array($nested_array) ) {
|
||||||
|
$this->calls(function() use($nested_array) {
|
||||||
|
echo '<table style="width: 100%;">';
|
||||||
|
|
||||||
|
foreach ( $nested_array as $row_idx => $row ) {
|
||||||
|
echo '<tr>';
|
||||||
|
|
||||||
|
foreach ( $row as $col_idx => $col ) {
|
||||||
|
$tag = $row_idx === 0 ? 'th' : 'td';
|
||||||
|
|
||||||
|
echo "<{$tag}>{$col}</{$tag}>";
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '</tr>';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '</table>';
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$this->writes('<table style="width: 100%;">');
|
||||||
|
$this->calls($nested_array);
|
||||||
|
$this->writes('</table>');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function table_row_cell(callable $inner, $span = 1) {
|
||||||
|
$this->table_row(function() use($inner, $span) {
|
||||||
|
$this->writes('<td colspan="' . $span . '">');
|
||||||
|
$this->calls($inner);
|
||||||
|
$this->writes('</td>');
|
||||||
|
});
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function table_row($inner = null) {
|
||||||
|
$this->writes('<tr>');
|
||||||
|
if ( $inner ) $this->calls($inner);
|
||||||
|
$this->writes('</tr>');
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function table_head(callable $inner) {
|
||||||
|
$this->writes('<th>');
|
||||||
|
$this->calls($inner);
|
||||||
|
$this->writes('</th>');
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function table_cell($inner = null) {
|
||||||
|
$this->writes('<td>');
|
||||||
|
if ( $inner ) $this->calls($inner);
|
||||||
|
$this->writes('</td>');
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function fail_to($message, $redirect_url) {
|
||||||
|
$this->writes('<p>' . $message . '</p>')
|
||||||
|
->writes('<p><a href="' . $redirect_url . '">Try Again</a></p>')
|
||||||
|
->write();
|
||||||
|
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function preamble() {
|
||||||
|
if ( $this->_wrote_pre ) return;
|
||||||
|
$this->_styles[] = system_url('assets/common.css');
|
||||||
|
|
||||||
|
$styles = [];
|
||||||
|
foreach ( $this->_styles as $style ) {
|
||||||
|
$styles[] = '<link rel="stylesheet" href="' . $style . '"/>';
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title><?= $this->_title ?></title>
|
||||||
|
<?= implode("\n", $styles) ?>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$this->_wrote_pre = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function postamble() {
|
||||||
|
if ( $this->_wrote_post ) return;
|
||||||
|
|
||||||
|
$scripts = [];
|
||||||
|
foreach ( $this->_scripts as $script ) {
|
||||||
|
$scripts[] = '<script src="' . $script . '"></script>';
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
<?= implode("\n", $scripts) ?>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$this->_wrote_post = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function write() {
|
||||||
|
$this->_writing = true;
|
||||||
|
$this->preamble();
|
||||||
|
foreach ( $this->_writers as $writer ) {
|
||||||
|
$writer();
|
||||||
|
}
|
||||||
|
$this->postamble();
|
||||||
|
$this->_writing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function compile() {
|
||||||
|
ob_start();
|
||||||
|
$this->_wrote_pre = false;
|
||||||
|
$this->_wrote_post = false;
|
||||||
|
$this->write();
|
||||||
|
$this->_wrote_pre = false;
|
||||||
|
$this->_wrote_post = false;
|
||||||
|
return ob_get_clean();
|
||||||
|
}
|
||||||
|
}
|
40
common/Request.php
Normal file
40
common/Request.php
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace common;
|
||||||
|
|
||||||
|
class Request {
|
||||||
|
protected $_get = [];
|
||||||
|
protected $_post = [];
|
||||||
|
|
||||||
|
public static function capture() {
|
||||||
|
$req = new static();
|
||||||
|
$req->_get = $_GET;
|
||||||
|
$req->_post = $_POST;
|
||||||
|
return $req;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function input($path = null) {
|
||||||
|
if ( !$path ) {
|
||||||
|
return array_merge($this->_get, $this->_post);
|
||||||
|
}
|
||||||
|
|
||||||
|
$path_parts = explode('.', $path);
|
||||||
|
|
||||||
|
$get_value = $this->_get;
|
||||||
|
foreach ( $path_parts as $part ) {
|
||||||
|
if ( $get_value ) {
|
||||||
|
$get_value = $get_value[$part];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$post_value = $this->_post;
|
||||||
|
foreach ( $path_parts as $part ) {
|
||||||
|
if ( $post_value ) {
|
||||||
|
$post_value = $post_value[$part];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $get_value ) return $get_value;
|
||||||
|
if ( $post_value ) return $post_value;
|
||||||
|
}
|
||||||
|
}
|
20
common/autoload.php
Normal file
20
common/autoload.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class AutoLoad {
|
||||||
|
public static function load($class_name) {
|
||||||
|
$file = str_replace("\\", '/', $class_name) . '.php';
|
||||||
|
$path = system_path($file);
|
||||||
|
|
||||||
|
if ( file_exists($path) ) {
|
||||||
|
include_system($file, false);
|
||||||
|
|
||||||
|
if ( class_exists($class_name) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spl_autoload_register('AutoLoad::load');
|
81
common/database/Connection.php
Normal file
81
common/database/Connection.php
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace common\database;
|
||||||
|
|
||||||
|
class Connection {
|
||||||
|
protected static $mysqli;
|
||||||
|
|
||||||
|
protected $config;
|
||||||
|
|
||||||
|
function __construct() {
|
||||||
|
$this->config = config('database');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function connect() {
|
||||||
|
if ( !static::$mysqli ) {
|
||||||
|
static::$mysqli = new \mysqli(
|
||||||
|
$this->config['url'],
|
||||||
|
$this->config['username'],
|
||||||
|
$this->config['password'],
|
||||||
|
$this->config['database']
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( static::$mysqli->connect_errno ) {
|
||||||
|
throw new \Exception('Unable to connect to database: ' . static::$mysqli->connect_error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function escape($value) {
|
||||||
|
return static::$mysqli->real_escape_string($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function execute($query, $args = [], $returns_statement = false) {
|
||||||
|
$statement = static::$mysqli->prepare($query);
|
||||||
|
|
||||||
|
if ( sizeof($args) > 0 ) {
|
||||||
|
$types = '';
|
||||||
|
foreach ( $args as $arg ) {
|
||||||
|
if ( is_int($arg) ) {
|
||||||
|
$types .= 'i';
|
||||||
|
} else if ( is_float($arg) || is_double($arg) ) {
|
||||||
|
$types .= 'd';
|
||||||
|
} else if ( is_string($arg) ) {
|
||||||
|
$types .= 's';
|
||||||
|
} else {
|
||||||
|
$types .= 'b';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$statement->bind_param($types, ...$args);
|
||||||
|
}
|
||||||
|
|
||||||
|
$statement->execute();
|
||||||
|
|
||||||
|
if ( $returns_statement ) return $statement;
|
||||||
|
return $statement->get_result();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function insert($query, $args = []) {
|
||||||
|
$statement = $this->execute($query, $args, true);
|
||||||
|
return $statement->insert_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function fetch($query, $args = []) {
|
||||||
|
$result = $this->execute($query, $args);
|
||||||
|
|
||||||
|
$rows = [];
|
||||||
|
while ( $row = $result->fetch_assoc() ) {
|
||||||
|
$rows[] = $row;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function close() {
|
||||||
|
if ( static::$mysqli ) {
|
||||||
|
static::$mysqli->close();
|
||||||
|
static::$mysqli = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
134
common/database/Repository.php
Normal file
134
common/database/Repository.php
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace common\database;
|
||||||
|
|
||||||
|
class Repository {
|
||||||
|
protected $table;
|
||||||
|
protected $primary_key;
|
||||||
|
protected $fields = [];
|
||||||
|
|
||||||
|
protected $connection;
|
||||||
|
|
||||||
|
function __construct() {
|
||||||
|
$this->connection = new Connection();
|
||||||
|
$this->connection->connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
function __destruct() {
|
||||||
|
$this->connection->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create($record) {
|
||||||
|
$fields = [];
|
||||||
|
$arg_parts = [];
|
||||||
|
$args = [];
|
||||||
|
|
||||||
|
foreach ( $this->fields as $field ) {
|
||||||
|
if ( isset($record[$field]) ) {
|
||||||
|
$fields[] = $field;
|
||||||
|
$args[] = $record[$field];
|
||||||
|
$arg_parts[] = '?';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = 'INSERT INTO ' . $this->table . ' (' . implode(', ', $fields) . ') VALUES (' . implode(', ', $arg_parts) . ')';
|
||||||
|
$insert_id = $this->connection->insert($query, $args);
|
||||||
|
|
||||||
|
$record[$this->primary_key] = $insert_id;
|
||||||
|
return $record;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function find_by_id($primary_key) {
|
||||||
|
$query = 'SELECT ' . implode(', ', $this->fields) . ' FROM ' . $this->table . ' WHERE ' . $this->primary_key . ' = ?';
|
||||||
|
$results = $this->connection->fetch($query, [$primary_key]);
|
||||||
|
|
||||||
|
if ( sizeof($results) > 0 ) {
|
||||||
|
return $results[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function find($filter = []) {
|
||||||
|
$query = 'SELECT ' . implode(', ', $this->fields) . ' FROM ' . $this->table . ' WHERE ';
|
||||||
|
list($wheres, $where_args) = $this->build_wheres_from_filter($filter);
|
||||||
|
|
||||||
|
$query .= implode(' AND ', $wheres);
|
||||||
|
$query .= ' ORDER BY ' . $this->primary_key . ' ASC';
|
||||||
|
return $this->connection->fetch($query, $where_args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function find_one($filter = []) {
|
||||||
|
$query = 'SELECT ' . implode(', ', $this->fields) . ' FROM ' . $this->table . ' WHERE ';
|
||||||
|
list($wheres, $where_args) = $this->build_wheres_from_filter($filter);
|
||||||
|
|
||||||
|
$query .= implode(' AND ', $wheres) . ' LIMIT 1';
|
||||||
|
$results = $this->connection->fetch($query, $where_args);
|
||||||
|
|
||||||
|
if ( sizeof($results) > 0 ) {
|
||||||
|
return $results[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update($record) {
|
||||||
|
$query = 'UPDATE ' . $this->table . ' SET ';
|
||||||
|
$query_args = [];
|
||||||
|
|
||||||
|
$sets = [];
|
||||||
|
foreach ( $this->fields as $field ) {
|
||||||
|
if ( isset($record[$field]) ) {
|
||||||
|
$sets[] = $field . '=?';
|
||||||
|
$query_args[] = $record[$field];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = 'UPDATE ' . $this->table . ' SET ' . implode(', ', $sets) . ' WHERE ' . $this->primary_key . ' = ?';
|
||||||
|
$query_args[] = $record[$this->primary_key];
|
||||||
|
|
||||||
|
$this->connection->execute($query, $query_args);
|
||||||
|
return $record;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function save($record) {
|
||||||
|
if ( isset($record[$this->primary_key]) ) {
|
||||||
|
return $this->update($record);
|
||||||
|
} else {
|
||||||
|
return $this->create($record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete($record) {
|
||||||
|
$primary_key = $record[$this->primary_key];
|
||||||
|
|
||||||
|
$query = 'DELETE FROM ' . $this->table . ' WHERE ' . $this->primary_key . ' = ?';
|
||||||
|
$this->connection->execute($query, [$primary_key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function build_wheres_from_filter($filter = []) {
|
||||||
|
if ( !$filter ) {
|
||||||
|
return [['1=1'], []];
|
||||||
|
}
|
||||||
|
|
||||||
|
$wheres = [];
|
||||||
|
$where_args = [];
|
||||||
|
foreach ( $this->fields as $field ) {
|
||||||
|
if ( isset($filter[$field]) ) {
|
||||||
|
$val = $filter[$field];
|
||||||
|
|
||||||
|
if ( is_string($val) || is_numeric($val) ) {
|
||||||
|
$wheres[] = $field . ' = ?';
|
||||||
|
$where_args[] = $val;
|
||||||
|
} else if ( is_array($val) ) {
|
||||||
|
$where_items = [];
|
||||||
|
|
||||||
|
foreach ( $val as $item ) {
|
||||||
|
$where_items[] = '?';
|
||||||
|
$where_args[] = $item;
|
||||||
|
}
|
||||||
|
|
||||||
|
$wheres[] = $field . ' IN (' . implode(',', $where_items) . ')';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [$wheres, $where_args];
|
||||||
|
}
|
||||||
|
}
|
18
common/functions_config.php
Normal file
18
common/functions_config.php
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
function config($path, $default_value = null) {
|
||||||
|
$parts = explode('.', $path);
|
||||||
|
|
||||||
|
if ( !$parts[0] ) {
|
||||||
|
return $default_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
$config = require_system('config/' . $parts[0] . '.php');
|
||||||
|
foreach ( $parts as $i => $part ) {
|
||||||
|
if ( $i !== 0 && $config ) {
|
||||||
|
$config = $config[$part];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $config;
|
||||||
|
}
|
8
common/functions_debugging.php
Normal file
8
common/functions_debugging.php
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
function dd($something) {
|
||||||
|
echo "<pre><code>";
|
||||||
|
var_dump($something);
|
||||||
|
echo "</code></pre>";
|
||||||
|
exit;
|
||||||
|
}
|
54
common/functions_system.php
Normal file
54
common/functions_system.php
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
function system_root() {
|
||||||
|
$root = dirname(dirname(__FILE__));
|
||||||
|
return $root;
|
||||||
|
}
|
||||||
|
|
||||||
|
function system_path($path) {
|
||||||
|
if ( $path[0] === '/' ) {
|
||||||
|
$path = substr($path, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode('/', [system_root(), $path]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function require_system($path, $once = true) {
|
||||||
|
if ( $once ) {
|
||||||
|
return require_once system_path($path);
|
||||||
|
} else {
|
||||||
|
return require system_path($path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function include_system($path, $once = true) {
|
||||||
|
if ( $once ) {
|
||||||
|
return include_once system_path($path);
|
||||||
|
} else {
|
||||||
|
return include system_path($path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function system_url($path) {
|
||||||
|
if ( $path[0] === '/' ) {
|
||||||
|
$path = substr($path, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode('/', [SYSTEM_URL, $path]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function system_redirect($path) {
|
||||||
|
header('Location: ' . system_url($path));
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
function no_direct_access() {
|
||||||
|
$key = array_search(__FUNCTION__, array_column(debug_backtrace(), 'function'));
|
||||||
|
$caller_file = debug_backtrace()[$key]['file'];
|
||||||
|
|
||||||
|
if ( $caller_file === $_SERVER['SCRIPT_FILENAME'] ) {
|
||||||
|
header("HTTP/1.1 401 Unauthorized");
|
||||||
|
echo 'Forbidden';
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
8
config/database.php
Normal file
8
config/database.php
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'url' => 'mysql.eecs.ku.edu',
|
||||||
|
'username' => 'garretmills',
|
||||||
|
'password' => '', // omitted for public repo
|
||||||
|
'database' => 'garretmills',
|
||||||
|
];
|
11
configuration.php
Normal file
11
configuration.php
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
|
||||||
|
!defined('SYSTEM_URL') && define('SYSTEM_URL', 'https://people.eecs.ku.edu/~g582m300/eecs448-lab10');
|
||||||
|
|
||||||
|
include_once dirname(__FILE__).'/common/functions_debugging.php';
|
||||||
|
include_once dirname(__FILE__).'/common/functions_system.php';
|
||||||
|
include_once dirname(__FILE__).'/common/functions_config.php';
|
||||||
|
include_once dirname(__FILE__).'/common/autoload.php';
|
10
index.html
Normal file
10
index.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<h1>Simple Posts</h1>
|
||||||
|
<ul>
|
||||||
|
<li><a href="CreateUser.html">Create User</a></li>
|
||||||
|
<li><a href="CreatePosts.html">Create Post</a></li>
|
||||||
|
<li><a href="AdminHome.html">Admin Home</a></li>
|
||||||
|
</ul>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue
Block a user