Big Update Added Services and Admin
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
class Database {
|
||||
|
||||
private $conn;
|
||||
public $lastid;
|
||||
|
||||
public function __construct($dbinfo) {
|
||||
$this->conn = new mysqli($dbinfo['host'], $dbinfo['user'], $dbinfo['pass'], $dbinfo['name']);
|
||||
@@ -13,43 +14,90 @@ class Database {
|
||||
}
|
||||
|
||||
public function query($query, $params = []) {
|
||||
// Prepare the SQL query
|
||||
if ($stmt = $this->conn->prepare($query)) {
|
||||
// Bind parameters to the prepared statement (if any)
|
||||
if (!empty($params)) {
|
||||
$types = str_repeat('s', count($params)); // Assuming all params are strings
|
||||
$stmt->bind_param($types, ...$params);
|
||||
// Clean up pending results to avoid "commands out of sync"
|
||||
while ($this->conn->more_results() && $this->conn->next_result()) {
|
||||
if ($res = $this->conn->use_result()) {
|
||||
$res->free();
|
||||
}
|
||||
|
||||
// Execute the statement
|
||||
if (!$stmt->execute()) {
|
||||
throw new Exception("Query execution failed: " . $stmt->error);
|
||||
}
|
||||
|
||||
// Return the statement result
|
||||
return $stmt;
|
||||
} else {
|
||||
}
|
||||
|
||||
// Prepare the SQL statement
|
||||
$stmt = $this->conn->prepare($query);
|
||||
if (!$stmt) {
|
||||
throw new Exception("Query preparation failed: " . $this->conn->error);
|
||||
}
|
||||
|
||||
// Bind parameters if needed
|
||||
if (!empty($params)) {
|
||||
$types = str_repeat('s', count($params)); // Use 's' for all types, or detect types dynamically
|
||||
$stmt->bind_param($types, ...$params);
|
||||
}
|
||||
|
||||
// Execute the statement
|
||||
if (!$stmt->execute()) {
|
||||
$stmt->close();
|
||||
throw new Exception("Query execution failed: " . $stmt->error);
|
||||
}
|
||||
|
||||
// Save last insert id if it's an INSERT query
|
||||
if (preg_match('/^\s*INSERT/i', $query)) {
|
||||
$this->lastid = $this->conn->insert_id;
|
||||
} else {
|
||||
$this->lastid = 0;
|
||||
}
|
||||
|
||||
// Decide what to return
|
||||
// For SELECT/SHOW etc., return result set
|
||||
if (preg_match('/^\s*(SELECT|SHOW|DESCRIBE|EXPLAIN)/i', $query)) {
|
||||
$result = $stmt->get_result();
|
||||
$stmt->close();
|
||||
return $result;
|
||||
}
|
||||
|
||||
// For INSERT/UPDATE/DELETE, return success status
|
||||
$success = $stmt->affected_rows;
|
||||
$stmt->close();
|
||||
return $success;
|
||||
}
|
||||
|
||||
public function lastid() {
|
||||
return $this->lastid;
|
||||
}
|
||||
|
||||
public function getRow($query, $params = []) {
|
||||
try {
|
||||
// Perform the query using prepared statement
|
||||
$stmt = $this->query($query, $params);
|
||||
|
||||
// Get the result of the query
|
||||
// Prepare the SQL statement
|
||||
$stmt = $this->conn->prepare($query);
|
||||
if (!$stmt) {
|
||||
throw new Exception("Query preparation failed: " . $this->conn->error);
|
||||
}
|
||||
|
||||
// Bind parameters
|
||||
if (!empty($params)) {
|
||||
$types = str_repeat('s', count($params)); // You may improve this with actual type detection
|
||||
$stmt->bind_param($types, ...$params);
|
||||
}
|
||||
|
||||
// Execute the statement
|
||||
if (!$stmt->execute()) {
|
||||
$stmt->close();
|
||||
throw new Exception("Query execution failed: " . $stmt->error);
|
||||
}
|
||||
|
||||
// Get result
|
||||
$result = $stmt->get_result();
|
||||
|
||||
// Fetch the first row from the result
|
||||
return $result->fetch_assoc();
|
||||
$row = $result->fetch_assoc();
|
||||
|
||||
$stmt->close();
|
||||
return $row;
|
||||
|
||||
} catch (Exception $e) {
|
||||
// Handle the exception (log it, display a message, etc.)
|
||||
echo "An error occurred: " . $e->getMessage();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function getRows($query, $params = []) {
|
||||
$stmt = $this->conn->prepare($query);
|
||||
if (!$stmt) {
|
||||
|
||||
48
src/Logger.php
Normal file
48
src/Logger.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
class Logger {
|
||||
protected string $logFile;
|
||||
protected int $logLevelThreshold;
|
||||
|
||||
const LEVELS = [
|
||||
'DEBUG' => 0,
|
||||
'INFO' => 1,
|
||||
'WARNING' => 2,
|
||||
'ERROR' => 3,
|
||||
'NONE' => 999
|
||||
];
|
||||
|
||||
public function __construct(string $logFile, string $minLevel = 'DEBUG') {
|
||||
$this->logFile = $logFile;
|
||||
$minLevel = strtoupper($minLevel);
|
||||
$this->logLevelThreshold = self::LEVELS[$minLevel] ?? 0;
|
||||
}
|
||||
|
||||
protected function log(string $level, string $message): void {
|
||||
$level = strtoupper($level);
|
||||
if (!isset(self::LEVELS[$level]) || self::LEVELS[$level] < $this->logLevelThreshold) {
|
||||
return;
|
||||
}
|
||||
|
||||
$time = date('Y-m-d H:i:s');
|
||||
$ip = $_SERVER['REMOTE_ADDR'];
|
||||
$logEntry = "[$time] [$ip] [$level] $message" . PHP_EOL;
|
||||
|
||||
file_put_contents($this->logFile, $logEntry, FILE_APPEND | LOCK_EX);
|
||||
}
|
||||
|
||||
public function debug(string $msg): void {
|
||||
$this->log('DEBUG', $msg);
|
||||
}
|
||||
|
||||
public function info(string $msg): void {
|
||||
$this->log('INFO', $msg);
|
||||
}
|
||||
|
||||
public function warning(string $msg): void {
|
||||
$this->log('WARNING', $msg);
|
||||
}
|
||||
|
||||
public function error(string $msg): void {
|
||||
$this->log('ERROR', $msg);
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,16 @@ class MessageHandler {
|
||||
'success' => []
|
||||
];
|
||||
|
||||
public function __construct(array $sessionMessages = [])
|
||||
{
|
||||
// Merge existing session messages into the default structure
|
||||
foreach ($this->messages as $type => $_) {
|
||||
if (isset($sessionMessages[$type]) && is_array($sessionMessages[$type])) {
|
||||
$this->messages[$type] = $sessionMessages[$type];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add a message of a specific type
|
||||
public function addMessage($type, $message) {
|
||||
if (!isset($this->messages[$type])) {
|
||||
@@ -16,11 +26,22 @@ class MessageHandler {
|
||||
$this->messages[$type][] = $message;
|
||||
}
|
||||
|
||||
public function error($message){
|
||||
$this->addMessage('error', $message);
|
||||
}
|
||||
|
||||
// Get all messages of a specific type
|
||||
public function getMessages($type) {
|
||||
return $this->messages[$type] ?? [];
|
||||
}
|
||||
|
||||
// Get all messages of a specific type
|
||||
public function showMessages($type) {
|
||||
$result = $this->messages[$type] ?? [];
|
||||
$this->messages[$type] = []; // Clear messages after showing
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Get all messages of all types
|
||||
public function getAllMessages() {
|
||||
return $this->messages;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
/**
|
||||
* Use
|
||||
* $redirect->to('/login');
|
||||
* $redirect->url('/login');
|
||||
* to trigger a redirect
|
||||
*/
|
||||
|
||||
|
||||
@@ -19,12 +19,13 @@ class Router {
|
||||
}
|
||||
|
||||
private function loadRoutes() {
|
||||
require_once(FRAMEWORKPATH . '/config/routes.php');
|
||||
// Check if Path exists
|
||||
if (file_exists(BASEPATH . '/App/routes.php')) {
|
||||
require_once( BASEPATH . '/App/routes.php');
|
||||
} else {
|
||||
require_once(FRAMEWORKPATH . '/defaults/App/routes.php');
|
||||
}
|
||||
$routes = array_merge((array)$routes, (array)$framework_routes);
|
||||
|
||||
return $routes;
|
||||
}
|
||||
|
||||
@@ -67,7 +68,9 @@ class Router {
|
||||
|
||||
// one to one match
|
||||
if (array_key_exists($this->path, $this->routes)) {
|
||||
return $this->routes[$this->path][$this->requestType];
|
||||
if (!empty($this->routes[$this->path][$this->requestType])) {
|
||||
return $this->routes[$this->path][$this->requestType];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->routes as $key => $value) {
|
||||
@@ -103,8 +106,13 @@ class Router {
|
||||
|
||||
// checks if the file exists, sets file path
|
||||
private function setRouteFile() {
|
||||
|
||||
$cp = BASEPATH . '/App/controllers/' . $this->controller . '.php';
|
||||
|
||||
if (str_starts_with($this->controller, 'NOVACONIUM')) {
|
||||
$trimmed = substr($this->controller, strlen('NOVACONIUM/'));
|
||||
$cp = FRAMEWORKPATH . '/controllers/' . $trimmed . '.php';
|
||||
} else {
|
||||
$cp = BASEPATH . '/App/controllers/' . $this->controller . '.php';
|
||||
}
|
||||
|
||||
if (file_exists($cp)) {
|
||||
return $cp;
|
||||
|
||||
@@ -5,8 +5,7 @@ class Session {
|
||||
|
||||
public function __construct() {
|
||||
session_start();
|
||||
if (!isset($_SESSION)) {
|
||||
$this->session = $_SESSION;
|
||||
if (!isset($_SESSION['token'])) {
|
||||
$this->setToken();
|
||||
$this->session['messages'] = [];
|
||||
} else {
|
||||
@@ -51,6 +50,7 @@ class Session {
|
||||
}
|
||||
|
||||
public function kill() {
|
||||
$_SESSION = [];
|
||||
session_destroy();
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ function dd(...$vars) {
|
||||
}
|
||||
|
||||
function makeitso() {
|
||||
global $session, $db, $redirect, $config, $messages;
|
||||
global $session, $db, $redirect, $config, $messages, $log;
|
||||
|
||||
if (!empty($config['database']['host'])) {
|
||||
$db->close();
|
||||
|
||||
@@ -10,19 +10,32 @@ if (file_exists(BASEPATH . '/App/config.php')) {
|
||||
require_once(FRAMEWORKPATH . '/defaults/App/config.php');
|
||||
}
|
||||
|
||||
// Logging
|
||||
require_once(FRAMEWORKPATH . '/src/Logger.php');
|
||||
$log = new Logger(BASEPATH . $config['logfile'], $config['loglevel']);
|
||||
|
||||
// Global Functions
|
||||
require_once(FRAMEWORKPATH . '/src/functions.php');
|
||||
|
||||
// Creates the view() function using twig
|
||||
$data = array();
|
||||
require_once(FRAMEWORKPATH . '/src/twig.php');
|
||||
|
||||
// Messages
|
||||
require_once(FRAMEWORKPATH . '/src/MessageHandler.php');
|
||||
$messages = new MessageHandler;
|
||||
|
||||
// Start a Session
|
||||
require_once(FRAMEWORKPATH . '/src/Session.php');
|
||||
$session = new Session();
|
||||
$data['token'] = $session->get('token');
|
||||
if ($config['loglevel'] == 'DEBUG') {
|
||||
$data['debug'] = nl2br(print_r($session->debug(), true));
|
||||
}
|
||||
|
||||
// Messages
|
||||
require_once(FRAMEWORKPATH . '/src/MessageHandler.php');
|
||||
$messages = new MessageHandler($session->flash('messages'));
|
||||
|
||||
foreach (['error','notice'] as $key){
|
||||
$data[$key] = $messages->showMessages($key);
|
||||
}
|
||||
|
||||
// Load Database Class
|
||||
if (!empty($config['database']['host'])) {
|
||||
|
||||
16
src/twig.php
16
src/twig.php
@@ -1,11 +1,16 @@
|
||||
<?php
|
||||
|
||||
//Twig
|
||||
function view($name = '', $data = []) {
|
||||
global $config; // Use the globally included $config
|
||||
function view($name = '', $moreData = []) {
|
||||
global $config, $data; // Use the globally included $config
|
||||
|
||||
if (!empty($moreData)){
|
||||
$data = array_merge($data, $moreData);
|
||||
}
|
||||
|
||||
$loader = new Twig\Loader\FilesystemLoader(BASEPATH . '/App/views/');
|
||||
$loader->addPath(BASEPATH . '/vendor/4lt/novaconium/twig', 'novaconium');
|
||||
$loader->addPath(FRAMEWORKPATH . '/twig', 'novaconium');
|
||||
$loader->addPath(FRAMEWORKPATH . '/views', 'novacore');
|
||||
$loader->addPath(BASEPATH . '/App/templates', 'override');
|
||||
|
||||
$twig = new Twig\Environment($loader);
|
||||
@@ -15,7 +20,10 @@ function view($name = '', $data = []) {
|
||||
|
||||
// Check if the template exists
|
||||
if (file_exists(BASEPATH . '/App/views/' . $name . '.html.twig')) {
|
||||
echo $twig->render("$name.html.twig", $data);
|
||||
echo $twig->render($name . '.html.twig', $data);
|
||||
return true;
|
||||
} elseif (str_starts_with($name, '@')) { // Check if using framework
|
||||
echo $twig->render($name . '.html.twig', $data);
|
||||
return true;
|
||||
} else {
|
||||
echo "Error: Twig Template ($name) Not Found.";
|
||||
|
||||
Reference in New Issue
Block a user