Enhance API error handling, add lastError tracking, and implement admin home template
This commit is contained in:
1 parent
ce0777bb33
commit
205f2e2f73
9 files changed
+257
-33
No files matched your search
+42
-10
@@ -16,6 +16,7 @@ class gbAPI {
|
|||||||
private $config;
|
private $config;
|
||||||
private $internal;
|
private $internal;
|
||||||
private $response;
|
private $response;
|
||||||
|
private $lastError;
|
||||||
|
|
||||||
private function b64url_encode($data) {
|
private function b64url_encode($data) {
|
||||||
return rtrim(strtr(base64_encode($data), "+/", "-_"), "=");
|
return rtrim(strtr(base64_encode($data), "+/", "-_"), "=");
|
||||||
@@ -40,6 +41,8 @@ class gbAPI {
|
|||||||
"error_text" => "Authentication failed."
|
"error_text" => "Authentication failed."
|
||||||
];
|
];
|
||||||
|
|
||||||
|
$this->lastError = $data;
|
||||||
|
|
||||||
$this->answer($status, $data, true);
|
$this->answer($status, $data, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -52,17 +55,25 @@ class gbAPI {
|
|||||||
try {
|
try {
|
||||||
$input = json_decode(file_get_contents("php://input"), true);
|
$input = json_decode(file_get_contents("php://input"), true);
|
||||||
} catch (JsonException $error) {
|
} catch (JsonException $error) {
|
||||||
$this->answer(400, [
|
$error_payload = [
|
||||||
"error" => "invalid_body",
|
"error" => "invalid_body",
|
||||||
"error_text" => "Can not read request body: " . $error
|
"error_text" => "Can not read request body: " . $error
|
||||||
]);
|
];
|
||||||
|
|
||||||
|
$this->lastError = $error_payload;
|
||||||
|
|
||||||
|
$this->answer(400, $error_payload, true);
|
||||||
}
|
}
|
||||||
return $input;
|
return $input;
|
||||||
}else{
|
}else{
|
||||||
$this->answer(400, [
|
$error_payload = [
|
||||||
"error" => "false_request_method",
|
"error" => "false_request_method",
|
||||||
"error_text" => "Only POST allowed"
|
"error_text" => "Only POST allowed"
|
||||||
], true);
|
];
|
||||||
|
|
||||||
|
$this->lastError = $error_payload;
|
||||||
|
|
||||||
|
$this->answer(400, $error_payload, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,6 +202,14 @@ class gbAPI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function returnLastError() {
|
||||||
|
if (isset($this->lastError)) {
|
||||||
|
return $this->lastError;
|
||||||
|
}else{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function getAnswer() {
|
function getAnswer() {
|
||||||
if (!isset($this->response)) {
|
if (!isset($this->response)) {
|
||||||
$error = [
|
$error = [
|
||||||
@@ -199,6 +218,8 @@ class gbAPI {
|
|||||||
"error_text" => "API Returned nothing."
|
"error_text" => "API Returned nothing."
|
||||||
];
|
];
|
||||||
|
|
||||||
|
$this->lastError = $error;
|
||||||
|
|
||||||
return $error;
|
return $error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,17 +239,25 @@ class gbAPI {
|
|||||||
$db_path = APP_PATH . $db_name;
|
$db_path = APP_PATH . $db_name;
|
||||||
|
|
||||||
if (!is_file($db_path)) {
|
if (!is_file($db_path)) {
|
||||||
$api->answer(500, [
|
$error_payload = [
|
||||||
"error" => "database_not_found",
|
"error" => "database_not_found",
|
||||||
"error_text" => "The Database was not found."
|
"error_text" => "The Database was not found."
|
||||||
], true);
|
];
|
||||||
|
|
||||||
|
$this->lastError = $error_payload;
|
||||||
|
|
||||||
|
$api->answer(500, $error_payload, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_writeable($db_path)) {
|
if (!is_writeable($db_path)) {
|
||||||
$this->answer(500, [
|
$error_payload = [
|
||||||
"error" => "database_not_writeable",
|
"error" => "database_not_writeable",
|
||||||
"error_text" => "The Database is not writeable."
|
"error_text" => "The Database is not writeable."
|
||||||
]);
|
];
|
||||||
|
|
||||||
|
$this->lastError = $error_payload;
|
||||||
|
|
||||||
|
$this->answer(500, $error_payload, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,11 +279,14 @@ class gbAPI {
|
|||||||
$command = "SELECT name, value FROM settings WHERE name = :name";
|
$command = "SELECT name, value FROM settings WHERE name = :name";
|
||||||
|
|
||||||
$value = $this->dbCommand($command, true, true, [":name" => $key]);
|
$value = $this->dbCommand($command, true, true, [":name" => $key]);
|
||||||
|
|
||||||
if (isset($value[0]["value"])) {
|
if (isset($value[0]["value"])) {
|
||||||
return $value[0]["value"];
|
return $value[0]["value"];
|
||||||
}else{
|
}else{
|
||||||
return;
|
$this->answer(500, [
|
||||||
|
"error" => "query_returned_nothing",
|
||||||
|
"error_text" => "The SQL Query Returned nothing usable. Check Database Permissions."
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+17
-4
@@ -9,7 +9,20 @@ if (!isset($internal)) {
|
|||||||
require_once API_DIR . "api.php";
|
require_once API_DIR . "api.php";
|
||||||
$api = new gbAPI(true, $internal);
|
$api = new gbAPI(true, $internal);
|
||||||
|
|
||||||
$api->answer(200, [
|
$auth = $api->checkAuth();
|
||||||
"login" => true,
|
|
||||||
"username" => $api->username
|
$lastError = $api->returnLastError();
|
||||||
]);
|
|
||||||
|
if ($lastError == NULL) {
|
||||||
|
if ($auth) {
|
||||||
|
$api->answer(200, [
|
||||||
|
"login" => true,
|
||||||
|
"username" => $api->username
|
||||||
|
]);
|
||||||
|
}else{
|
||||||
|
$api->answer(401, [
|
||||||
|
"login" => false,
|
||||||
|
"username" => ""
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,7 +10,8 @@ $api = new gbAPI(false, $internal);
|
|||||||
|
|
||||||
// Get Template
|
// Get Template
|
||||||
$template = $api->getSetting("template");
|
$template = $api->getSetting("template");
|
||||||
|
if ($template !== NULL) {
|
||||||
$api->answer(200, [
|
$api->answer(200, [
|
||||||
"template_name" => $template
|
"template_name" => $template
|
||||||
]);
|
]);
|
||||||
|
}
|
||||||
BIN
Binary file not shown.
@@ -16,7 +16,10 @@ $htmlloader = new HTMLLoader();
|
|||||||
$call = new APICall("auth/isauth.php");
|
$call = new APICall("auth/isauth.php");
|
||||||
$response = $call->response;
|
$response = $call->response;
|
||||||
|
|
||||||
if (!isset($response["data"]["login"])) {
|
if (!$response["data"]["login"]) {
|
||||||
$htmlloader->setPage("login");
|
$htmlloader->setPage("login");
|
||||||
$htmlloader->show();
|
$htmlloader->show([], true);
|
||||||
|
}else{
|
||||||
|
$htmlloader->setPage("admin_home");
|
||||||
|
$htmlloader->show([], true);
|
||||||
}
|
}
|
||||||
+16
-11
@@ -4,7 +4,7 @@ class HTMLLoader {
|
|||||||
private $page;
|
private $page;
|
||||||
|
|
||||||
private $templates;
|
private $templates;
|
||||||
private $tempalte_conf;
|
private $template_conf;
|
||||||
|
|
||||||
function __construct() {
|
function __construct() {
|
||||||
// Check if Paths variables exists
|
// Check if Paths variables exists
|
||||||
@@ -13,6 +13,7 @@ class HTMLLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->templates = json_decode(file_get_contents(TEMPLATE_CONF), true);
|
$this->templates = json_decode(file_get_contents(TEMPLATE_CONF), true);
|
||||||
|
$this->getTemplate();
|
||||||
}
|
}
|
||||||
|
|
||||||
function setTemplate($template) {
|
function setTemplate($template) {
|
||||||
@@ -26,6 +27,7 @@ class HTMLLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->template = $template;
|
$this->template = $template;
|
||||||
|
$this->template_conf = file_get_contents(TEMPLATE_PATH . $this->templates[$template]["dir_name"] . "/template.json");
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTemplate() {
|
function getTemplate() {
|
||||||
@@ -38,19 +40,26 @@ class HTMLLoader {
|
|||||||
$this->showError("Template API Returned an error: " . $response["error_text"]);
|
$this->showError("Template API Returned an error: " . $response["error_text"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->template = $response["data"]["template_name"];
|
$template = $response["data"]["template_name"];
|
||||||
|
|
||||||
|
$this->template_conf = json_decode(file_get_contents(TEMPLATE_PATH . $this->templates[$template]["dir_name"] . "/template.json"), true);
|
||||||
|
$this->template = $template;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setPage($page) {
|
function setPage($page) {
|
||||||
$this->page = $page;
|
if (!array_key_exists($page, $this->template_conf)) {
|
||||||
|
$this->showError("Page " . $page . " for template " . $this->template . " not found.");
|
||||||
|
}else{
|
||||||
|
$this->page = $page;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function showError($error) {
|
function showError($error) {
|
||||||
$template_dir = $this->templates[$this->template]["dir_name"];
|
$template_dir = $this->templates[$this->template]["dir_name"];
|
||||||
$template_conf = json_decode(file_get_contents(TEMPLATE_DIR . $template_dir));
|
$template_conf = json_decode(file_get_contents(TEMPLATE_PATH . $template_dir . "/template.json"), true);
|
||||||
|
|
||||||
$page = $tempalte_conf["error"];
|
$page = $template_conf["error"];
|
||||||
$html = file_get_contents(TEMPLATE_PATH . $page["dir_name"] . "/" . $page["html_file"]);
|
$html = file_get_contents(TEMPLATE_PATH . $template_dir . "/" . $page["dir_name"] . "/" . $page["html_file"]);
|
||||||
|
|
||||||
$css = "";
|
$css = "";
|
||||||
|
|
||||||
@@ -79,12 +88,8 @@ class HTMLLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$template = $this->template;
|
$template = $this->template;
|
||||||
|
$tempalte_conf = $this->template_conf;
|
||||||
$template_dir = $this->templates[$template]["dir_name"];
|
$template_dir = $this->templates[$template]["dir_name"];
|
||||||
$template_conf = TEMPLATE_PATH . $template_dir . "/template.json";
|
|
||||||
|
|
||||||
$file = file_get_contents($template_conf);
|
|
||||||
$tempalte_conf = json_decode($file, true);
|
|
||||||
|
|
||||||
$page = $tempalte_conf[$this->page];
|
$page = $tempalte_conf[$this->page];
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,150 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Document</title>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0">
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet">
|
||||||
|
<script type="importmap">
|
||||||
|
{
|
||||||
|
"imports": {
|
||||||
|
"@material/web/": "https://esm.run/@material/web/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script type="module">
|
||||||
|
import '@material/web/all.js';
|
||||||
|
import { styles as typescaleStyles } from '@material/web/typography/md-typescale-styles.js';
|
||||||
|
|
||||||
|
document.adoptedStyleSheets.push(typescaleStyles.styleSheet);
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--md-sys-color-primary: rgb(58, 58, 255);
|
||||||
|
--active-menu-point-color: rgb(116, 148, 250);
|
||||||
|
--md-sys-color-surface-container: rgb(223, 228, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout {
|
||||||
|
display: flex;
|
||||||
|
height: 100vh;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
flex: 0 0 280px;
|
||||||
|
width: 280px;
|
||||||
|
overflow: hidden;
|
||||||
|
background: var(--md-sys-color-surface-container);
|
||||||
|
border-right: 1px solid var(--md-sys-color-outline-variant);
|
||||||
|
transition: flex-basis .2s ease, width .2s ease;
|
||||||
|
padding: 10px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 12px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar md-list {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
md-list-item.active {
|
||||||
|
background-color: var(--active-menu-point-color);
|
||||||
|
border-radius: 28px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
md-list-item {
|
||||||
|
border-radius: 28px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar.collapsed {
|
||||||
|
flex-basis: 58px;
|
||||||
|
width: 58x;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar.collapsed .title,
|
||||||
|
.sidebar.collapsed .label {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
flex: 1;
|
||||||
|
padding: 24px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 720px) {
|
||||||
|
body {
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="layout">
|
||||||
|
<aside class="sidebar" id="sidebar">
|
||||||
|
<div class="sidebar-header">
|
||||||
|
<md-icon-button id="toggle" aria-label="Menü ein-/ausklappen">
|
||||||
|
<md-icon>menu</md-icon>
|
||||||
|
</md-icon-button>
|
||||||
|
<span class="title">Dashboard</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<md-list>
|
||||||
|
<md-list-item type="link" href="/admin/" class="active">
|
||||||
|
<md-icon slot="start">dashboard</md-icon>
|
||||||
|
<span class="label">Overview</span>
|
||||||
|
</md-list-item>
|
||||||
|
<md-list-item type="link" href="/admin/settings.php">
|
||||||
|
<md-icon slot="start">settings</md-icon>
|
||||||
|
<span class="label">Settings</span>
|
||||||
|
</md-list-item>
|
||||||
|
</md-list>
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
<main class="content">
|
||||||
|
<h1>Dashboard</h1>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="module">
|
||||||
|
const sidebar = document.getElementById('sidebar');
|
||||||
|
const items = sidebar.querySelectorAll('md-list-item');
|
||||||
|
|
||||||
|
const mq = window.matchMedia('(max-width: 720px)');
|
||||||
|
|
||||||
|
const applyBreakpoint = () => {
|
||||||
|
sidebar.classList.toggle('collapsed', mq.matches);
|
||||||
|
};
|
||||||
|
|
||||||
|
applyBreakpoint();
|
||||||
|
mq.addEventListener('change', applyBreakpoint);
|
||||||
|
|
||||||
|
document.getElementById('toggle').addEventListener('click', () => {
|
||||||
|
sidebar.classList.toggle('collapsed');
|
||||||
|
});
|
||||||
|
|
||||||
|
items.forEach(item => {
|
||||||
|
item.addEventListener('click', () => {
|
||||||
|
items.forEach(i => i.classList.remove('active'));
|
||||||
|
item.classList.add('active');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
@@ -7,22 +7,32 @@
|
|||||||
"error.css"
|
"error.css"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
"setup":{
|
"setup":{
|
||||||
"name":"setup",
|
"name":"setup",
|
||||||
"dir_name":"setup",
|
"dir_name":"setup",
|
||||||
"html_file":"setup.html",
|
"html_file":"setup.html",
|
||||||
"css_files":[]
|
"css_files":[]
|
||||||
},
|
},
|
||||||
|
|
||||||
"entrys_frontend":{
|
"entrys_frontend":{
|
||||||
"name":"entrys_frontend",
|
"name":"entrys_frontend",
|
||||||
"dir_name":"entrys_frontend",
|
"dir_name":"entrys_frontend",
|
||||||
"html_file":"entrys_frontend.html",
|
"html_file":"entrys_frontend.html",
|
||||||
"css_files":[]
|
"css_files":[]
|
||||||
},
|
},
|
||||||
|
|
||||||
"login":{
|
"login":{
|
||||||
"name":"login",
|
"name":"login",
|
||||||
"dir_name":"login",
|
"dir_name":"login",
|
||||||
"html_file":"login.html",
|
"html_file":"login.html",
|
||||||
"css_files":[]
|
"css_files":[]
|
||||||
|
},
|
||||||
|
|
||||||
|
"admin_home":{
|
||||||
|
"name":"admin_home",
|
||||||
|
"dir_name":"admin_home",
|
||||||
|
"html_file":"home.html",
|
||||||
|
"css_files":[]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+12
-2
@@ -19,5 +19,15 @@
|
|||||||
|
|
||||||
//print_r(explode(".", "jakob.stinkt"));
|
//print_r(explode(".", "jakob.stinkt"));
|
||||||
|
|
||||||
var_dump(extension_loaded("pdo_sqlite"));
|
//var_dump(extension_loaded("pdo_sqlite"));
|
||||||
var_dump(extension_loaded("sqlite3"));
|
//var_dump(extension_loaded("sqlite3"));
|
||||||
|
|
||||||
|
class test {
|
||||||
|
private $test;
|
||||||
|
|
||||||
|
function __construct() {
|
||||||
|
var_dump(isset($this->test));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new test();
|
||||||
Reference in new issue
Block a user