Minggu 17 November 2019
This commit is contained in:
commit
4d29a48f79
59
README.md
Normal file
59
README.md
Normal file
@ -0,0 +1,59 @@
|
||||
# Metaforums
|
||||
An online web-based discussion forum application
|
||||
|
||||
## Project Structure
|
||||
This project is separated between the frontend and the backend application.
|
||||
- backend/
|
||||
The backend of this application is written in PHP, and is API focused.
|
||||
- index.php
|
||||
The main handler of backend functions. Handles routing, loading of Mitsumine services, and conversion of array responses to JSON.
|
||||
- Mitsumine/
|
||||
Mitsumine is a set of custom-written helper classes to consolidate frequently used code.
|
||||
- Mitsumine/HTTP
|
||||
Mitsumine HTTP contains a number of abstractions for HTTP, such as Request class
|
||||
- Mitsumine/Services
|
||||
Mitsumine Services contains a number of service classes for common functionality such as Database and Session.
|
||||
- Application/
|
||||
Application contains classes that are the core of the application itself
|
||||
- Controllers/
|
||||
Controllers contain controllers that return HTTP responses
|
||||
- frontend/
|
||||
The frontend of this application, written in HTML and utilizes T
|
||||
- index.php
|
||||
This index file allows serving both frontend and backend from one endpoint.
|
||||
|
||||
## Software Stack
|
||||
|
||||
The software is tested on the Apache server and PHP 7.3 on Arch Linux.
|
||||
|
||||
## Backend
|
||||
|
||||
The database used is MariaDB 10.4.8
|
||||
|
||||
## External frontend libraries used
|
||||
|
||||
### Vue.js
|
||||
|
||||
Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web
|
||||
|
||||
Vue.js allows for interactivity while being less cumbersome than manipulating the DOM manually e.g. with jQuery.
|
||||
|
||||
[Project Website](https://vuejs.org)
|
||||
|
||||
### jQuery
|
||||
|
||||
jQuery is a feature-rich JavaScript library.
|
||||
|
||||
Here, jQuery is mainly used for its AJAX functionality.
|
||||
|
||||
[Project Website](https://jquery.com)
|
||||
|
||||
## CSS Frameworks and Styles used
|
||||
|
||||
### Tailwind
|
||||
|
||||
Tailwind is a utility-first CSS framework for rapidly building custom designs
|
||||
|
||||
[Project Website](https://tailwindcss.com)
|
||||
|
||||
## Additional Development
|
12
backend/Application/Controllers/IndexController.php
Normal file
12
backend/Application/Controllers/IndexController.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
namespace Application\Controllers;
|
||||
|
||||
use Mitsumine\HTTP\Request;
|
||||
|
||||
class IndexController {
|
||||
public function index(Request $request) {
|
||||
return [
|
||||
'mitsumine' => 'yuika'
|
||||
];
|
||||
}
|
||||
}
|
6
backend/Mitsumine/HTTP/Request.php
Normal file
6
backend/Mitsumine/HTTP/Request.php
Normal file
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
namespace Mitsumine\HTTP;
|
||||
|
||||
class Request {
|
||||
|
||||
}
|
12
backend/Mitsumine/Services/Config.php
Normal file
12
backend/Mitsumine/Services/Config.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
namespace Mitsumine\Services;
|
||||
|
||||
class Config {
|
||||
private $configs;
|
||||
public function __construct() {
|
||||
$this->configs = require 'backend/config.php';
|
||||
}
|
||||
public function __call($name, $args) {
|
||||
return $this->configs[$name];
|
||||
}
|
||||
}
|
12
backend/Mitsumine/Services/Database.php
Normal file
12
backend/Mitsumine/Services/Database.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
namespace Mitsumine\Services;
|
||||
|
||||
use Mitsumine\Services\ServiceContainer;
|
||||
|
||||
class Database {
|
||||
private $conn;
|
||||
public function __construct() {
|
||||
$config = ServiceContainer::Config();
|
||||
$this->conn = mysqli_connect($config->db_host(),$config->db_user(),$config->db_pass(),$config->db_name());
|
||||
}
|
||||
}
|
21
backend/Mitsumine/Services/ServiceContainer.php
Normal file
21
backend/Mitsumine/Services/ServiceContainer.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
namespace Mitsumine\Services;
|
||||
|
||||
class ServiceContainer{
|
||||
private static $services = [];
|
||||
public static function get($service) {
|
||||
if(!isset(self::$services[$service])) {
|
||||
self::load($service);
|
||||
}
|
||||
return self::$services[$service];
|
||||
}
|
||||
public static function load($service) {
|
||||
$class = 'Mitsumine\\Services\\'.$service;
|
||||
self::$services[$service] = new $class();
|
||||
}
|
||||
public static function __callStatic($name, $args) {
|
||||
// Allow services to be referenced as ServiceContainer::Service()
|
||||
|
||||
return self::get($name);
|
||||
}
|
||||
}
|
14
backend/autoload.php
Normal file
14
backend/autoload.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
/*
|
||||
autoload.php
|
||||
|
||||
Contains a simple autoloader function
|
||||
|
||||
|
||||
*/
|
||||
|
||||
function mitsumine_autoloader($class) {
|
||||
$file = str_replace('\\',DIRECTORY_SEPARATOR,$class);
|
||||
require $file.'.php';
|
||||
}
|
||||
spl_autoload_register('mitsumine_autoloader');
|
7
backend/config.php
Normal file
7
backend/config.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
return [
|
||||
'db_name' => 'metaforums',
|
||||
'db_host' => '127.0.0.1',
|
||||
'db_user' => 'root',
|
||||
'db_pass' => '',
|
||||
];
|
48
backend/index.php
Normal file
48
backend/index.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
require 'autoload.php';
|
||||
|
||||
// Use helper classes from Mitsumine
|
||||
use Mitsumine\HTTP\Request;
|
||||
use Mitsumine\Services\ServiceContainer;
|
||||
|
||||
ServiceContainer::Database();
|
||||
|
||||
// Get all routes
|
||||
$routes = require 'routes.php';
|
||||
|
||||
// Get request URI
|
||||
$uri = $_SERVER['PHP_SELF'];
|
||||
// Cut off index.php
|
||||
$uri = substr($uri,strlen('/index.php'),strlen($uri)-strlen('/index.php'));
|
||||
|
||||
// Build request object to pass to controller
|
||||
$request = new Request();
|
||||
|
||||
$request_method = $_SERVER['REQUEST_METHOD'];
|
||||
|
||||
// Get current route from uri
|
||||
$route = $routes[$request_method.':'.$uri];
|
||||
|
||||
|
||||
// Duar (actually, split the method string to class name and method name)
|
||||
$method_part = explode("@",$route['controller']);
|
||||
|
||||
// Get class name and method name
|
||||
$class = $method_part[0];
|
||||
$method = $method_part[1];
|
||||
|
||||
// Get fully qualified class name of route
|
||||
$fqcn = 'Application\\Controllers\\'.$class;
|
||||
$controller = new $fqcn();
|
||||
|
||||
// Execute method specified in route
|
||||
$result = $controller->$method($request);
|
||||
|
||||
// Convert array to JSON
|
||||
if(is_array($result)) {
|
||||
header('Content-Type: application/json');
|
||||
$result = json_encode($result);
|
||||
}
|
||||
echo $result;
|
||||
|
6
backend/routes.php
Normal file
6
backend/routes.php
Normal file
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
return [
|
||||
'GET:/api' => [
|
||||
'controller' => 'IndexController@index',
|
||||
],
|
||||
];
|
18
frontend/index.html
Normal file
18
frontend/index.html
Normal file
@ -0,0 +1,18 @@
|
||||
<html>
|
||||
<head>
|
||||
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
{{ message }}
|
||||
</div>
|
||||
<script>
|
||||
var app = new Vue({
|
||||
el: '#app',
|
||||
data: {
|
||||
message: 'Yuika!'
|
||||
}
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
18
index.php
Normal file
18
index.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
// Get request URI
|
||||
$uri = $_SERVER['PHP_SELF'];
|
||||
// Cut off index.php
|
||||
$uri = substr($uri,strlen('/index.php'),strlen($uri)-strlen('/index.php'));
|
||||
if(strpos($uri,'/api') !== false && strpos($uri,'/api') == 0) {
|
||||
include 'backend/index.php';
|
||||
} else {
|
||||
// Remove trailing slashes
|
||||
if(substr($uri,strlen($uri)-1,1) == '/') {
|
||||
$uri = substr($uri,0,strlen($uri)-1);
|
||||
}
|
||||
$file = 'frontend'.$uri.'.html';
|
||||
if(!file_exists($file)) {
|
||||
$file = 'frontend'.$uri.'/index.html';
|
||||
}
|
||||
readfile($file);
|
||||
}
|
Loading…
Reference in New Issue
Block a user