Added the files from MVP
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
namespace classes;
|
||||
|
||||
use Exception;
|
||||
use interfaces\authentication_i;
|
||||
use objects\plate_scanners_o;
|
||||
use objects\tokens_o;
|
||||
use objects\users_o;
|
||||
|
||||
class authentication implements authentication_i
|
||||
{
|
||||
|
||||
public function authenticate(int $customer_number, string $password): bool
|
||||
{
|
||||
// Get the customer from the database
|
||||
$customer = (new users_o())->getUserByCustomerNumber( $customer_number );
|
||||
// Check if the customer exists
|
||||
if (!$customer->password->value()) {
|
||||
return false;
|
||||
}
|
||||
// Check if the password is correct
|
||||
if (!$this->match_passwords($password, $customer->password->value())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function create_token(int $customer_number): string
|
||||
{
|
||||
// Create a token
|
||||
$token = bin2hex(random_bytes(32));
|
||||
// Get the user id
|
||||
$user_id = (new users_o())->getUserByCustomerNumber($customer_number)->id;
|
||||
// Save the token in the database
|
||||
(new tokens_o())->create($user_id, $token, 'AUTH_TOKEN');
|
||||
return $token;
|
||||
}
|
||||
|
||||
public function validate_token(string $token): bool
|
||||
{
|
||||
// Get the token from the database
|
||||
$token = (new tokens_o())->getToken($token);
|
||||
// Check if the token exists
|
||||
if (!$token->id) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function get_user(): users_o|false
|
||||
{
|
||||
/**
|
||||
* Get the user from the token
|
||||
*/
|
||||
// Get the token from the headers
|
||||
$headers = getallheaders();
|
||||
if (!isset($headers['Authorization'])) {
|
||||
return false;
|
||||
}
|
||||
$token = $headers['Authorization'];
|
||||
// Strip the Bearer prefix
|
||||
$token = str_replace('Bearer ', '', $token);
|
||||
// Get the token from the database
|
||||
$token = (new tokens_o())->getToken($token);
|
||||
// Check if the token exists
|
||||
if (!$token->id) {
|
||||
return false;
|
||||
}
|
||||
// Get the user from the database
|
||||
return (new users_o())->getUserById($token->user_id->value());
|
||||
}
|
||||
|
||||
public function get_plate_scanner(): plate_scanners_o|false
|
||||
{
|
||||
// Get the token from the headers
|
||||
$headers = getallheaders();
|
||||
if (!isset($headers['Authorization'])) {
|
||||
return false;
|
||||
}
|
||||
$token = $headers['Authorization'];
|
||||
// Strip the Bearer prefix
|
||||
$token = str_replace('Bearer ', '', $token);
|
||||
// Get the token from the database
|
||||
$token = (new plate_scanners_o())->getPlateScannerByApiKey($token);
|
||||
// Check if the token exists
|
||||
if (!isset($token->id)) {
|
||||
return false;
|
||||
}
|
||||
// Get the plate scanner from the database
|
||||
return $token;
|
||||
}
|
||||
|
||||
|
||||
public function hash_password($password): string
|
||||
{
|
||||
// Hash the password
|
||||
return password_hash($password, PASSWORD_DEFAULT);
|
||||
}
|
||||
|
||||
public function match_passwords($password, $hash): bool
|
||||
{
|
||||
// Compare the password with the hash
|
||||
return password_verify($password, $hash);
|
||||
}
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
namespace classes;
|
||||
|
||||
use Exception;
|
||||
use mysqli;
|
||||
|
||||
class db
|
||||
{
|
||||
private string $host;
|
||||
private string $user;
|
||||
private string $password;
|
||||
private string $database;
|
||||
public mysqli $conn;
|
||||
|
||||
public function __construct(array $config)
|
||||
{
|
||||
$this->host = $config['host'];
|
||||
$this->user = $config['user'];
|
||||
$this->password = $config['password'];
|
||||
$this->database = $config['database'];
|
||||
}
|
||||
|
||||
public function connect(): void
|
||||
{
|
||||
global $response;
|
||||
try {
|
||||
$this->conn = new mysqli($this->host, $this->user, $this->password, $this->database);
|
||||
} catch (Exception $e) {
|
||||
$response->internal_server_error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function query(string $sql): \mysqli_result|bool
|
||||
{
|
||||
// If the connection is not established, connect
|
||||
return $this->conn->query($sql);
|
||||
}
|
||||
|
||||
public function fetch_assoc($result)
|
||||
{
|
||||
return $result->fetch_assoc();
|
||||
}
|
||||
|
||||
public function fetch_all($result)
|
||||
{
|
||||
return $result->fetch_all(MYSQLI_ASSOC);
|
||||
}
|
||||
|
||||
public function escape_string(string $string): string
|
||||
{
|
||||
return $this->conn->real_escape_string($string);
|
||||
}
|
||||
|
||||
public function close(): void
|
||||
{
|
||||
$this->conn->close();
|
||||
}
|
||||
|
||||
public function get(string $table, int $id)
|
||||
{
|
||||
$sql = "SELECT * FROM $table WHERE id = $id";
|
||||
$result = $this->query($sql);
|
||||
return $this->fetch_assoc($result);
|
||||
}
|
||||
|
||||
public function list_objects(string $table): array
|
||||
{
|
||||
$sql = "SELECT * FROM $table";
|
||||
$result = $this->query($sql);
|
||||
return $this->fetch_all($result);
|
||||
}
|
||||
|
||||
public function list_objects_paginated(string $table, int $page, int $limit): array
|
||||
{
|
||||
$offset = ($page - 1) * $limit;
|
||||
$sql = "SELECT * FROM $table LIMIT $limit OFFSET $offset";
|
||||
$result = $this->query($sql);
|
||||
return $this->fetch_all($result);
|
||||
}
|
||||
|
||||
public function count_objects(string $table): int
|
||||
{
|
||||
$sql = "SELECT COUNT(*) FROM $table";
|
||||
$result = $this->query($sql);
|
||||
return $result->fetch_row()[0];
|
||||
}
|
||||
|
||||
public function add_object(string $table, array $data): void
|
||||
{
|
||||
$columns = implode(', ', array_keys($data));
|
||||
$values = implode("', '", array_values($data));
|
||||
$sql = "INSERT INTO $table ($columns) VALUES ('$values')";
|
||||
$this->query($sql);
|
||||
}
|
||||
|
||||
public function insert_id(): int
|
||||
{
|
||||
return $this->conn->insert_id;
|
||||
}
|
||||
|
||||
public function conn(): mysqli
|
||||
{
|
||||
return $this->conn;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace classes;
|
||||
|
||||
use interfaces\encrypt_i;
|
||||
|
||||
class encrypt implements encrypt_i
|
||||
{
|
||||
|
||||
public function encrypt(string $data): string
|
||||
{
|
||||
// Debug:
|
||||
return $data;
|
||||
// Encrypt data
|
||||
global $ENCRYPTION_KEY;
|
||||
// Use AES 256 encryption
|
||||
$cipher = "aes-256-cbc";
|
||||
// Use the encryption key
|
||||
$options = 0;
|
||||
// Get the initialization vector
|
||||
$iv_length = openssl_cipher_iv_length($cipher);
|
||||
$iv = openssl_random_pseudo_bytes($iv_length);
|
||||
// Use the first 16 bytes of the initialization vector
|
||||
$iv = substr($iv, 0, 16);
|
||||
// Encrypt the data
|
||||
$encrypted = openssl_encrypt($data, $cipher, $ENCRYPTION_KEY, $options, $iv);
|
||||
// Save the initialization vector for decryption
|
||||
return $iv . $encrypted;
|
||||
}
|
||||
|
||||
public function decrypt(string $data): string
|
||||
{
|
||||
// Debug:
|
||||
return $data;
|
||||
// Decrypt data
|
||||
global $ENCRYPTION_KEY;
|
||||
// Use AES 256 encryption
|
||||
$cipher = "aes-256-cbc";
|
||||
// Use the encryption key and initialization vector
|
||||
$options = 0;
|
||||
// Get the initialization vector
|
||||
$iv_length = openssl_cipher_iv_length($cipher);
|
||||
$iv = substr($data, 0, $iv_length);
|
||||
// Get the encrypted data
|
||||
$encrypted = substr($data, $iv_length);
|
||||
// Decrypt the data
|
||||
return openssl_decrypt($encrypted, $cipher, $ENCRYPTION_KEY, $options, $iv);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace classes;
|
||||
|
||||
class object_property
|
||||
{
|
||||
private string $table; // The table of the objects in the database (e.g. users)
|
||||
public int $id; // The id of the object in the database
|
||||
private string $column; // The column name of the field in the database table (e.g. id, name, email)
|
||||
private string $type; // The data type of the field in the database table (e.g. int, varchar, text)
|
||||
private bool $required; // Whether the field is required or not
|
||||
private mixed $default; // The default value of the field
|
||||
|
||||
public function __construct(string $table, int $id, string $column, string $type, bool $required = false, mixed $default = null)
|
||||
{
|
||||
$this->table = $table;
|
||||
$this->id = $id;
|
||||
$this->column = $column;
|
||||
$this->type = $type;
|
||||
$this->required = $required;
|
||||
$this->default = $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the field in the database table
|
||||
* @return mixed The value of the field in the database table
|
||||
*/
|
||||
public function value(): mixed
|
||||
{
|
||||
// Get the value of the field in the database table
|
||||
global $db;
|
||||
$sql = "SELECT $this->column FROM $this->table WHERE id = $this->id";
|
||||
$result = $db->query($sql);
|
||||
$row = $db->fetch_assoc($result);
|
||||
return $row[$this->column];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of the field in the database table
|
||||
* @param mixed $value The value of the field in the database table
|
||||
*/
|
||||
public function set(mixed $value): void
|
||||
{
|
||||
// Set the value of the field in the database table
|
||||
global /** @var db $db */
|
||||
$db;
|
||||
// If the value is null, set it to null
|
||||
if ($value === null) {
|
||||
$sql = "UPDATE $this->table SET $this->column = NULL WHERE id = $this->id";
|
||||
}
|
||||
// If the value is a string, escape it
|
||||
else {
|
||||
$value = $db->escape_string($value);
|
||||
$sql = "UPDATE $this->table SET $this->column = '$value' WHERE id = $this->id";
|
||||
}
|
||||
$db->query($sql);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace classes;
|
||||
|
||||
use interfaces\ratelimit_i;
|
||||
use objects\ratelimit_o;
|
||||
|
||||
class ratelimit implements ratelimit_i
|
||||
{
|
||||
private int $limit; // The number of requests allowed in the time period
|
||||
private int $time; // The time period in seconds
|
||||
|
||||
public function __construct(int $defaultLimit, int $defaultTime)
|
||||
{
|
||||
$this->limit = $defaultLimit;
|
||||
$this->time = $defaultTime;
|
||||
}
|
||||
|
||||
public function enforceIP(string $ip): bool
|
||||
{
|
||||
global $response;
|
||||
$ratelimit = (new ratelimit_o())->getOrCreateRateLimitByIp($ip);
|
||||
if ($ratelimit->count->value() >= $this->limit) {
|
||||
$response->rate_limit_exceeded();
|
||||
}
|
||||
$ratelimit->increment($ratelimit->id, 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace classes;
|
||||
|
||||
class request
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
namespace classes;
|
||||
|
||||
use interfaces\response_i;
|
||||
use JetBrains\PhpStorm\NoReturn;
|
||||
|
||||
class response implements response_i
|
||||
{
|
||||
private bool $matching_route_found = false;
|
||||
private array $data = [];
|
||||
private array $meta = [];
|
||||
private array $includes = [];
|
||||
#[NoReturn] public function response(bool $success, mixed $data, int $status = null): void
|
||||
{
|
||||
header('Content-Type: application/json');
|
||||
if ($status) {
|
||||
http_response_code($status);
|
||||
} else {
|
||||
http_response_code($success ? 200 : 400);
|
||||
}
|
||||
// If the data isn't an array, convert it to an array
|
||||
if (! is_array($data)) {
|
||||
$data = ['message' => $data];
|
||||
}
|
||||
echo json_encode([
|
||||
'success' => $success,
|
||||
'data' => $data,
|
||||
'meta' => $this->meta,
|
||||
'includes' => $this->includes
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
#[NoReturn] public function success(mixed $data, int $status = null): void
|
||||
{
|
||||
$this->response(true, $data, $status);
|
||||
}
|
||||
|
||||
#[NoReturn] public function error(mixed $data, int $status = null): void
|
||||
{
|
||||
$this->response(false, $data, $status);
|
||||
}
|
||||
|
||||
#[NoReturn] public function not_found(): void
|
||||
{
|
||||
$this->error('Not found', 404);
|
||||
}
|
||||
|
||||
#[NoReturn] public function rate_limit_exceeded(): void
|
||||
{
|
||||
$this->error('Rate limit exceeded', 429);
|
||||
}
|
||||
|
||||
public function add_data(string $key, mixed $value): void
|
||||
{
|
||||
$this->data[$key] = $value;
|
||||
}
|
||||
|
||||
public function add_meta(string $key, mixed $value): void
|
||||
{
|
||||
$this->meta[$key] = $value;
|
||||
}
|
||||
|
||||
public function add_included(string $key, mixed $value): void
|
||||
{
|
||||
$this->includes[$key] = $value;
|
||||
}
|
||||
|
||||
public function matching_route_found(): void
|
||||
{
|
||||
$this->matching_route_found = true;
|
||||
}
|
||||
|
||||
#[NoReturn] public function method_not_allowed(): void
|
||||
{
|
||||
$this->error('Method not allowed', 405);
|
||||
}
|
||||
|
||||
#[NoReturn] public function internal_server_error($error): void
|
||||
{
|
||||
$this->error('Internal server error' . ($error ? ': ' . $error : ''), 500);
|
||||
}
|
||||
|
||||
public function paginate(int $page, int $per_page, int $total, string $search = null, array $filters = null): void
|
||||
{
|
||||
// If the total is 0, return 1 page, 0 total
|
||||
if ($total === 0) {
|
||||
$total = 1;
|
||||
}
|
||||
$this->add_meta('pagination', [
|
||||
'page' => $page,
|
||||
'per_page' => $per_page,
|
||||
'total' => $total,
|
||||
'search' => $search,
|
||||
'filters' => $filters
|
||||
]);
|
||||
}
|
||||
|
||||
public function get_data(): array
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
public function is_matching_route_found(): bool
|
||||
{
|
||||
return $this->matching_route_found;
|
||||
}
|
||||
|
||||
public function add_debug(mixed $data): void
|
||||
{
|
||||
$this->add_data('debug', $data);
|
||||
}
|
||||
|
||||
public function getRequestParameter(string $key): string|null
|
||||
{
|
||||
// Get the request data if the method is POST, PUT or PATCH
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' || $_SERVER['REQUEST_METHOD'] === 'PUT' || $_SERVER['REQUEST_METHOD'] === 'PATCH') {
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
}
|
||||
// Get the request data if the method is GET, DELETE or OPTIONS
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'GET' || $_SERVER['REQUEST_METHOD'] === 'DELETE' || $_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
|
||||
$data = $_GET;
|
||||
}
|
||||
// Return the data
|
||||
return $data[$key] ?? null;
|
||||
}
|
||||
|
||||
public function add_include(string $string, array $dataArray): void
|
||||
{
|
||||
$this->add_included($string, $dataArray);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace classes;
|
||||
|
||||
class router
|
||||
{
|
||||
private string $url;
|
||||
private string $method;
|
||||
private array $routes;
|
||||
private array $routeClasses; // Contains the classes that have the route_t trait
|
||||
public function __construct()
|
||||
{
|
||||
$this->url = $_SERVER['REQUEST_URI'];
|
||||
$this->method = $_SERVER['REQUEST_METHOD'];
|
||||
$this->routes = [];
|
||||
$this->routeClasses = [];
|
||||
}
|
||||
|
||||
public function add($route, $method, $function): void
|
||||
{
|
||||
$this->routes[] = ['route' => $route, 'method' => $method, 'function' => $function];
|
||||
}
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
foreach ($this->routeClasses as $class) {
|
||||
$route = new $class();
|
||||
// Add the routes to the router
|
||||
$route->run();
|
||||
}
|
||||
|
||||
$this->routeRequest();
|
||||
}
|
||||
|
||||
public function auto_load_routes(string $path): void
|
||||
{
|
||||
global $response;
|
||||
$files = scandir($path);
|
||||
foreach ($files as $file) {
|
||||
if ($file == '.' || $file == '..') {
|
||||
continue;
|
||||
}
|
||||
require_once $path . '/' . $file;
|
||||
}
|
||||
|
||||
// Get all the classes in the files with the route_t trait
|
||||
$classes = get_declared_classes();
|
||||
foreach ($classes as $class) {
|
||||
if (in_array('traits\route_t', class_uses($class))) {
|
||||
$this->routeClasses[] = $class;
|
||||
}
|
||||
}
|
||||
|
||||
// Try to run the routes, if there is an error, catch it and send an internal server error response
|
||||
try {
|
||||
$this->run();
|
||||
} catch (\Exception $e) {
|
||||
$response->internal_server_error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function ERROR_HANDLER($callback): void
|
||||
{
|
||||
try {
|
||||
$callback();
|
||||
} catch (\Exception $e) {
|
||||
global $response;
|
||||
$response->internal_server_error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private function routeRequest(): void
|
||||
{
|
||||
global $response;
|
||||
$matching_route_found = false;
|
||||
foreach ($this->routes as $route) {
|
||||
if ($this->doesRouteMatchCurrent($route['route']) && $route['method'] == $this->method) {
|
||||
$route['function']();
|
||||
$matching_route_found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($matching_route_found) {
|
||||
$response->matching_route_found();
|
||||
} else {
|
||||
$response->not_found();
|
||||
}
|
||||
}
|
||||
|
||||
private function doesRouteMatchCurrent($route): bool
|
||||
{
|
||||
// Check if the route matches the current URL or if it matches the regex pattern
|
||||
// Remove the query string
|
||||
$this->url = explode('?', $this->url)[0];
|
||||
// Exact match
|
||||
if ($route == $this->url) {
|
||||
return true;
|
||||
}
|
||||
// Regex
|
||||
$route = str_replace('/', '\/', $route);
|
||||
$route = preg_replace('/{[a-zA-Z0-9]+}/', '([a-zA-Z0-9]+)', $route);
|
||||
if (preg_match('/^' . $route . '$/', $this->url)) {
|
||||
return true;
|
||||
}
|
||||
// None of the matches were found
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace classes;
|
||||
|
||||
use traits\session_t;
|
||||
|
||||
class session
|
||||
{
|
||||
use session_t;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php global $CONFIG_DB, $DEBUG, $ENCRYPTION_KEY, $CORS, $ECONOMIC_API;
|
||||
$CONFIG_DB = [
|
||||
'host' => '', // IP address of the database server e.g. 127.0.0.1
|
||||
'user' => '', // Username of the database server e.g. root
|
||||
'password' => '', // Password of the database server e.g. password123
|
||||
'database' => '' // Name of the database e.g. my_database
|
||||
];
|
||||
$DEBUG = true; // Set to true to enable debugging (Error messages will be shown, and this should never be used in production)
|
||||
$USE_PROD_ECONOMIC_IN_DEBUG = true; // Set to true to use the production economic API in debug mode
|
||||
$ENCRYPTION_KEY = ''; // 44 Characters long encryption key
|
||||
$CORS = '*'; // Set to the domain that should be allowed to access the API e.g. https://example.com
|
||||
$ECONOMIC_API = [
|
||||
'app_access_grant' => '', // Economic API access grant token (1)
|
||||
'app_access_grant2' => '', // Economic API access grant token (2)
|
||||
'app_secret_token' => '' // Economic API secret token
|
||||
];
|
||||
if ($DEBUG && !$USE_PROD_ECONOMIC_IN_DEBUG) {
|
||||
$ECONOMIC_API = [
|
||||
'app_access_grant' => '', // Development Economic API access grant token (1)
|
||||
'app_access_grant2' => '', // Development Economic API access grant token (2)
|
||||
'app_secret_token' => '' // Development Economic API secret token
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php global $DEBUG, $CONFIG_DB, $ENCRYPTION_KEY, $CORS, $WD, $db, $response, $request, $router;
|
||||
/**
|
||||
* This is the main entry point to the Truck Wash API.
|
||||
*/
|
||||
const WD = __DIR__;
|
||||
require_once 'config.php';
|
||||
/** Debug */
|
||||
if ($DEBUG) {
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
}
|
||||
|
||||
/** CORS */
|
||||
header("Access-Control-Allow-Origin: $CORS");
|
||||
header("Access-Control-Allow-Headers: Content-Type, Authorization");
|
||||
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
|
||||
|
||||
/** Autoload */
|
||||
require_once 'vendor/autoload.php';
|
||||
/** Load all Interfaces */
|
||||
foreach (glob(WD . '/interfaces/*.php') as $interface) {
|
||||
require_once $interface;
|
||||
}
|
||||
/** Load all Traits */
|
||||
foreach (glob(WD . '/traits/*.php') as $trait) {
|
||||
require_once $trait;
|
||||
}
|
||||
|
||||
/** Load all Classes */
|
||||
require_once 'classes/encrypt.php';
|
||||
require_once 'classes/authentication.php';
|
||||
require_once 'classes/object_property.php';
|
||||
require_once 'classes/router.php';
|
||||
require_once 'classes/db.php';
|
||||
require_once 'classes/response.php';
|
||||
require_once 'classes/request.php';
|
||||
require_once 'classes/ratelimit.php';
|
||||
|
||||
/**
|
||||
* Modules
|
||||
* Load all the modules
|
||||
*/
|
||||
require_once 'modules/economic/economic_m.php';
|
||||
require_once 'modules/economic/customers/economicCustomers.php';
|
||||
require_once 'modules/economic/customers/economic_customer_mo.php';
|
||||
require_once 'modules/economic/invoices/draft/economicInvoicesDrafts.php';
|
||||
require_once 'modules/economic/invoices/draft/economic_invoice_draft_mo.php';
|
||||
|
||||
use classes\response;
|
||||
use classes\request;
|
||||
use classes\db;
|
||||
use classes\router;
|
||||
|
||||
// Start the session
|
||||
$router = new router();
|
||||
$response = new response();
|
||||
$request = new request();
|
||||
$db = new db($CONFIG_DB);
|
||||
|
||||
// Connect to the database, and ensure the connection is successful
|
||||
try {
|
||||
$db->connect();
|
||||
} catch (Exception $e) {
|
||||
$response->error($e->getMessage(), 500);
|
||||
}
|
||||
// Load all the traits
|
||||
foreach (glob(WD . '/traits/*.php') as $trait) {
|
||||
require_once $trait;
|
||||
}
|
||||
|
||||
// Load all the routes
|
||||
foreach (glob(WD . '/routes/*.php') as $route) {
|
||||
require_once $route;
|
||||
}
|
||||
|
||||
/** Load all Objects */
|
||||
foreach (glob(WD . '/objects/*.php') as $object) {
|
||||
try {
|
||||
require_once $object;
|
||||
} catch (Exception $e) {
|
||||
$response->error($e->getMessage(), 500);
|
||||
}
|
||||
}
|
||||
|
||||
// Autoload all the routes
|
||||
$router->auto_load_routes(WD . '/routes');
|
||||
|
||||
/** If no matching route is found, return a 404 */
|
||||
if (!$response->is_matching_route_found()) {
|
||||
// Debug
|
||||
$response->add_debug(['message' => 'No matching route found']);
|
||||
$response->not_found();
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace interfaces;
|
||||
|
||||
interface authentication_i
|
||||
{
|
||||
public function authenticate(int $customer_number, string $password): bool;
|
||||
public function create_token(int $customer_number): string;
|
||||
public function hash_password(string $password): string;
|
||||
public function match_passwords(string $password, string $hash): bool;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace interfaces;
|
||||
|
||||
interface encrypt_i
|
||||
{
|
||||
public function encrypt(string $data): string;
|
||||
public function decrypt(string $data): string;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace interfaces;
|
||||
|
||||
interface ratelimit_i
|
||||
{
|
||||
public function enforceIP(string $ip): bool;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace interfaces;
|
||||
|
||||
interface response_i
|
||||
{
|
||||
public function response(bool $success, array $data, int $status = null): void;
|
||||
public function success(mixed $data, int $status = null): void;
|
||||
public function error(mixed $data, int $status = null): void;
|
||||
public function not_found(): void;
|
||||
public function matching_route_found(): void;
|
||||
public function method_not_allowed(): void;
|
||||
public function internal_server_error($error): void;
|
||||
public function add_data(string $key, mixed $value): void;
|
||||
public function add_debug(mixed $data): void;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace customers;
|
||||
|
||||
use economic_m;
|
||||
|
||||
class economicCustomers extends economic_m
|
||||
{
|
||||
public function getCustomerId(int $customerNumber): array|bool
|
||||
{
|
||||
// Check if the customer exists
|
||||
$url = '/customers?filter=customerNumber$eq:' . $customerNumber;
|
||||
$response = $this->send_request($url, 'GET', '');
|
||||
$response = json_decode($response);
|
||||
return $response->collection;
|
||||
}
|
||||
|
||||
public function searchCustomers(string|int $search, string $filter, int $limit = 10, int $page = 1): object
|
||||
{
|
||||
// Make sure the search string is ready for the API
|
||||
$search = urlencode($search);
|
||||
// Search for customers
|
||||
$url = '/customers?filter=' . $filter . '$like:' . $search . '&pagesize=' . $limit . '&skippages=' . $page - 1;
|
||||
$response = $this->send_request($url, 'GET', '');
|
||||
return json_decode($response);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace customers;
|
||||
|
||||
class economic_customer_mo
|
||||
{
|
||||
public int $customer_number;
|
||||
public null|string $name;
|
||||
public null|string $address;
|
||||
public null|string $city;
|
||||
public null|string $zip;
|
||||
public null|string $message;
|
||||
public null|string $corporateIdentificationNumber;
|
||||
public null|string $email;
|
||||
public null|string $mobilePhone;
|
||||
public null|string $currency;
|
||||
public null|string $country;
|
||||
public function getCustomerByCustomerNumber(int $customer_number): static
|
||||
{
|
||||
// Get the customer from the economic system
|
||||
$economicCustomers = new economicCustomers();
|
||||
$customer = $economicCustomers->getCustomerId($customer_number);
|
||||
// Check if the customer exists
|
||||
if (count($customer) > 0) {
|
||||
return $this->parseCustomer($customer[0]);
|
||||
}
|
||||
return $this;
|
||||
|
||||
}
|
||||
|
||||
public function parseCustomer($customer): static
|
||||
{
|
||||
$this->customer_number = $customer->customerNumber;
|
||||
$this->name = ($customer->name ?? null);
|
||||
$this->address = ($customer->address ?? null);
|
||||
$this->city = ($customer->city ?? null);
|
||||
$this->zip = ($customer->zip ?? null);
|
||||
$this->corporateIdentificationNumber = ($customer->corporateIdentificationNumber ?? null);
|
||||
$this->email = ($customer->email ?? null);
|
||||
$this->mobilePhone = ($customer->mobilePhone ?? null);
|
||||
$this->currency = ($customer->currency ?? null);
|
||||
$this->country = ($customer->country ?? null);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function asArray(): array
|
||||
{
|
||||
// If the customer does not exist, return an empty array
|
||||
if (!isset($this->customer_number)) {
|
||||
return [];
|
||||
}
|
||||
return [
|
||||
'customerNumber' => $this->customer_number,
|
||||
'name' => $this->name,
|
||||
'address' => $this->address,
|
||||
'city' => $this->city,
|
||||
'zip' => $this->zip,
|
||||
'corporateIdentificationNumber' => $this->corporateIdentificationNumber,
|
||||
'email' => $this->email,
|
||||
'mobilePhone' => $this->mobilePhone,
|
||||
'currency' => $this->currency,
|
||||
'country' => $this->country,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
class economic_m
|
||||
{
|
||||
/**
|
||||
* https://secure.e-conomic.com/secure/api1/requestaccess.aspx?appPublicToken=WeG89W2Y63wLjy1lnqfpsHlfa1mBiyNKByqtGmBOoOw&redirectUrl=truckwash.dk
|
||||
*/
|
||||
private string $api_url = 'https://restapi.e-conomic.com';
|
||||
private string $appAccessGrant;
|
||||
private string $app_token;
|
||||
private string $appAccessGrant2;
|
||||
public function __construct()
|
||||
{
|
||||
global $ECONOMIC_API;
|
||||
$this->app_token = $ECONOMIC_API['app_secret_token'];
|
||||
$this->appAccessGrant = $ECONOMIC_API['app_access_grant'];
|
||||
$this->appAccessGrant2 = $ECONOMIC_API['app_access_grant2'];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a request to the Economic API
|
||||
* @param string $url
|
||||
* @param string $method
|
||||
* @param string $data
|
||||
* @param bool $authToken2
|
||||
* @return string
|
||||
*/
|
||||
protected function send_request($url, $method, $data = '', bool $authToken2 = false): string
|
||||
{
|
||||
$curl = curl_init();
|
||||
curl_setopt_array($curl, array(
|
||||
CURLOPT_URL => $this->api_url . $url,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_ENCODING => '',
|
||||
CURLOPT_MAXREDIRS => 10,
|
||||
CURLOPT_TIMEOUT => 0,
|
||||
CURLOPT_FOLLOWLOCATION => true,
|
||||
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
||||
CURLOPT_CUSTOMREQUEST => $method,
|
||||
CURLOPT_HTTPHEADER => array(
|
||||
'X-AppSecretToken: ' . $this->app_token,
|
||||
'X-AgreementGrantToken: ' . ( $authToken2 ? $this->appAccessGrant2 : $this->appAccessGrant ),
|
||||
'Content-Type: application/json'
|
||||
),
|
||||
));
|
||||
|
||||
if ($method === 'POST') {
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
|
||||
}
|
||||
|
||||
$response = curl_exec($curl);
|
||||
curl_close($curl);
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allowed search filters
|
||||
* @return array
|
||||
*/
|
||||
public function allowed_search_filters_customers(): array
|
||||
{
|
||||
return [
|
||||
'address', 'balance', 'barred', 'city', 'corporateIdentificationNumber', 'country', 'creditLimit', 'currency', 'customerGroup.customerGroupNumber', 'customerNumber', 'ean', 'email', 'lastUpdated', 'mobilePhone', 'name', 'publicEntryNumber', 'telephoneAndFaxNumber', 'vatNumber', 'website', 'zip'
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
class economicInvoicesDrafts extends economic_m
|
||||
{
|
||||
public function createInvoiceDraft(array $data): object
|
||||
{
|
||||
// Create a draft invoice
|
||||
$url = '/invoices/drafts';
|
||||
$response = $this->send_request($url, 'POST', json_encode($data));
|
||||
return json_decode($response);
|
||||
}
|
||||
|
||||
public function getLayouts(): object
|
||||
{
|
||||
// Get all the layouts
|
||||
$url = '/layouts';
|
||||
$response = $this->send_request($url, 'GET');
|
||||
return json_decode($response);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
class economic_invoice_draft_mo extends economicInvoicesDrafts
|
||||
{
|
||||
protected int $customer_number;
|
||||
protected string $date; // Date of the invoice (YYYY-MM-DD)
|
||||
protected string $currency; // Currency of the invoice (DKK, EUR, USD, etc.)
|
||||
protected float $layout_number; // Layout number of the invoice
|
||||
protected float $payment_terms_number; // Payment terms number of the invoice
|
||||
protected array $recipient; // Recipient of the invoice (Includes name, address, zip, city, and (array)vatZone)
|
||||
protected array $lines; // Lines of the invoice (Includes product, quantity, unitNetPrice, discountPercentage, and (array)vatRate)
|
||||
public function createInvoiceDraft(array $data): object
|
||||
{
|
||||
// Create a draft invoice
|
||||
$url = '/invoices/drafts';
|
||||
$response = $this->send_request($url, 'POST', json_encode($data));
|
||||
return json_decode($response);
|
||||
}
|
||||
|
||||
public function addLine(string $productNumber, string $description, float $quantity, float $unitNetPrice, float $discountPercentage): void
|
||||
{
|
||||
// We then add a 0 in front of the product number to make sure it's the right one, made by FlexPOS.
|
||||
// Add a line to the invoice
|
||||
$this->lines[] = [
|
||||
'product' => [
|
||||
'productNumber' => $productNumber,
|
||||
],
|
||||
'quantity' => $quantity,
|
||||
'unitNetPrice' => $unitNetPrice,
|
||||
'discountPercentage' => $discountPercentage,
|
||||
'description' => $description,
|
||||
];
|
||||
}
|
||||
|
||||
public function addLineTEXT(string $text): void
|
||||
{
|
||||
// Add a line to the invoice
|
||||
$this->lines[] = [
|
||||
'product' => [
|
||||
'productNumber' => '81234',
|
||||
],
|
||||
'description' => $text,
|
||||
'quantity' => 1,
|
||||
'unitNetPrice' => 0,
|
||||
'discountPercentage' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
// Example of a method that uses the createInvoiceDraft method
|
||||
public function createInvoiceDraftExample(): object
|
||||
{
|
||||
$data = [
|
||||
'currency' => 'DKK',
|
||||
'date' => date('Y-m-d'),
|
||||
'layout' => [
|
||||
'layoutNumber' => 1
|
||||
],
|
||||
'paymentTerms' => [
|
||||
'paymentTermsNumber' => 1
|
||||
],
|
||||
'recipient' => [
|
||||
'name' => $this->recipient['name'],
|
||||
'address' => $this->recipient['address'],
|
||||
'zip' => $this->recipient['zip'],
|
||||
'city' => $this->recipient['city'],
|
||||
'vatZone' => [
|
||||
'vatZoneNumber' => 1
|
||||
]
|
||||
],
|
||||
'customer' => [
|
||||
'customerNumber' => (int)$this->customer_number
|
||||
],
|
||||
'lines' => $this->lines // Lines added using the addLine method
|
||||
];
|
||||
return $this->createInvoiceDraft($data);
|
||||
}
|
||||
|
||||
public function setCustomerNumber(int $customer_number): economic_invoice_draft_mo
|
||||
{
|
||||
$this->customer_number = $customer_number;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setRecipient(string $name, string $address, string $zip, string $city): economic_invoice_draft_mo
|
||||
{
|
||||
$this->recipient = [
|
||||
'name' => $name,
|
||||
'address' => $address,
|
||||
'zip' => $zip,
|
||||
'city' => $city,
|
||||
];
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function deleteInvoiceDraft(int $value): void
|
||||
{
|
||||
// Delete the invoice draft
|
||||
$url = '/invoices/drafts/' . $value;
|
||||
$this->send_request($url, 'DELETE');
|
||||
}
|
||||
|
||||
public function publishInvoiceDraft(int $invoiceDraftId): object
|
||||
{
|
||||
// Publish the invoice draft
|
||||
$url = '/invoices/booked';
|
||||
return json_decode($this->send_request($url, 'POST', json_encode(['draftInvoice' => ['draftInvoiceNumber' => $invoiceDraftId]])));
|
||||
}
|
||||
|
||||
public function getInvoicePdf(int $param)
|
||||
{
|
||||
// Get the invoice PDF
|
||||
$url = '/invoices/booked/' . $param . '/pdf';
|
||||
return $this->send_request($url, 'GET');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace objects;
|
||||
|
||||
use classes\db;
|
||||
use classes\object_property;
|
||||
use traits\db_object_t;
|
||||
|
||||
class cron_o extends db
|
||||
{
|
||||
use db_object_t;
|
||||
public object_property $name;
|
||||
public object_property $last_run;
|
||||
public object_property $times_ran;
|
||||
|
||||
public function structure(): void
|
||||
{
|
||||
$this->setTable('cron');
|
||||
}
|
||||
|
||||
public function getObjectProperties(): void
|
||||
{
|
||||
$this->name = new object_property($this->table, $this->id, 'name', 'string', true);
|
||||
$this->last_run = new object_property($this->table, $this->id, 'last_run', 'datetime', true);
|
||||
$this->times_ran = new object_property($this->table, $this->id, 'times_ran', 'int', true);
|
||||
}
|
||||
|
||||
public function getByName(string $name): cron_o
|
||||
{
|
||||
global $db;
|
||||
// Get the record from the database
|
||||
$sql = "SELECT * FROM $this->table WHERE name = '$name'";
|
||||
$result = $db->query($sql);
|
||||
if ($result->num_rows > 0) {
|
||||
$this->id = $result->fetch_assoc()['id'];
|
||||
$this->getObjectProperties();
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function incrementTimesRan(int $id): void
|
||||
{
|
||||
global $db;
|
||||
$this->id = $id;
|
||||
// Update the record in the database
|
||||
$sql = "UPDATE $this->table SET times_ran = times_ran + 1 WHERE id = $this->id";
|
||||
$db->query($sql);
|
||||
}
|
||||
|
||||
public function updateLastRun(int $id): void
|
||||
{
|
||||
global $db;
|
||||
$this->id = $id;
|
||||
// Update the record in the database
|
||||
$sql = "UPDATE $this->table SET last_run = NOW() WHERE id = $this->id";
|
||||
$db->query($sql);
|
||||
}
|
||||
|
||||
public function getCronCreateIfNotExists(string $name): cron_o
|
||||
{
|
||||
global $db;
|
||||
// Avoid SQL injection
|
||||
$name = $db->escape_string($name);
|
||||
// Check if the record exists
|
||||
$sql = "SELECT id FROM $this->table WHERE name = '$name'";
|
||||
$result = $db->query($sql);
|
||||
if ($result->num_rows == 0) {
|
||||
// Create a new record in the database
|
||||
$sql = "INSERT INTO $this->table (name, last_run, times_ran) VALUES ('$name', NOW(), 0)";
|
||||
$db->query($sql);
|
||||
// Get the id of the new record
|
||||
$this->id = $db->insert_id();
|
||||
// Set the values of the object properties
|
||||
$this->getObjectProperties();
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
namespace objects;
|
||||
|
||||
use classes\db;
|
||||
use classes\object_property;
|
||||
use traits\db_object_t;
|
||||
|
||||
class customer_notes_o extends db
|
||||
{
|
||||
use db_object_t;
|
||||
public object_property $customer_id;
|
||||
public object_property $note;
|
||||
public object_property $cashier_id;
|
||||
public object_property $deleted_at;
|
||||
|
||||
public function structure(): void
|
||||
{
|
||||
$this->setTable('customer_notes');
|
||||
}
|
||||
|
||||
public function getObjectProperties(): void
|
||||
{
|
||||
$this->customer_id = new object_property($this->table, $this->id, 'customer_id', 'int', true);
|
||||
$this->note = new object_property($this->table, $this->id, 'note', 'string', true);
|
||||
$this->cashier_id = new object_property($this->table, $this->id, 'cashier_id', 'int', true);
|
||||
$this->deleted_at = new object_property($this->table, $this->id, 'deleted_at', 'timestamp', false);
|
||||
}
|
||||
|
||||
public function add(int $customer_id, string $note, int $cashier_id): customer_notes_o
|
||||
{
|
||||
global $db, $response;
|
||||
try {
|
||||
// Avoid SQL injection
|
||||
$note = $db->escape_string($note);
|
||||
// Create a new record in the database
|
||||
$sql = "INSERT INTO $this->table (customer_id, note, cashier_id) VALUES ($customer_id, '$note', $cashier_id)";
|
||||
$db->query($sql);
|
||||
|
||||
// Get the id of the new record
|
||||
$this->id = $db->insert_id();
|
||||
|
||||
// Set the values of the object properties
|
||||
$this->getObjectProperties();
|
||||
} catch (\Exception $e) {
|
||||
$response->error($e->getMessage());
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCustomerNotesAsArray(int $customer_id): array
|
||||
{
|
||||
global $db;
|
||||
$sql = "SELECT * FROM $this->table WHERE customer_id = $customer_id AND deleted_at IS NULL";
|
||||
$result = $db->query($sql);
|
||||
$customer_notes = [];
|
||||
if ($result->num_rows > 0) {
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$customer_notes[] = $row;
|
||||
}
|
||||
}
|
||||
return $customer_notes;
|
||||
}
|
||||
|
||||
public function getCustomerNoteById(int $id): customer_notes_o
|
||||
{
|
||||
global $db;
|
||||
// Get the record from the database
|
||||
$sql = "SELECT * FROM $this->table WHERE id = $id";
|
||||
$result = $db->query($sql);
|
||||
if ($result->num_rows > 0) {
|
||||
$this->id = $id;
|
||||
$this->getObjectProperties();
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function delete(int $id): void
|
||||
{
|
||||
global $db;
|
||||
$this->id = $id;
|
||||
$sql = "UPDATE $this->table SET deleted_at = NOW() WHERE id = $this->id";
|
||||
$db->query($sql);
|
||||
}
|
||||
|
||||
public function restore(int $id): void
|
||||
{
|
||||
global $db;
|
||||
$this->id = $id;
|
||||
$sql = "UPDATE $this->table SET deleted_at = NULL WHERE id = $this->id";
|
||||
$db->query($sql);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
namespace objects;
|
||||
|
||||
use classes\db;
|
||||
use classes\object_property;
|
||||
use classes\response;
|
||||
use traits\db_object_t;
|
||||
|
||||
class customer_vehicles_o extends db
|
||||
{
|
||||
use db_object_t;
|
||||
public object_property $customer_id; // The id of the customer
|
||||
public object_property $type; // The type of the vehicle
|
||||
public object_property $reg; // The registration number of the vehicle
|
||||
public object_property $notes; // The notes of the vehicle
|
||||
public object_property $deleted_at; // The timestamp of when the record was "deleted"
|
||||
|
||||
public function structure(): void
|
||||
{
|
||||
$this->setTable('customer_vehicles');
|
||||
}
|
||||
|
||||
public function getObjectProperties(): void
|
||||
{
|
||||
$this->customer_id = new object_property($this->table, $this->id, 'customer_id', 'int', true);
|
||||
$this->type = new object_property($this->table, $this->id, 'type', 'string', true);
|
||||
$this->reg = new object_property($this->table, $this->id, 'reg', 'string', true);
|
||||
$this->notes = new object_property($this->table, $this->id, 'notes', 'string', true);
|
||||
$this->deleted_at = new object_property($this->table, $this->id, 'deleted_at', 'timestamp', false);
|
||||
}
|
||||
|
||||
public function add(int $customer_id, string $type, string $reg, string $notes): customer_vehicles_o
|
||||
{
|
||||
global $db, $response;
|
||||
try {
|
||||
// Avoid SQL injection
|
||||
$type = $db->escape_string($type);
|
||||
$reg = $db->escape_string($reg);
|
||||
$notes = $db->escape_string($notes);
|
||||
// Create a new record in the database
|
||||
$sql = "INSERT INTO $this->table (customer_id, type, reg, notes) VALUES ($customer_id, '$type', '$reg', '$notes')";
|
||||
$db->query($sql);
|
||||
|
||||
// Get the id of the new record
|
||||
$this->id = $db->insert_id();
|
||||
|
||||
// Set the values of the object properties
|
||||
$this->getObjectProperties();
|
||||
} catch (\Exception $e) {
|
||||
$response->error($e->getMessage());
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCustomerVehiclesAsArray(int $customer_id): array
|
||||
{
|
||||
global $db;
|
||||
$sql = "SELECT * FROM $this->table WHERE customer_id = $customer_id AND deleted_at IS NULL";
|
||||
$result = $db->query($sql);
|
||||
$customer_notes = [];
|
||||
if ($result->num_rows > 0) {
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$customer_notes[] = $row;
|
||||
}
|
||||
}
|
||||
return $customer_notes;
|
||||
}
|
||||
|
||||
public function getCustomerVehiclesPaginated($customer_id, $page = 1 , $limit = 10): array
|
||||
{
|
||||
global /** @var response $response */
|
||||
$db, $response;
|
||||
$sql = "SELECT * FROM $this->table WHERE customer_id = $customer_id AND deleted_at IS NULL LIMIT $limit OFFSET " . ($page - 1) * $limit;
|
||||
$result = $db->query($sql);
|
||||
$array = $db->fetch_all($result);
|
||||
$sql = "SELECT COUNT(*) as count FROM $this->table WHERE customer_id = $customer_id AND deleted_at IS NULL";
|
||||
$result = $db->query($sql);
|
||||
$row = $db->fetch_assoc($result);
|
||||
$total = $row['count'];
|
||||
$response->paginate($page, $limit, $total);
|
||||
return $array;
|
||||
}
|
||||
public function getCustomerVehicleById(int $id): customer_vehicles_o
|
||||
{
|
||||
global $db;
|
||||
// Get the record from the database
|
||||
$sql = "SELECT * FROM $this->table WHERE id = $id";
|
||||
$result = $db->query($sql);
|
||||
if ($result->num_rows > 0) {
|
||||
$this->id = $id;
|
||||
$this->getObjectProperties();
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function delete(int $id): void
|
||||
{
|
||||
global $db;
|
||||
$this->id = $id;
|
||||
$sql = "UPDATE $this->table SET deleted_at = NOW() WHERE id = $this->id";
|
||||
$db->query($sql);
|
||||
}
|
||||
|
||||
public function restore(int $id): void
|
||||
{
|
||||
global $db;
|
||||
$this->id = $id;
|
||||
$sql = "UPDATE $this->table SET deleted_at = NULL WHERE id = $this->id";
|
||||
$db->query($sql);
|
||||
}
|
||||
|
||||
public function getArrayByObjectProperties(): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'customer_id' => $this->customer_id->value(),
|
||||
'type' => $this->type->value(),
|
||||
'reg' => $this->reg->value(),
|
||||
'notes' => $this->notes->value(),
|
||||
'deleted_at' => $this->deleted_at->value()
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace objects;
|
||||
|
||||
use classes\db;
|
||||
use classes\object_property;
|
||||
use traits\db_object_t;
|
||||
|
||||
class departments_o extends db
|
||||
{
|
||||
use db_object_t;
|
||||
public object_property $name;
|
||||
public object_property $description;
|
||||
|
||||
public function structure(): void
|
||||
{
|
||||
$this->setTable('departments');
|
||||
}
|
||||
|
||||
public function getObjectProperties(): void
|
||||
{
|
||||
$this->name = new object_property($this->table, $this->id, 'name', 'string', true);
|
||||
$this->description = new object_property($this->table, $this->id, 'description', 'string', false);
|
||||
}
|
||||
|
||||
public function create(string $name, string $description): void
|
||||
{
|
||||
global $db;
|
||||
// Avoid SQL injection
|
||||
$name = $db->escape_string($name);
|
||||
$description = $db->escape_string($description);
|
||||
// Create a new record in the database
|
||||
$sql = "INSERT INTO $this->table (name, description) VALUES ('$name', '$description')";
|
||||
$db->query($sql);
|
||||
|
||||
// Get the id of the new record
|
||||
$this->id = $db->insert_id();
|
||||
|
||||
// Set the values of the object properties
|
||||
$this->getObjectProperties();
|
||||
}
|
||||
|
||||
public function edit(int $id, string $name, string $description): void
|
||||
{
|
||||
global $db;
|
||||
$this->id = $id;
|
||||
// Avoid SQL injection
|
||||
$name = $db->escape_string($name);
|
||||
$description = $db->escape_string($description);
|
||||
// Update the record in the database
|
||||
$sql = "UPDATE $this->table SET name = '$name', description = '$description' WHERE id = $this->id";
|
||||
$db->query($sql);
|
||||
|
||||
// Set the values of the object properties
|
||||
$this->getObjectProperties();
|
||||
}
|
||||
|
||||
public function list(): array
|
||||
{
|
||||
global $db;
|
||||
$sql = "SELECT * FROM $this->table";
|
||||
$result = $db->query($sql);
|
||||
return $db->fetch_all($result);
|
||||
}
|
||||
|
||||
public function getDepartmentById(int $id): array
|
||||
{
|
||||
global $db;
|
||||
$sql = "SELECT * FROM $this->table WHERE id = $id";
|
||||
$result = $db->query($sql);
|
||||
return $db->fetch_assoc($result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace objects;
|
||||
|
||||
use classes\db;
|
||||
use classes\object_property;
|
||||
use classes\response;
|
||||
use traits\db_object_t;
|
||||
|
||||
class economic_module_orders extends db
|
||||
{
|
||||
use db_object_t;
|
||||
public object_property $economic_invoice_draft_id;
|
||||
public object_property $economic_invoice_id;
|
||||
|
||||
public function structure(): void
|
||||
{
|
||||
$this->setTable('economic_module_orders');
|
||||
}
|
||||
|
||||
public function getObjectProperties(): void
|
||||
{
|
||||
$this->economic_invoice_draft_id = new object_property($this->table, $this->id, 'invoice_draft_id', 'int', true);
|
||||
$this->economic_invoice_id = new object_property($this->table, $this->id, 'invoice_id', 'int', true);
|
||||
}
|
||||
|
||||
public function getByOrderId(int $orderId): economic_module_orders
|
||||
{
|
||||
global $db;
|
||||
// Create a new record in the database, if it does not exist
|
||||
$sql = "SELECT * FROM $this->table WHERE id = $orderId";
|
||||
$result = $db->query($sql);
|
||||
if ($result->num_rows > 0) {
|
||||
$this->id = $orderId;
|
||||
$this->getObjectProperties();
|
||||
} else {
|
||||
$this->add($orderId);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function add(int $orderId): void
|
||||
{
|
||||
global $db, $response;
|
||||
try {
|
||||
// Create a new record in the database
|
||||
$sql = "INSERT INTO $this->table (id) VALUES ($orderId)";
|
||||
$db->query($sql);
|
||||
|
||||
// Get the id of the new record
|
||||
$this->id = $orderId;
|
||||
|
||||
// Set the values of the object properties
|
||||
$this->getObjectProperties();
|
||||
} catch (\Exception $e) {
|
||||
$response->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function asArray(): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'invoice_draft_id' => $this->economic_invoice_draft_id->value(),
|
||||
'invoice_id' => $this->economic_invoice_id->value(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace objects;
|
||||
|
||||
use classes\db;
|
||||
use classes\object_property;
|
||||
use traits\db_object_t;
|
||||
|
||||
class logs_o extends db
|
||||
{
|
||||
use db_object_t;
|
||||
public object_property $module;
|
||||
public object_property $department;
|
||||
public object_property $type;
|
||||
public object_property $user_id;
|
||||
public object_property $action;
|
||||
public object_property $message;
|
||||
|
||||
public function structure(): void
|
||||
{
|
||||
$this->setTable('logs');
|
||||
}
|
||||
|
||||
public function getObjectProperties(): void
|
||||
{
|
||||
$this->module = new object_property($this->table, $this->id, 'module', 'string', true);
|
||||
$this->department = new object_property($this->table, $this->id, 'department', 'string', false);
|
||||
$this->type = new object_property($this->table, $this->id, 'type', 'int', true);
|
||||
$this->user_id = new object_property($this->table, $this->id, 'user_id', 'int', false);
|
||||
$this->action = new object_property($this->table, $this->id, 'action', 'string', true);
|
||||
$this->message = new object_property($this->table, $this->id, 'message', 'string', false);
|
||||
}
|
||||
|
||||
public function add(string $module, string $department, int $type, int $user_id, string $action, string $message): void
|
||||
{
|
||||
global $db;
|
||||
// Avoid SQL injection
|
||||
$module = $db->escape_string($module);
|
||||
$department = $db->escape_string($department);
|
||||
$action = $db->escape_string($action);
|
||||
$message = $db->escape_string($message);
|
||||
// Create a new record in the database
|
||||
$sql = "INSERT INTO $this->table (module, department, type, user_id, action, message) VALUES ('$module', '$department', $type, $user_id, '$action', '$message')";
|
||||
$db->query($sql);
|
||||
|
||||
// Get the id of the new record
|
||||
$this->id = $db->insert_id();
|
||||
|
||||
// Set the values of the object properties
|
||||
$this->getObjectProperties();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
|
||||
namespace objects;
|
||||
|
||||
use classes\db;
|
||||
use classes\object_property;
|
||||
use traits\db_object_t;
|
||||
|
||||
class order_items_o extends db
|
||||
{
|
||||
use db_object_t;
|
||||
public object_property $order_id;
|
||||
public object_property $product_id;
|
||||
public object_property $reference;
|
||||
public object_property $notes;
|
||||
public object_property $cashier_id;
|
||||
public object_property $price;
|
||||
|
||||
public function structure(): void
|
||||
{
|
||||
$this->setTable('order_items');
|
||||
}
|
||||
|
||||
public function getObjectProperties(): void
|
||||
{
|
||||
$this->order_id = new object_property($this->table, $this->id, 'order_id', 'int', true);
|
||||
$this->product_id = new object_property($this->table, $this->id, 'product_id', 'int', true);
|
||||
$this->reference = new object_property($this->table, $this->id, 'reference', 'string', true);
|
||||
$this->notes = new object_property($this->table, $this->id, 'notes', 'string', false);
|
||||
$this->cashier_id = new object_property($this->table, $this->id, 'cashier_id', 'int', true);
|
||||
$this->price = new object_property($this->table, $this->id, 'price', 'int', true);
|
||||
}
|
||||
|
||||
public function getOrderItemById(int $id): order_items_o
|
||||
{
|
||||
global $db;
|
||||
// Get the record from the database
|
||||
$sql = "SELECT * FROM $this->table WHERE id = $id";
|
||||
$result = $db->query($sql);
|
||||
if ($result->num_rows > 0) {
|
||||
$this->id = $id;
|
||||
$this->getObjectProperties();
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function add(int $order_id, int $product_id, string $reference, string $notes, int $cashier_id, int $price): void
|
||||
{
|
||||
global $db, $response;
|
||||
try {
|
||||
// Avoid SQL injection
|
||||
$reference = $db->escape_string($reference);
|
||||
$notes = $db->escape_string($notes);
|
||||
// Create a new record in the database
|
||||
$sql = "INSERT INTO $this->table (order_id, product_id, reference, notes, cashier_id, price) VALUES ($order_id, $product_id, '$reference', '$notes', $cashier_id, $price)";
|
||||
$db->query($sql);
|
||||
|
||||
// Get the id of the new record
|
||||
$this->id = $db->insert_id();
|
||||
|
||||
// Set the values of the object properties
|
||||
$this->getObjectProperties();
|
||||
} catch (\Exception $e) {
|
||||
$response->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function edit(int $id, int $order_id, int $product_id, string $reference, string $notes, int $cashier_id, int $price): void
|
||||
{
|
||||
global $db, $response;
|
||||
$this->id = $id;
|
||||
try {
|
||||
// Avoid SQL injection
|
||||
$reference = $db->escape_string($reference);
|
||||
$notes = $db->escape_string($notes);
|
||||
// Update the record in the database
|
||||
$sql = "UPDATE $this->table SET order_id = $order_id, product_id = $product_id, reference = '$reference', notes = '$notes', cashier_id = $cashier_id, price = $price WHERE id = $this->id";
|
||||
$db->query($sql);
|
||||
|
||||
// Set the values of the object properties
|
||||
$this->getObjectProperties();
|
||||
} catch (\Exception $e) {
|
||||
$response->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function addItemToOrder(int $order_id, int $product_id, int $cashier_id): void
|
||||
{
|
||||
global $db, $response;
|
||||
try {
|
||||
// Get the product price
|
||||
$sql = "SELECT price FROM products WHERE id = $product_id";
|
||||
$result = $db->query($sql);
|
||||
$row = $db->fetch_assoc($result);
|
||||
$price = $row['price'];
|
||||
|
||||
// Create a new record in the database
|
||||
$sql = "INSERT INTO $this->table (order_id, product_id, price, cashier_id) VALUES ($order_id, $product_id, $price, $cashier_id)";
|
||||
$db->query($sql);
|
||||
// Get the id of the new record
|
||||
$this->id = $db->insert_id();
|
||||
// Set the values of the object properties
|
||||
$this->getObjectProperties();
|
||||
} catch (\Exception $e) {
|
||||
$response->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function removeOrderItem(int $id): void
|
||||
{
|
||||
global $db;
|
||||
$this->id = $id;
|
||||
$sql = "DELETE FROM $this->table WHERE id = $this->id";
|
||||
$db->query($sql);
|
||||
}
|
||||
|
||||
public function getItemAsArray(): array
|
||||
{
|
||||
return [
|
||||
'id' => (int)$this->id,
|
||||
'order_id' => (int)$this->order_id->value(),
|
||||
'product_id' => (int)$this->product_id->value(),
|
||||
'reference' => (string)$this->reference->value(),
|
||||
'notes' => (string)$this->notes->value(),
|
||||
'cashier_id' => (int)$this->cashier_id->value(),
|
||||
'price' => (int)$this->price->value(),
|
||||
'product' => (array)(new products_o())->getProductById($this->product_id->value())->asArray(),
|
||||
'cashier' => (array)(new users_o())->getUserById($this->cashier_id->value())->asArray()
|
||||
];
|
||||
}
|
||||
|
||||
public function getAllItemsAsArray(int $orderId): array
|
||||
{
|
||||
global $db;
|
||||
$sql = "SELECT * FROM $this->table WHERE order_id = $orderId";
|
||||
$result = $db->query($sql);
|
||||
// Circumvent the repeated instantiation of the object, by just selecting the fields
|
||||
$items = [];
|
||||
if ($result->num_rows > 0) {
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$items[] = $row;
|
||||
}
|
||||
}
|
||||
return $items;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
<?php
|
||||
|
||||
namespace objects;
|
||||
|
||||
use classes\db;
|
||||
use classes\object_property;
|
||||
use classes\response;
|
||||
use traits\db_object_t;
|
||||
|
||||
class orders_o extends db
|
||||
{
|
||||
use db_object_t;
|
||||
public object_property $customer_id;
|
||||
public object_property $cashier_id;
|
||||
public object_property $reference;
|
||||
public object_property $notes;
|
||||
public object_property $department_id;
|
||||
public object_property $reg_1;
|
||||
public object_property $reg_2;
|
||||
public object_property $reg_3;
|
||||
public economic_module_orders $economic_module_orders;
|
||||
public object_property $created_at;
|
||||
|
||||
public function structure(): void
|
||||
{
|
||||
$this->setTable('orders');
|
||||
}
|
||||
|
||||
public function getObjectProperties(): void
|
||||
{
|
||||
$this->customer_id = new object_property($this->table, $this->id, 'customer_id', 'int', true);
|
||||
$this->cashier_id = new object_property($this->table, $this->id, 'cashier_id', 'int', true);
|
||||
$this->reference = new object_property($this->table, $this->id, 'reference', 'string', true);
|
||||
$this->notes = new object_property($this->table, $this->id, 'notes', 'string', false);
|
||||
$this->department_id = new object_property($this->table, $this->id, 'department_id', 'int', true);
|
||||
$this->reg_1 = new object_property($this->table, $this->id, 'reg_1', 'string', false);
|
||||
$this->reg_2 = new object_property($this->table, $this->id, 'reg_2', 'string', false);
|
||||
$this->reg_3 = new object_property($this->table, $this->id, 'reg_3', 'string', false);
|
||||
$this->created_at = new object_property($this->table, $this->id, 'created_at', 'timestamp', false);
|
||||
$this->economic_module_orders = (new economic_module_orders())->getByOrderId($this->id);
|
||||
}
|
||||
|
||||
public function getOrderById(int $id): orders_o
|
||||
{
|
||||
global $db;
|
||||
// Get the record from the database
|
||||
$sql = "SELECT * FROM $this->table WHERE id = $id";
|
||||
$result = $db->query($sql);
|
||||
if ($result->num_rows > 0) {
|
||||
$this->id = $id;
|
||||
$this->getObjectProperties();
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function add(int $customer_id, int $cashier_id, string $reference, string $notes, int $department_id, string $reg_1 = '', string $reg_2 = '', string $reg_3 = ''): orders_o
|
||||
{
|
||||
global $db, $response;
|
||||
try {
|
||||
// Avoid SQL injection
|
||||
$reference = $db->escape_string($reference);
|
||||
$notes = $db->escape_string($notes);
|
||||
$reg_1 = $db->escape_string($reg_1);
|
||||
$reg_2 = $db->escape_string($reg_2);
|
||||
$reg_3 = $db->escape_string($reg_3);
|
||||
// Create a new record in the database
|
||||
$sql = "INSERT INTO $this->table (customer_id, cashier_id, reference, notes, department_id, reg_1, reg_2, reg_3) VALUES ($customer_id, $cashier_id, '$reference', '$notes', $department_id, '$reg_1', '$reg_2', '$reg_3')";
|
||||
$db->query($sql);
|
||||
|
||||
// Get the id of the new record
|
||||
$this->id = $db->insert_id();
|
||||
|
||||
// Set the values of the object properties
|
||||
$this->getObjectProperties();
|
||||
return $this;
|
||||
} catch (\Exception $e) {
|
||||
$response->error($e->getMessage());
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
public function edit(int $id, int $customer_id, int $cashier_id, string $reference, string $notes, int $department_id): void
|
||||
{
|
||||
global $db, $response;
|
||||
$this->id = $id;
|
||||
try {
|
||||
// Avoid SQL injection
|
||||
$reference = $db->escape_string($reference);
|
||||
$notes = $db->escape_string($notes);
|
||||
// Update the record in the database
|
||||
$sql = "UPDATE $this->table SET customer_id = $customer_id, cashier_id = $cashier_id, reference = '$reference', notes = '$notes', department_id = $department_id WHERE id = $id";
|
||||
$db->query($sql);
|
||||
|
||||
// Set the values of the object properties
|
||||
$this->getObjectProperties();
|
||||
} catch (\Exception $e) {
|
||||
$response->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function getOrderItems(int $order_id): array
|
||||
{
|
||||
global $db;
|
||||
$sql = "SELECT * FROM order_items WHERE order_id = $order_id";
|
||||
$result = $db->query($sql);
|
||||
$order_items = [];
|
||||
if ($result->num_rows > 0 && $result) {
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$order_item = new order_items_o();
|
||||
$order_items[] = $order_item->getOrderItemById($row['id'])->getItemAsArray();
|
||||
}
|
||||
}
|
||||
return $order_items;
|
||||
}
|
||||
|
||||
public function asArray(): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'customer_id' => $this->customer_id->value(),
|
||||
'cashier_id' => $this->cashier_id->value(),
|
||||
'reference' => $this->reference->value(),
|
||||
'notes' => $this->notes->value(),
|
||||
'department_id' => $this->department_id->value(),
|
||||
'reg_1' => $this->reg_1->value(),
|
||||
'reg_2' => $this->reg_2->value(),
|
||||
'reg_3' => $this->reg_3->value(),
|
||||
'created_at' => $this->created_at->value(),
|
||||
];
|
||||
}
|
||||
|
||||
public function includeIncludes(): orders_o
|
||||
{
|
||||
global /** @var response $response */
|
||||
$response;
|
||||
$includeEverything = $response->getRequestParameter('include_all') === 'true';
|
||||
/** orderItems */
|
||||
if ($response->getRequestParameter('includeOrderItems') || $includeEverything) {
|
||||
$response->add_include('orderItems', $this->getOrderItems($this->id));
|
||||
}
|
||||
/** customer */
|
||||
if ($response->getRequestParameter('includeCustomer') || $includeEverything) {
|
||||
$customer = new users_o();
|
||||
$response->add_include('customer', $customer->getCustomerByIdOrCustomerNumber($this->customer_id->value())->includeIncludes()->asArray());
|
||||
}
|
||||
/** cashier */
|
||||
if ($response->getRequestParameter('includeCashier') || $includeEverything) {
|
||||
$cashier = new users_o();
|
||||
$response->add_include('cashier', $cashier->getUserById($this->cashier_id->value())->asArray());
|
||||
}
|
||||
/**
|
||||
* economicModuleOrders
|
||||
*/
|
||||
if ($response->getRequestParameter('includeEconomicModuleOrders') || $includeEverything) {
|
||||
$response->add_include('economicModuleOrders', $this->economic_module_orders->getByOrderId($this->id)->asArray());
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCustomerByOrderId(?string $order_id): users_o
|
||||
{
|
||||
global $db;
|
||||
$sql = "SELECT customer_id FROM orders WHERE id = $order_id";
|
||||
$result = $db->query($sql);
|
||||
if ($result->num_rows > 0) {
|
||||
$row = $result->fetch_assoc();
|
||||
return (new users_o())->getCustomerByIdOrCustomerNumber($row['customer_id']);
|
||||
}
|
||||
return new users_o();
|
||||
}
|
||||
|
||||
public function getCustomerOrdersPaginated(int $customer_number, int $page = 1, int $limit = 10, string $order = 'DESC'): array
|
||||
{
|
||||
global /** @var response $response */
|
||||
$db, $response;
|
||||
$sql = "SELECT * FROM $this->table WHERE customer_id = $customer_number ORDER BY id $order LIMIT $limit OFFSET " . ($page - 1) * $limit;
|
||||
$result = $db->query($sql);
|
||||
$array = $db->fetch_all($result);
|
||||
// Add the metadata
|
||||
$sql = "SELECT COUNT(*) as count FROM $this->table WHERE customer_id = $customer_number";
|
||||
$result = $db->query($sql);
|
||||
$row = $db->fetch_assoc($result);
|
||||
$total = $row['count'];
|
||||
$response->paginate($page, $limit, $total);
|
||||
return $array;
|
||||
}
|
||||
|
||||
public function getDepartmentByOrderId($order_id): array
|
||||
{
|
||||
return (new departments_o())->getDepartmentById($this->department_id->value());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace objects;
|
||||
|
||||
use classes\db;
|
||||
use classes\object_property;
|
||||
use traits\db_object_t;
|
||||
|
||||
class plate_scanners_o extends db
|
||||
{
|
||||
use db_object_t;
|
||||
public object_property $department_id;
|
||||
public object_property $name;
|
||||
public object_property $notes;
|
||||
public object_property $api_key;
|
||||
|
||||
public function structure(): void
|
||||
{
|
||||
$this->setTable('plate_scanners');
|
||||
}
|
||||
|
||||
public function getObjectProperties(): void
|
||||
{
|
||||
$this->department_id = new object_property($this->table, $this->id, 'department_id', 'int');
|
||||
$this->name = new object_property($this->table, $this->id, 'name', 'string');
|
||||
$this->notes = new object_property($this->table, $this->id, 'notes', 'string');
|
||||
$this->api_key = new object_property($this->table, $this->id, 'api_key', 'string');
|
||||
}
|
||||
|
||||
public function getPlateScannerById(int $id): plate_scanners_o
|
||||
{
|
||||
global $db;
|
||||
// Get the record from the database
|
||||
$sql = "SELECT * FROM $this->table WHERE id = $id";
|
||||
$result = $db->query($sql);
|
||||
if ($result->num_rows > 0) {
|
||||
$this->id = $id;
|
||||
$this->getObjectProperties();
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function add(int $department_id, string $name, string $notes): void
|
||||
{
|
||||
global $db, $response;
|
||||
try {
|
||||
// Generate an API key
|
||||
$api_key = bin2hex(random_bytes(32));
|
||||
// Avoid SQL injection
|
||||
$name = $db->escape_string($name);
|
||||
$notes = $db->escape_string($notes);
|
||||
// Create a new record in the database
|
||||
$sql = "INSERT INTO $this->table (department_id, name, notes, api_key) VALUES ($department_id, '$name', '$notes', '$api_key')";
|
||||
$db->query($sql);
|
||||
|
||||
// Get the id of the new record
|
||||
$this->id = $db->insert_id();
|
||||
|
||||
// Set the values of the object properties
|
||||
$this->getObjectProperties();
|
||||
} catch (\Exception $e) {
|
||||
$response->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function edit(int $id, int $department_id, string $name, string $notes): void
|
||||
{
|
||||
global $db, $response;
|
||||
$this->id = $id;
|
||||
try {
|
||||
// Avoid SQL injection
|
||||
$name = $db->escape_string($name);
|
||||
$notes = $db->escape_string($notes);
|
||||
// Update the record in the database
|
||||
$sql = "UPDATE $this->table SET department_id = $department_id, name = '$name', notes = '$notes' WHERE id = $id";
|
||||
$db->query($sql);
|
||||
|
||||
// Set the values of the object properties
|
||||
$this->getObjectProperties();
|
||||
} catch (\Exception $e) {
|
||||
$response->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function getPlateScannerByApiKey(mixed $token): plate_scanners_o
|
||||
{
|
||||
global $db;
|
||||
// Avoid SQL injection
|
||||
$token = $db->escape_string($token);
|
||||
// Get the record from the database
|
||||
$sql = "SELECT * FROM $this->table WHERE api_key = '$token'";
|
||||
$result = $db->query($sql);
|
||||
if ($result->num_rows > 0) {
|
||||
$this->id = $result->fetch_assoc()['id'];
|
||||
$this->getObjectProperties();
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace objects;
|
||||
|
||||
use classes\db;
|
||||
use classes\object_property;
|
||||
use traits\db_object_t;
|
||||
|
||||
class plate_scans_o extends db
|
||||
{
|
||||
use db_object_t;
|
||||
public object_property $plate_scanner_id;
|
||||
public object_property $plate;
|
||||
|
||||
public function structure(): void
|
||||
{
|
||||
$this->setTable('plate_scans');
|
||||
}
|
||||
|
||||
public function getObjectProperties(): void
|
||||
{
|
||||
$this->plate_scanner_id = new object_property($this->table, $this->id, 'plate_scanner_id', 'int');
|
||||
$this->plate = new object_property($this->table, $this->id, 'plate', 'string');
|
||||
}
|
||||
|
||||
public function getPlateScanById(int $id): plate_scans_o
|
||||
{
|
||||
global $db;
|
||||
// Get the record from the database
|
||||
$sql = "SELECT * FROM $this->table WHERE id = $id";
|
||||
$result = $db->query($sql);
|
||||
if ($result->num_rows > 0) {
|
||||
$this->id = $id;
|
||||
$this->getObjectProperties();
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function add(int $plate_scanner_id, string $plate): void
|
||||
{
|
||||
global $db, $response;
|
||||
try {
|
||||
// Avoid SQL injection
|
||||
$plate = $db->escape_string($plate);
|
||||
// Get the department id from the plate scanner id
|
||||
$sql = "SELECT department_id FROM plate_scanners WHERE id = $plate_scanner_id";
|
||||
$result = $db->query($sql);
|
||||
$row = $db->fetch_assoc($result);
|
||||
$department_id = $row['department_id'];
|
||||
// Create a new record in the database
|
||||
$sql = "INSERT INTO $this->table (plate_scanner_id, plate, department_id) VALUES ($plate_scanner_id, '$plate', $department_id)";
|
||||
$db->query($sql);
|
||||
|
||||
// Get the id of the new record
|
||||
$this->id = $db->insert_id();
|
||||
|
||||
// Set the values of the object properties
|
||||
$this->getObjectProperties();
|
||||
} catch (\Exception $e) {
|
||||
$response->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function getPlateScansByDepartment(int $department_id, int $page, int $limit): array
|
||||
{
|
||||
global $db;
|
||||
// Avoid SQL injection
|
||||
$department_id = $db->escape_string($department_id);
|
||||
$page = $db->escape_string($page);
|
||||
$limit = $db->escape_string($limit);
|
||||
// Calculate the offset
|
||||
$offset = ($page - 1) * $limit;
|
||||
$sql = "SELECT * FROM $this->table WHERE department_id = $department_id ORDER BY id DESC LIMIT $limit OFFSET $offset";
|
||||
$result = $db->query($sql);
|
||||
$plate_scans = [];
|
||||
if ($result->num_rows > 0) {
|
||||
// Return the records as an array raw data
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$plate_scans[] = $row;
|
||||
}
|
||||
}
|
||||
return $plate_scans;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
namespace objects;
|
||||
|
||||
use classes\db;
|
||||
use classes\object_property;
|
||||
use traits\db_object_t;
|
||||
|
||||
class products_o extends db
|
||||
{
|
||||
use db_object_t;
|
||||
public object_property $name;
|
||||
public object_property $description;
|
||||
public object_property $price;
|
||||
public object_property $category;
|
||||
public object_property $piktogram;
|
||||
public object_property $economic_product_id;
|
||||
|
||||
public function structure(): void
|
||||
{
|
||||
$this->setTable('products');
|
||||
}
|
||||
|
||||
public function getObjectProperties(): void
|
||||
{
|
||||
$this->name = new object_property($this->table, $this->id, 'name', 'string', true);
|
||||
$this->description = new object_property($this->table, $this->id, 'description', 'string', false);
|
||||
$this->price = new object_property($this->table, $this->id, 'price', 'int', true);
|
||||
$this->category = new object_property($this->table, $this->id, 'category', 'string', true);
|
||||
$this->piktogram = new object_property($this->table, $this->id, 'piktogram', 'string', false);
|
||||
$this->economic_product_id = new object_property($this->table, $this->id, 'economic_product_id', 'int', false);
|
||||
}
|
||||
|
||||
public function getProductById(int $id): products_o
|
||||
{
|
||||
global $db;
|
||||
// Get the record from the database
|
||||
$sql = "SELECT * FROM $this->table WHERE id = $id";
|
||||
$result = $db->query($sql);
|
||||
if ($result->num_rows > 0) {
|
||||
$this->id = $id;
|
||||
$this->getObjectProperties();
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function add(string $name, string $description, int $price, string|bool $category = false, string|bool $piktogram = false, string|bool $economicProductId = false): void
|
||||
{
|
||||
global $db, $response;
|
||||
try {
|
||||
// Avoid SQL injection
|
||||
$name = $db->escape_string($name);
|
||||
$description = $db->escape_string($description);
|
||||
$category = $category ? $db->escape_string($category) : null;
|
||||
$piktogram = $piktogram ? $db->escape_string($piktogram) : '';
|
||||
$economicProductId = $economicProductId ? $db->escape_string($economicProductId) : null;
|
||||
// Create a new record in the database
|
||||
$sql = "INSERT INTO $this->table (name, description, price, category, piktogram, economic_product_id) VALUES ('$name', '$description', $price, '$category', '$piktogram', '$economicProductId')";
|
||||
$db->query($sql);
|
||||
|
||||
// Get the id of the new record
|
||||
$this->id = $db->insert_id();
|
||||
|
||||
// Set the values of the object properties
|
||||
$this->getObjectProperties();
|
||||
} catch (\Exception $e) {
|
||||
$response->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function edit(mixed $id, mixed $name, mixed $description, mixed $price, mixed $category = false, mixed $piktogram = false, mixed $economicProductId = false): void
|
||||
{
|
||||
global $db, $response;
|
||||
$this->id = $id;
|
||||
try {
|
||||
// Avoid SQL injection
|
||||
$name = $db->escape_string($name);
|
||||
$description = $db->escape_string($description);
|
||||
$category = $category ? $db->escape_string($category) : null;
|
||||
$piktogram = $piktogram ? $db->escape_string($piktogram) : '';
|
||||
$economicProductId = $economicProductId ? $db->escape_string($economicProductId) : null;
|
||||
// Update the record in the database
|
||||
$sql = "UPDATE $this->table SET name = '$name', description = '$description', price = $price, category = '$category', piktogram = '$piktogram', economic_product_id = '$economicProductId' WHERE id = $id";
|
||||
$db->query($sql);
|
||||
|
||||
// Set the values of the object properties
|
||||
$this->getObjectProperties();
|
||||
} catch (\Exception $e) {
|
||||
$response->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function listObjectsByCategory(string $category): array
|
||||
{
|
||||
global $db;
|
||||
$category = $db->escape_string($category);
|
||||
$sql = "SELECT * FROM $this->table WHERE category = '$category'";
|
||||
$result = $db->query($sql);
|
||||
return $db->fetch_all($result);
|
||||
}
|
||||
|
||||
public function asArray(): array
|
||||
{
|
||||
return [
|
||||
'id' => (int)$this->id,
|
||||
'name' => (string)$this->name->value(),
|
||||
'description' => (string)$this->description->value(),
|
||||
'price' => (int)$this->price->value(),
|
||||
'category' => $this->category->value(),
|
||||
'piktogram' => $this->piktogram->value(),
|
||||
'economic_product_id' => $this->economic_product_id->value(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
namespace objects;
|
||||
|
||||
use classes\db;
|
||||
use classes\object_property;
|
||||
use traits\db_object_t;
|
||||
|
||||
class ratelimit_o extends db
|
||||
{
|
||||
use db_object_t;
|
||||
public object_property $ip;
|
||||
public object_property $count;
|
||||
public object_property $total_count;
|
||||
|
||||
public function structure(): void
|
||||
{
|
||||
$this->setTable('ratelimit');
|
||||
}
|
||||
|
||||
public function getObjectProperties(): void
|
||||
{
|
||||
$this->ip = new object_property($this->table, $this->id, 'ip', 'string', true);
|
||||
$this->count = new object_property($this->table, $this->id, 'count', 'int', true);
|
||||
$this->total_count = new object_property($this->table, $this->id, 'total_count', 'int', true);
|
||||
}
|
||||
|
||||
public function getRateLimitByIp(string $ip): ratelimit_o
|
||||
{
|
||||
global $db;
|
||||
// Get the record from the database
|
||||
$sql = "SELECT * FROM $this->table WHERE ip = '$ip'";
|
||||
$result = $db->query($sql);
|
||||
if ($result->num_rows > 0) {
|
||||
$this->id = $result->fetch_assoc()['id'];
|
||||
$this->getObjectProperties();
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRateLimitById(int $id): ratelimit_o
|
||||
{
|
||||
global $db;
|
||||
// Get the record from the database
|
||||
$sql = "SELECT * FROM $this->table WHERE id = $id";
|
||||
$result = $db->query($sql);
|
||||
if ($result->num_rows > 0) {
|
||||
$this->id = $id;
|
||||
$this->getObjectProperties();
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function increment(int $id, int $count): void
|
||||
{
|
||||
global $db;
|
||||
$this->id = $id;
|
||||
// Update the record in the database
|
||||
$sql = "UPDATE $this->table SET count = count + $count, total_count = total_count + $count WHERE id = $this->id";
|
||||
$db->query($sql);
|
||||
|
||||
// Set the values of the object properties
|
||||
$this->getObjectProperties();
|
||||
}
|
||||
|
||||
public function reset(int $id): void
|
||||
{
|
||||
global $db;
|
||||
$this->id = $id;
|
||||
// Update the record in the database
|
||||
$sql = "UPDATE $this->table SET count = 0 WHERE id = $this->id";
|
||||
$db->query($sql);
|
||||
|
||||
// Set the values of the object properties
|
||||
$this->getObjectProperties();
|
||||
}
|
||||
|
||||
public function create(string $ip): void
|
||||
{
|
||||
global $db;
|
||||
// Avoid SQL injection
|
||||
$ip = $db->escape_string($ip);
|
||||
// Create a new record in the database
|
||||
$sql = "INSERT INTO $this->table (ip, count, total_count) VALUES ('$ip', 1, 1)";
|
||||
$db->query($sql);
|
||||
|
||||
// Get the id of the new record
|
||||
$this->id = $db->insert_id();
|
||||
|
||||
// Set the values of the object properties
|
||||
$this->getObjectProperties();
|
||||
}
|
||||
|
||||
public function getOrCreateRateLimitByIp(string $ip): ratelimit_o
|
||||
{
|
||||
$ratelimit = $this->getRateLimitByIp($ip);
|
||||
if (!$ratelimit->id) {
|
||||
$this->create($ip);
|
||||
return $this;
|
||||
}
|
||||
return $ratelimit;
|
||||
}
|
||||
|
||||
public function resetAll(): void
|
||||
{
|
||||
global $db;
|
||||
// Reset all the ratelimits
|
||||
$sql = "UPDATE $this->table SET count = 0";
|
||||
$db->query($sql);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace objects;
|
||||
|
||||
use classes\db;
|
||||
use classes\object_property;
|
||||
use Exception;
|
||||
use traits\db_object_t;
|
||||
|
||||
class tokens_o extends db
|
||||
{
|
||||
use db_object_t;
|
||||
public object_property $user_id;
|
||||
public object_property $type; // AUTH_TOKEN, RESET_PASSWORD
|
||||
public object_property $token;
|
||||
|
||||
public function structure(): void
|
||||
{
|
||||
$this->setTable('tokens');
|
||||
}
|
||||
|
||||
public function getObjectProperties(): void
|
||||
{
|
||||
$this->user_id = new object_property($this->table, $this->id, 'user_id', 'int', true);
|
||||
$this->type = new object_property($this->table, $this->id, 'type', 'string', true);
|
||||
$this->token = new object_property($this->table, $this->id, 'token', 'string', true);
|
||||
}
|
||||
|
||||
public function create(int $user_id, string $token, string $type = 'AUTH_TOKEN'): void
|
||||
{
|
||||
global $db;
|
||||
// Avoid SQL injection
|
||||
$token = $db->escape_string($token);
|
||||
// Create a new record in the database
|
||||
$sql = "INSERT INTO $this->table (user_id, token, type) VALUES ($user_id, '$token', '$type')";
|
||||
$db->query($sql);
|
||||
|
||||
// Get the id of the new record
|
||||
$this->id = $db->insert_id();
|
||||
|
||||
// Set the values of the object properties
|
||||
$this->getObjectProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getToken(string $token): tokens_o
|
||||
{
|
||||
global $db;
|
||||
// Avoid SQL injection
|
||||
$token = $db->escape_string($token);
|
||||
// Prepare the SQL statement
|
||||
$sql = "SELECT id FROM $this->table WHERE token = '$token'";
|
||||
$result = $db->query($sql);
|
||||
$row = $db->fetch_assoc($result);
|
||||
if (!$row) {
|
||||
throw new Exception("Token not found " . $token);
|
||||
}
|
||||
$this->id = $row['id'];
|
||||
$this->getObjectProperties();
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function delete(string $token): void
|
||||
{
|
||||
global $db;
|
||||
// Avoid SQL injection
|
||||
$token = $db->escape_string($token);
|
||||
// Prepare the SQL statement
|
||||
$sql = "DELETE FROM $this->table WHERE token = '$token'";
|
||||
$db->query($sql);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,357 @@
|
||||
<?php
|
||||
|
||||
namespace objects;
|
||||
|
||||
use classes\db;
|
||||
use classes\object_property;
|
||||
use classes\response;
|
||||
use customers\economic_customer_mo;
|
||||
use customers\economicCustomers;
|
||||
use traits\db_object_t;
|
||||
|
||||
class users_o extends db
|
||||
{
|
||||
use db_object_t;
|
||||
public object_property $customer_number;
|
||||
public object_property $password;
|
||||
public object_property $group_id;
|
||||
public economic_customer_mo $economic_customer;
|
||||
public object_property $created_at;
|
||||
public object_property $updated_at;
|
||||
public array $permissions;
|
||||
|
||||
public function structure(): void
|
||||
{
|
||||
$this->setTable('users');
|
||||
}
|
||||
|
||||
public function getObjectProperties(): void
|
||||
{
|
||||
$this->customer_number = new object_property($this->table, $this->id, 'customer_number', 'string', true);
|
||||
$this->password = new object_property($this->table, $this->id, 'password', 'string', true);
|
||||
$this->group_id = new object_property($this->table, $this->id, 'group_id', 'int', true);
|
||||
$this->created_at = new object_property($this->table, $this->id, 'created_at', 'string', false);
|
||||
$this->updated_at = new object_property($this->table, $this->id, 'updated_at', 'string', false);
|
||||
}
|
||||
|
||||
public function getUserByCustomerNumber(int $customer_number): users_o
|
||||
{
|
||||
global $db;
|
||||
// Get the record from the database
|
||||
$sql = "SELECT * FROM $this->table WHERE customer_number = '$customer_number'";
|
||||
$result = $db->query($sql);
|
||||
if ($result->num_rows > 0) {
|
||||
$this->id = $result->fetch_assoc()['id'];
|
||||
$this->getObjectProperties();
|
||||
} else {
|
||||
// Import the customer
|
||||
$this->importCustomerFromExternalSource($customer_number);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getUserById(int $id): users_o
|
||||
{
|
||||
global $db;
|
||||
// Get the record from the database
|
||||
$sql = "SELECT * FROM $this->table WHERE id = $id";
|
||||
$result = $db->query($sql);
|
||||
if ($result->num_rows > 0) {
|
||||
$this->id = $id;
|
||||
$this->getObjectProperties();
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function add(string $customer_number, mixed $password): void
|
||||
{
|
||||
global $db;
|
||||
// Avoid SQL injection
|
||||
$customer_number = $db->escape_string($customer_number);
|
||||
// Hash the password
|
||||
$password = password_hash($password, PASSWORD_DEFAULT);
|
||||
$password = $db->escape_string($password);
|
||||
// Create a new record in the database
|
||||
$sql = "INSERT INTO $this->table (customer_number, password) VALUES ('$customer_number', '$password')";
|
||||
$db->query($sql);
|
||||
|
||||
// Get the id of the new record
|
||||
$this->id = $db->insert_id();
|
||||
|
||||
// Set the values of the object properties
|
||||
$this->getObjectProperties();
|
||||
}
|
||||
|
||||
public function hasPermission(string $permission): bool
|
||||
{
|
||||
global $db;
|
||||
// Get the user's group id
|
||||
$group_id = $this->group_id->value();
|
||||
// If the users is an admin, they have all permissions
|
||||
if ((int)$group_id === 1) {
|
||||
return true;
|
||||
}
|
||||
// Get the record from the database
|
||||
$sql = "SELECT * FROM groups_permissions WHERE group_id = $group_id AND permission = '$permission'";
|
||||
$result = $db->query($sql);
|
||||
if ($result->num_rows > 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function edit(int $id, string $customer_number, string|null $role, string|null $password): void
|
||||
{
|
||||
global $db;
|
||||
$this->id = $id;
|
||||
// Avoid SQL injection
|
||||
$customer_number = $db->escape_string($customer_number);
|
||||
if ($password !== null) {
|
||||
// Hash the password
|
||||
$password = password_hash($password, PASSWORD_DEFAULT);
|
||||
$password = $db->escape_string($password);
|
||||
}
|
||||
if ($role !== null) {
|
||||
$role = $db->escape_string($role);
|
||||
}
|
||||
// Update the record in the database
|
||||
$sql = "UPDATE $this->table SET customer_number = '$customer_number'";
|
||||
if ($password !== null) {
|
||||
$sql .= ", password = '$password'";
|
||||
}
|
||||
if ($role !== null) {
|
||||
$sql .= ", group_id = '$role'";
|
||||
}
|
||||
$sql .= " WHERE id = $this->id";
|
||||
$db->query($sql);
|
||||
|
||||
// Set the values of the object properties
|
||||
$this->getObjectProperties();
|
||||
}
|
||||
|
||||
public function getCustomerByIdOrCustomerNumber(int $idOrCustomerNumber): users_o
|
||||
{
|
||||
global $db;
|
||||
// Get the record from the database
|
||||
$sql = "SELECT * FROM $this->table WHERE id = $idOrCustomerNumber OR customer_number = '$idOrCustomerNumber'";
|
||||
$result = $db->query($sql);
|
||||
if ($result->num_rows > 0) {
|
||||
$this->id = $result->fetch_assoc()['id'];
|
||||
$this->getObjectProperties();
|
||||
} else {
|
||||
// Import the customer
|
||||
$this->importCustomerFromExternalSource($idOrCustomerNumber);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function automaticGetTargetUserFromRequest(): users_o
|
||||
{
|
||||
// Get the data from the request
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'GET' || $_SERVER['REQUEST_METHOD'] === 'DELETE') {
|
||||
$data = $_GET;
|
||||
} else {
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
}
|
||||
// Check if the user id is set in the request
|
||||
if (isset($data['user_id'])) {
|
||||
return $this->getUserById((int)$data['user_id']);
|
||||
} elseif (isset($data['customer_number'])) {
|
||||
return $this->getUserByCustomerNumber($data['customer_number']);
|
||||
} else {
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
public function asArray(): array
|
||||
{
|
||||
$array = [
|
||||
'id' => (int)$this->id,
|
||||
'customer_number' => (int)$this->customer_number->value(),
|
||||
'group_id' => (int)$this->group_id->value(),
|
||||
'created_at' => $this->created_at->value(),
|
||||
'updated_at' => $this->updated_at->value(),
|
||||
];
|
||||
// If the economic customer data is set, add it to the array
|
||||
if (isset($this->economic_customer)) {
|
||||
$array['economic_customer'] = $this->economic_customer->asArray();
|
||||
}
|
||||
// If the permissions are set, add them to the array
|
||||
if (isset($this->permissions)) {
|
||||
$array['permissions'] = $this->permissions;
|
||||
}
|
||||
return $array;
|
||||
}
|
||||
|
||||
public function getNotes():array
|
||||
{
|
||||
global $db;
|
||||
// Create the customer notes object
|
||||
$customer_notes = new customer_notes_o();
|
||||
// Get the customer notes
|
||||
return $customer_notes->getCustomerNotesAsArray($this->id);
|
||||
}
|
||||
|
||||
public function addNote($customer_id, $note, $cashier_id): void
|
||||
{
|
||||
global $db;
|
||||
// Create the customer notes object
|
||||
$customer_notes = new customer_notes_o();
|
||||
// Add the note
|
||||
$customer_notes->add($customer_id, $note, $cashier_id);
|
||||
}
|
||||
|
||||
public function deleteNote(int $note_id): void
|
||||
{
|
||||
global $db;
|
||||
// Create the customer notes object
|
||||
$customer_notes = new customer_notes_o();
|
||||
// Delete the note
|
||||
$customer_notes->delete($note_id);
|
||||
}
|
||||
|
||||
public function getOrImportCustomerByCustomerNumber(int $customer_number): object|bool
|
||||
{
|
||||
global $db;
|
||||
// Check if the customer exists
|
||||
$sql = "SELECT * FROM $this->table WHERE customer_number = $customer_number";
|
||||
$result = $db->query($sql);
|
||||
if ($result->num_rows > 0) {
|
||||
$this->id = $result->fetch_assoc()['id'];
|
||||
$this->getObjectProperties();
|
||||
} else {
|
||||
// Import the customer
|
||||
return $this->importCustomerFromExternalSource($customer_number);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function importCustomerFromExternalSource(int $customer_number): object|bool
|
||||
{
|
||||
global $db;
|
||||
// Get the customer data from the external source
|
||||
$economic = new economicCustomers();
|
||||
$customer_data = $economic->getCustomerId($customer_number);
|
||||
// DEBUG: Return the customer data
|
||||
// Check if the customer exists
|
||||
if (isset($customer_data[0])) {
|
||||
// Avoid SQL injection
|
||||
$customer_number = $db->escape_string($customer_data[0]->customerNumber);
|
||||
// Create a new record in the database
|
||||
$sql = "INSERT INTO $this->table (customer_number) VALUES ('$customer_number')";
|
||||
$db->query($sql);
|
||||
// Get the id of the new record
|
||||
$this->id = $db->insert_id();
|
||||
// Set the values of the object properties
|
||||
$this->getObjectProperties();
|
||||
}
|
||||
// Else return false
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getCustomerEcocomicData(int $customer_number = null): users_o
|
||||
{
|
||||
// Get the customer data from the external source
|
||||
$economic = new economicCustomers();
|
||||
// Check if the customer number is set
|
||||
if (!isset($this->customer_number) && $customer_number === null) {
|
||||
return $this;
|
||||
}
|
||||
$customer_number = $customer_number ?? $this->customer_number->value();
|
||||
$this->economic_customer = (new economic_customer_mo())->getCustomerByCustomerNumber($customer_number);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getUserAttributes(int $user_id = null): array
|
||||
{
|
||||
global $db;
|
||||
if ($user_id === null) {
|
||||
$user_id = $this->id;
|
||||
}
|
||||
$sql = "SELECT * FROM maintenancemode_dbtest.customer_attributes WHERE user_id = $user_id";
|
||||
$result = $db->query($sql);
|
||||
return $db->fetch_all($result);
|
||||
}
|
||||
|
||||
public function doesUserHaveAttribute(string $attribute, int $user_id = null): bool
|
||||
{
|
||||
global $db;
|
||||
if ($user_id === null) {
|
||||
$user_id = $this->id;
|
||||
}
|
||||
$attribute = $db->escape_string($attribute);
|
||||
$sql = "SELECT * FROM maintenancemode_dbtest.customer_attributes WHERE user_id = $user_id AND attribute = '$attribute'";
|
||||
$result = $db->query($sql);
|
||||
if ($result->num_rows > 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function addAttribute(string $attribute, int $user_id = null): void
|
||||
{
|
||||
global $db;
|
||||
if ($user_id === null) {
|
||||
$user_id = $this->id;
|
||||
}
|
||||
$attribute = $db->escape_string($attribute);
|
||||
// Make sure the attribute does not already exist
|
||||
if ($this->doesUserHaveAttribute((string)$attribute, (int)$user_id)) {
|
||||
return;
|
||||
}
|
||||
$sql = "INSERT INTO maintenancemode_dbtest.customer_attributes (user_id, attribute) VALUES ($user_id, '$attribute')";
|
||||
$db->query($sql);
|
||||
}
|
||||
|
||||
public function deleteAttribute(string $attribute, int $user_id = null): void
|
||||
{
|
||||
global $db;
|
||||
if ($user_id === null) {
|
||||
$user_id = $this->id;
|
||||
}
|
||||
$attribute = $db->escape_string($attribute);
|
||||
// Make sure the attribute exists
|
||||
if (!$this->doesUserHaveAttribute((string)$attribute, (int)$user_id)) {
|
||||
return;
|
||||
}
|
||||
$sql = "DELETE FROM maintenancemode_dbtest.customer_attributes WHERE user_id = $user_id AND attribute = '$attribute'";
|
||||
$db->query($sql);
|
||||
}
|
||||
|
||||
public function requiresReference(): bool
|
||||
{
|
||||
return $this->doesUserHaveAttribute('requiresReferenceNumber');
|
||||
}
|
||||
|
||||
public function includeIncludes(array $includes = []): users_o
|
||||
{
|
||||
global /** @var response $response */
|
||||
$response;
|
||||
$includeEverything = $response->getRequestParameter('include_all') === 'true' || in_array('all', $includes);
|
||||
/**
|
||||
* economicCustomer
|
||||
*/
|
||||
if ($includeEverything || $response->getRequestParameter('includeEconomicCustomer') === 'true' || in_array('economicCustomer', $includes)) {
|
||||
$this->getCustomerEcocomicData();
|
||||
}
|
||||
/**
|
||||
* permissions
|
||||
*/
|
||||
if ($includeEverything || $response->getRequestParameter('includePermissions') === 'true' || in_array('permissions', $includes)) {
|
||||
$this->getPermissions();
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function getPermissions(): void
|
||||
{
|
||||
global $db;
|
||||
$sql = "SELECT permission FROM groups_permissions WHERE group_id = " . $this->group_id->value();
|
||||
$result = $db->query($sql);
|
||||
$perms = [];
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$perms[] = $row['permission'];
|
||||
}
|
||||
$this->permissions = $perms;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace routes;
|
||||
|
||||
use classes\authentication;
|
||||
use classes\encrypt;
|
||||
use objects\logs_o;
|
||||
use objects\tokens_o;
|
||||
use objects\users_o;
|
||||
use traits\route_t;
|
||||
|
||||
class authRoute
|
||||
{
|
||||
use route_t;
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$this->post('/auth/login', function () {
|
||||
// Get the post data
|
||||
global $response;
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
// Check if the customer number, and password are set
|
||||
if (!isset($data['customer_number'])) { $response->error('Customer number is required', 400); }
|
||||
if (!isset($data['password'])) { $response->error('Password is required', 400); }
|
||||
// Try to log the user in
|
||||
$isCredentialsValid = (new authentication())->authenticate($data['customer_number'], $data['password']);
|
||||
// Log the incident
|
||||
if ($isCredentialsValid) {
|
||||
(new logs_o())->add('auth', 'global', 1, 0, 'AUTH_SUCCESS', 'Customer number: ' . $data['customer_number']);
|
||||
} else {
|
||||
(new logs_o())->add('auth', 'global', 1, 0, 'AUTH_FAILURE', 'Customer number: ' . $data['customer_number']);
|
||||
$response->error('Invalid credentials', 401);
|
||||
}
|
||||
// If the credentials are valid, create a token
|
||||
$token = (new authentication())->create_token($data['customer_number']);
|
||||
// Return the token
|
||||
$response->success(['token' => $token]);
|
||||
});
|
||||
|
||||
$this->get('/auth/logout', function () {
|
||||
// Get the token from the headers
|
||||
global $response;
|
||||
$token = $_SERVER['HTTP_AUTHORIZATION'];
|
||||
// Remove the Bearer prefix
|
||||
$token = str_replace('Bearer ', '', $token);
|
||||
// Check if the token is valid
|
||||
if (!(new authentication())->validate_token($token)) {
|
||||
$response->error('Invalid token', 401);
|
||||
}
|
||||
// Delete the token
|
||||
(new tokens_o())->delete($token);
|
||||
// Return a success message
|
||||
$response->success(['message' => 'Logged out']);
|
||||
});
|
||||
|
||||
$this->get('/auth/session', function () {
|
||||
// Get the token from the headers
|
||||
global $response;
|
||||
$token = $_SERVER['HTTP_AUTHORIZATION'];
|
||||
// Remove the Bearer prefix
|
||||
$token = str_replace('Bearer ', '', $token);
|
||||
// Check if the token is valid
|
||||
if (!(new authentication())->validate_token($token)) {
|
||||
$response->error('Invalid token', 401);
|
||||
}
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the user exists
|
||||
if (!$user) {
|
||||
$response->error('User not found', 400);
|
||||
}
|
||||
// Return the (session) user object
|
||||
$response->success(
|
||||
($user->includeIncludes(['economicCustomer', 'permissions'])->asArray())
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
namespace routes;
|
||||
|
||||
use classes\authentication;
|
||||
use objects\customer_notes_o;
|
||||
use objects\logs_o;
|
||||
use objects\users_o;
|
||||
use traits\route_t;
|
||||
|
||||
class customerAttributes
|
||||
{
|
||||
use route_t;
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$this->get('/customer/attributes', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('list_customer_attributes');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Get the query parameters from the URL
|
||||
$data = $_GET;
|
||||
// Check if the required fields are set
|
||||
if (!isset($data['customer_number']) && !isset($data['user_id'])) {
|
||||
$response->error('User ID or Customer Number is required', 400);
|
||||
}
|
||||
// Log the incident
|
||||
(new logs_o())->add('customer_attributes', 'global', 1, $user->id, 'LIST_CUSTOMER_ATTRIBUTES', 'Successfully listed customer attributes');
|
||||
// Check if the user exists
|
||||
if (!(new users_o())->automaticGetTargetUserFromRequest()->exists()) {
|
||||
$response->error('Customer not found', 400);
|
||||
}
|
||||
// Return the list of customer notes
|
||||
$response->success(
|
||||
(new users_o())->automaticGetTargetUserFromRequest()->getUserAttributes()
|
||||
);
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('customer_attributes', 'global', 1, 0, 'LIST_CUSTOMER_ATTRIBUTES', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
|
||||
$this->post('/customer/attributes', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('add_customer_attribute');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Get the post data
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
// Check if the required fields are set
|
||||
if (!isset($data['user_id']) && !isset($data['customer_number'])) {
|
||||
$response->error('User ID or Customer Number is required', 400);
|
||||
}
|
||||
if (!isset($data['attribute'])) {
|
||||
$response->error('Attribute is required', 400);
|
||||
}
|
||||
// Add the note to the customer
|
||||
(new users_o())->automaticGetTargetUserFromRequest()->addAttribute((string)$data['attribute']);
|
||||
// Log the incident
|
||||
(new logs_o())->add('customer_attributes', 'global', 1, $user->id, 'ADD_CUSTOMER_ATTRIBUTE', 'Successfully added a customer attribute');
|
||||
// Return a success message
|
||||
$response->success(['message' => 'Customer attribute added']);
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('customer_attributes', 'global', 1, 0, 'ADD_CUSTOMER_ATTRIBUTE', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
|
||||
$this->delete('/customer/attributes', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('delete_customer_attribute');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Get the query parameters from the URL
|
||||
$data = $_GET;
|
||||
// Check if the required fields are set
|
||||
if (!isset($data['user_id']) && !isset($data['customer_number'])) {
|
||||
$response->error('User ID or Customer Number is required', 400);
|
||||
}
|
||||
if (!isset($data['attribute'])) {
|
||||
$response->error('Attribute is required', 400);
|
||||
}
|
||||
// Check if the user exists
|
||||
if (!(new users_o())->automaticGetTargetUserFromRequest()->exists()) {
|
||||
$response->error('Customer not found', 400);
|
||||
}
|
||||
// Add the note to the customer
|
||||
(new users_o())->automaticGetTargetUserFromRequest()->deleteAttribute($data['attribute']);
|
||||
// Log the incident
|
||||
(new logs_o())->add('customer_attributes', 'global', 1, $user->id, 'DELETE_CUSTOMER_ATTRIBUTE', 'Successfully deleted a customer attribute');
|
||||
// Return a success message
|
||||
$response->success(['message' => 'Customer attribute deleted']);
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('customer_attributes', 'global', 1, 0, 'DELETE_CUSTOMER_ATTRIBUTE', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
namespace routes;
|
||||
|
||||
use classes\authentication;
|
||||
use objects\customer_notes_o;
|
||||
use objects\logs_o;
|
||||
use objects\users_o;
|
||||
use traits\route_t;
|
||||
|
||||
class customerNotes
|
||||
{
|
||||
use route_t;
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$this->get('/customer/notes', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('list_customer_notes');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Get the query parameters from the URL
|
||||
$data = $_GET;
|
||||
// Check if the required fields are set
|
||||
if (!isset($data['customer_number']) && !isset($data['user_id'])) { $response->error('User ID or Customer Number is required', 400); }
|
||||
// Log the incident
|
||||
(new logs_o())->add('customer_notes', 'global', 1, $user->id, 'LIST_CUSTOMER_NOTES', 'Successfully listed customer notes');
|
||||
// Check if the user exists
|
||||
if (!(new users_o())->automaticGetTargetUserFromRequest()->exists()) {
|
||||
$response->error('Customer not found', 400);
|
||||
}
|
||||
// Return the list of customer notes
|
||||
$response->success(
|
||||
(new users_o())->automaticGetTargetUserFromRequest()->getNotes()
|
||||
);
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('customer_notes', 'global', 1, 0, 'LIST_CUSTOMER_NOTES', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
|
||||
$this->post('/customer/notes', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('add_customer_note');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Get the post data
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
// Check if the required fields are set
|
||||
if (!isset($data['user_id']) && !isset($data['customer_number'])) { $response->error('User ID or Customer Number is required', 400); }
|
||||
if (!isset($data['note'])) { $response->error('Note is required', 400); }
|
||||
// Add the note to the customer
|
||||
$customer = (new users_o())->automaticGetTargetUserFromRequest();
|
||||
// Check if the customer exists
|
||||
if (!$customer->exists()) {
|
||||
$response->error('Customer not found', 400);
|
||||
}
|
||||
$customer->addNote((int)$customer->id, (string)$data['note'], (int)$user->id);
|
||||
// Log the incident
|
||||
(new logs_o())->add('customer_notes', 'global', 1, $user->id, 'ADD_CUSTOMER_NOTE', 'Successfully added a customer note');
|
||||
// Return a success message
|
||||
$response->success(['message' => 'Customer note added']);
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('customer_notes', 'global', 1, 0, 'ADD_CUSTOMER_NOTE', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
|
||||
$this->delete('/customer/notes', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('delete_customer_note');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Get the query parameters from the URL
|
||||
$data = $_GET;
|
||||
// Check if the required fields are set
|
||||
if (!isset($data['id'])) { $response->error('Note ID is required', 400); }
|
||||
// Delete the note from the customer
|
||||
(new customer_notes_o())->delete((int)$data['id']);
|
||||
// Log the incident
|
||||
(new logs_o())->add('customer_notes', 'global', 1, $user->id, 'DELETE_CUSTOMER_NOTE', 'Successfully deleted a customer note');
|
||||
// Return a success message
|
||||
$response->success(['message' => 'Customer note deleted']);
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('customer_notes', 'global', 1, 0, 'DELETE_CUSTOMER_NOTE', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace routes;
|
||||
|
||||
use classes\authentication;
|
||||
use customers\economicCustomers;
|
||||
use objects\logs_o;
|
||||
use objects\users_o;
|
||||
use traits\route_t;
|
||||
|
||||
class customerSearchRoute
|
||||
{
|
||||
use route_t;
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$this->post('/customers/search', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('search_customers');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Get the post data
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
// Check if the pagination, search and sort parameters are set
|
||||
if (!isset($data['search'])) {
|
||||
$response->error('Missing required body parameter search', 400);
|
||||
}
|
||||
if (!isset($data['filter'])) {
|
||||
$response->error('Missing required body parameter filter', 400);
|
||||
}
|
||||
// Check if the search parameter is valid
|
||||
$allowedSearchFilters = (new economicCustomers())->allowed_search_filters_customers();
|
||||
if (!in_array($data['filter'], $allowedSearchFilters)) {
|
||||
$response->error('Invalid search parameter', 400);
|
||||
}
|
||||
(new logs_o())->add('customers', 'global', 1, $user->id, 'SEARCH_CUSTOMERS', 'Successfully retrieved customers meeting search criteria');
|
||||
// Return the list of users
|
||||
$response->success(
|
||||
(array)(new economicCustomers())->searchCustomers((string)$data['search'], (string)$data['filter'])
|
||||
);
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('customers', 'global', 1, 0, 'SEARCH_CUSTOMERS', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace routes;
|
||||
|
||||
use classes\authentication;
|
||||
use objects\departments_o;
|
||||
use objects\logs_o;
|
||||
use objects\users_o;
|
||||
use traits\route_t;
|
||||
|
||||
class departmentsRoute
|
||||
{
|
||||
use route_t;
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$this->get('/departments', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('list_departments');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Log the incident
|
||||
(new logs_o())->add('departments', 'global', 1, $user->id, 'LIST_DEPARTMENTS', 'Successfully listed departments');
|
||||
// Return the list of departments
|
||||
$response->success(
|
||||
(new departments_o())->list()
|
||||
);
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('departments', 'global', 1, 0, 'LIST_DEPARTMENTS', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
|
||||
$this->post('/departments', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('add_department');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Get the post data
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
// Check if the required fields are set
|
||||
if (!isset($data['name'])) { $response->error('Name is required', 400); }
|
||||
if (!isset($data['description'])) { $response->error('Description is required', 400); }
|
||||
// Add the department
|
||||
(new departments_o())->create($data['name'], $data['description']);
|
||||
// Log the incident
|
||||
(new logs_o())->add('departments', 'global', 1, $user->id, 'ADD_DEPARTMENT', 'Successfully added a department ' . $data['name']);
|
||||
// Return a success message
|
||||
$response->success(['message' => 'Department added successfully']);
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('departments', 'global', 1, 0, 'ADD_DEPARTMENT', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
|
||||
$this->put('/departments', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('edit_department');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Get the post data
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
// Check if the required fields are set
|
||||
if (!isset($data['id'])) { $response->error('ID is required', 400); }
|
||||
if (!isset($data['name'])) { $response->error('Name is required', 400); }
|
||||
if (!isset($data['description'])) { $response->error('Description is required', 400); }
|
||||
// Update the department
|
||||
(new departments_o())->edit($data['id'], $data['name'], $data['description']);
|
||||
// Log the incident
|
||||
(new logs_o())->add('departments', $data['id'], 1, $user->id, 'EDIT_DEPARTMENT', 'Successfully updated a department ' . $data['name']);
|
||||
// Return a success message
|
||||
$response->success(['message' => 'Department updated successfully']);
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('departments', 'global', 1, 0, 'EDIT_DEPARTMENT', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
<?php
|
||||
|
||||
namespace routes;
|
||||
|
||||
use classes\authentication;
|
||||
use classes\response;
|
||||
use classes\router;
|
||||
use economic_invoice_draft_mo;
|
||||
use objects\departments_o;
|
||||
use objects\economic_module_orders;
|
||||
use objects\logs_o;
|
||||
use objects\orders_o;
|
||||
use objects\tokens_o;
|
||||
use traits\route_t;
|
||||
|
||||
class economicInvoiceRoute
|
||||
{
|
||||
use route_t;
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
global /** @var response $response */
|
||||
/** @var router $router */
|
||||
$router, $response;
|
||||
|
||||
$this->post('/economic/invoice/draft/export', function () {
|
||||
global $response;
|
||||
$this->requirePermission('economic_invoice_draft_export');
|
||||
$user = (new authentication())->get_user();
|
||||
if ($user) {
|
||||
$order_id = $response->getRequestParameter('order_id');
|
||||
if (!isset($order_id)) {
|
||||
$response->error('Order ID is required', 400);
|
||||
}
|
||||
$order = (new orders_o())->getOrderById($order_id);
|
||||
// Check if the order exists
|
||||
if (!$order->exists()) {
|
||||
$response->error('Order not found', 404);
|
||||
}
|
||||
// Get the order items
|
||||
$order_items = (new orders_o())->getOrderItems($order_id);
|
||||
// Get the customer
|
||||
$customer = (new orders_o())->getCustomerByOrderId($order_id);
|
||||
// Check if the customer exists
|
||||
if (!$customer->exists()) {
|
||||
$response->error('Customer not found', 404);
|
||||
}
|
||||
// Get the customer economic number
|
||||
$customer_economic = $customer->getCustomerEcocomicData()->economic_customer;
|
||||
$economic_invoice_draft = (new economic_invoice_draft_mo());
|
||||
// Set the customer number
|
||||
$economic_invoice_draft->setCustomerNumber((int)$customer_economic->customer_number);
|
||||
// Set the recipient
|
||||
$economic_invoice_draft->setRecipient(
|
||||
$customer_economic->name ?? 'Ukendt',
|
||||
$customer_economic->address ?? 'Ukendt',
|
||||
$customer_economic->zip ?? 'Ukendt',
|
||||
$customer_economic->city ?? 'Ukendt'
|
||||
);
|
||||
// Make sure there are order items
|
||||
if (count($order_items) === 0) {
|
||||
$response->error('No order items found', 404);
|
||||
}
|
||||
// Get the department
|
||||
$department = (new departments_o())->getDepartmentById($order->department_id->value());
|
||||
// Add the department, date, reference
|
||||
$economic_invoice_draft->addLineTEXT('Afdeling: ' . $department['name']);
|
||||
$economic_invoice_draft->addLineTEXT('Dato: ' . $order->created_at->value());
|
||||
$economic_invoice_draft->addLineTEXT('Reference: ' . $order->reference->value());
|
||||
// Add the lines to the invoice
|
||||
foreach ($order_items as $order_item) {
|
||||
// If the customer requires any prefix or suffix to the product name, add it here
|
||||
if ($customer->doesUserHaveAttribute('requiresRegistrationNumbersInvoice')) {
|
||||
$order_item['product']['name'] = $order->reg_1->value() . ' ' . $order_item['product']['name'];
|
||||
}
|
||||
$economic_invoice_draft->addLine((string)$order_item['product']['economic_product_id'], (string)$order_item['product']['name'], 1, (int)$order_item['price'], 0);
|
||||
}
|
||||
// Create the invoice draft
|
||||
$result = $economic_invoice_draft->createInvoiceDraftExample();
|
||||
// Check if the invoice draft was created
|
||||
if (!isset($result->draftInvoiceNumber)) {
|
||||
// Log the error
|
||||
(new logs_o())->add('economic_invoice_draft', 'global', 3, $user->id, 'ECONOMIC_INVOICE_DRAFT_EXPORT', 'Failed to create economic invoice draft');
|
||||
// Check if we can get the errors from the response
|
||||
if (isset($result->errors)) {
|
||||
$response->add_meta('economic_errors', $result->errors);
|
||||
}
|
||||
// Try to parse the error message
|
||||
$response->error($result->message ?? 'Failed to create economic invoice draft', 500);
|
||||
}
|
||||
// Add the economic invoice draft to the order
|
||||
$economic_module_orders = (new economic_module_orders())->getByOrderId($order_id);
|
||||
// Remove the existing invoice draft (if any)
|
||||
if ($economic_module_orders->economic_invoice_draft_id->value() > 0) {
|
||||
$economic_invoice_draft->deleteInvoiceDraft($economic_module_orders->economic_invoice_draft_id->value());
|
||||
}
|
||||
$economic_module_orders->economic_invoice_draft_id->set($result->draftInvoiceNumber);
|
||||
// Return the response
|
||||
(new logs_o())->add('economic_invoice_draft', 'global', 1, $user->id, 'ECONOMIC_INVOICE_DRAFT_EXPORT', 'Successfully exported an economic invoice draft');
|
||||
$response->success($economic_module_orders->getArray());
|
||||
} else {
|
||||
(new logs_o())->add('economic_invoice_draft', 'global', 1, 0, 'ECONOMIC_INVOICE_DRAFT_EXPORT', 'No user found, or invalid session');
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
|
||||
$this->delete('/economic/invoice/draft/delete', function () {
|
||||
|
||||
global /** @var response $response */
|
||||
$response;
|
||||
$this->requirePermission('economic_invoice_draft_delete');
|
||||
$user = (new authentication())->get_user();
|
||||
if ($user) {
|
||||
$order_id = $response->getRequestParameter('order_id');
|
||||
if (!isset($order_id)) {
|
||||
$response->error('Order ID is required', 400);
|
||||
}
|
||||
$order = (new orders_o())->getOrderById($order_id);
|
||||
// Check if the order exists
|
||||
if (!$order->exists()) {
|
||||
$response->error('Order not found', 404);
|
||||
}
|
||||
// Make sure the order has an economic invoice draft
|
||||
$economic_module_orders = (new economic_module_orders())->getByOrderId($order_id);
|
||||
if ($economic_module_orders->economic_invoice_draft_id->value() === 0) {
|
||||
$response->error('No economic invoice draft found', 404);
|
||||
}
|
||||
$economic_invoice_draft = (new economic_invoice_draft_mo());
|
||||
// Get the invoice draft number
|
||||
$invoiceDraftId = $economic_module_orders->economic_invoice_draft_id->value();
|
||||
// Delete the invoice draft
|
||||
$economic_invoice_draft->deleteInvoiceDraft($invoiceDraftId);
|
||||
// Remove the economic invoice draft from the order
|
||||
$economic_module_orders->economic_invoice_draft_id->set(null);
|
||||
// Return the response
|
||||
(new logs_o())->add('economic_invoice_draft', 'global', 1, $user->id, 'ECONOMIC_INVOICE_DRAFT_DELETE', 'Successfully deleted an economic invoice draft');
|
||||
$response->success($economic_module_orders->getArray());
|
||||
} else {
|
||||
(new logs_o())->add('economic_invoice_draft', 'global', 1, 0, 'ECONOMIC_INVOICE_DRAFT_DELETE', 'No user found, or invalid session');
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
|
||||
$this->post('/economic/invoice/export', function () {
|
||||
global $response;
|
||||
$this->requirePermission('economic_invoice_export');
|
||||
$user = (new authentication())->get_user();
|
||||
if ($user) {
|
||||
$order_id = $response->getRequestParameter('order_id');
|
||||
if (!isset($order_id)) {
|
||||
$response->error('Order ID is required', 400);
|
||||
}
|
||||
$order = (new orders_o())->getOrderById($order_id);
|
||||
// Check if the order exists
|
||||
if (!$order->exists()) {
|
||||
$response->error('Order not found', 404);
|
||||
}
|
||||
// Get the customer
|
||||
$customer = (new orders_o())->getCustomerByOrderId($order_id);
|
||||
// Check if the customer exists
|
||||
if (!$customer->exists()) {
|
||||
$response->error('Customer not found', 404);
|
||||
}
|
||||
// Make sure the order has an economic invoice draft
|
||||
$economic_module_orders = (new economic_module_orders())->getByOrderId($order_id);
|
||||
if ($economic_module_orders->economic_invoice_draft_id->value() === 0) {
|
||||
$response->error('No economic invoice draft found', 404);
|
||||
}
|
||||
$economic_invoice_draft = (new economic_invoice_draft_mo());
|
||||
// Get the invoice draft number
|
||||
$invoiceDraftId = $economic_module_orders->economic_invoice_draft_id->value();
|
||||
// Make sure there's not already an invoice created
|
||||
$invoiceId = $economic_module_orders->economic_invoice_id->value();
|
||||
if ($invoiceId > 0) {
|
||||
$response->error('An invoice has already been created, invoice ID: ' . $invoiceId, 400);
|
||||
}
|
||||
// Publish the invoice draft
|
||||
$result = $economic_invoice_draft->publishInvoiceDraft((int)$invoiceDraftId);
|
||||
// Check if the invoice was created
|
||||
if (!isset($result->bookedInvoiceNumber)) {
|
||||
// Log the error
|
||||
(new logs_o())->add('economic_invoice', 'global', 3, $user->id, 'ECONOMIC_INVOICE_EXPORT', 'Failed to create economic invoice from draft: ' . $invoiceDraftId);
|
||||
// Check if we can get the errors from the response
|
||||
if (isset($result->errors)) {
|
||||
$response->add_meta('economic_errors', $result->errors);
|
||||
}
|
||||
// Try to parse the error message
|
||||
$response->error($result->message ?? 'Failed to create economic invoice', 500);
|
||||
}
|
||||
// Add the economic invoice to the order
|
||||
$economic_module_orders = (new economic_module_orders())->getByOrderId($order_id);
|
||||
$economic_module_orders->economic_invoice_id->set($result->bookedInvoiceNumber);
|
||||
// Return the response
|
||||
(new logs_o())->add('economic_invoice', 'global', 1, $user->id, 'ECONOMIC_INVOICE_EXPORT', 'Successfully exported an economic invoice');
|
||||
$response->success($economic_module_orders->getArray());
|
||||
} else {
|
||||
(new logs_o())->add('economic_invoice', 'global', 1, 0, 'ECONOMIC_INVOICE_EXPORT', 'No user found, or invalid session');
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace routes;
|
||||
|
||||
use traits\route_t;
|
||||
|
||||
class exampleRoute
|
||||
{
|
||||
use route_t;
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$this->get('/example', function () {
|
||||
global $response;
|
||||
$response->success(['message' => 'Hello World!']);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace routes;
|
||||
|
||||
use classes\authentication;
|
||||
use objects\logs_o;
|
||||
use objects\tokens_o;
|
||||
use objects\users_o;
|
||||
use traits\route_t;
|
||||
|
||||
class intimidateRoute
|
||||
{
|
||||
use route_t;
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$this->post('/su/intimidate', function () {
|
||||
// Get the post data
|
||||
global $response;
|
||||
// Make sure the user has the SUPERUSER_INTIMIDATE permission
|
||||
if (!$this->requirePermission('SUPERUSER_INTIMIDATE')) {
|
||||
$response->error('Permission denied', 403);
|
||||
}
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Get the post data
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
// Check if the customer number, and password are set
|
||||
if (!isset($data['user_id'])) {
|
||||
$response->error('User id is required', 400);
|
||||
}
|
||||
// Get the user object
|
||||
$intimidated_user = (new users_o())->getUserById($data['user_id']);
|
||||
// Log the incident
|
||||
(new logs_o())->add('auth', 'global', 1, $user->id, 'AUTH_SUCCESS_INTIMIDATE', 'Created intimidate token for customer: ' . $data['user_id']);
|
||||
// If the credentials are valid, create a token
|
||||
$token = (new authentication())->create_token($intimidated_user->customer_number->value());
|
||||
// Return the token
|
||||
$response->success(['token' => $token]);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace routes;
|
||||
|
||||
use traits\route_t;
|
||||
|
||||
class optionsRoute
|
||||
{
|
||||
use route_t;
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
// When the OPTIONS method is requested, accept all using regex
|
||||
$this->options('/.*', function () {
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
|
||||
header('Access-Control-Allow-Headers: *');
|
||||
header('Content-Type: application/json');
|
||||
http_response_code(200);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace routes;
|
||||
|
||||
use classes\authentication;
|
||||
use classes\response;
|
||||
use objects\logs_o;
|
||||
use objects\order_items_o;
|
||||
use objects\orders_o;
|
||||
use traits\route_t;
|
||||
|
||||
class orderItemsRoute
|
||||
{
|
||||
use route_t;
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$this->post('/order/items', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('add_order_items');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Check if the required fields are set
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
if (!isset($data['order_id'])) { $response->error('Order ID is required', 400); }
|
||||
if (!isset($data['product_id'])) { $response->error('Product ID is required', 400); }
|
||||
if (!isset($data['quantity'])) { $response->error('Quantity is required', 400); }
|
||||
// Make sure we don't add more than 200 items at a time
|
||||
if ($data['quantity'] > 199) { $response->error('Quantity is too high, please add less than 200 items at a time', 400); }
|
||||
// Add the order item to the order This is done individually, to make the notes to the individual order items possible
|
||||
for ($i = 0; $i < $data['quantity']; $i++) {
|
||||
(new order_items_o())->addItemToOrder($data['order_id'], $data['product_id'], $user->id);
|
||||
}
|
||||
// Return the list of departments
|
||||
$response->success(
|
||||
['message' => 'Order items added']
|
||||
);
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('departments', 'global', 1, 0, 'ADD_ORDER_ITEMS', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
|
||||
$this->get('/order/items', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('list_order_items');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Get the post data
|
||||
$data = $_GET;
|
||||
// Check if the required fields are set
|
||||
if (!(int)$data['order_id']) { $response->error('Order ID is required', 400); }
|
||||
// Return the list of departments
|
||||
$response->success(
|
||||
(new orders_o())->getOrderItems($data['order_id'])
|
||||
);
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('departments', 'global', 1, 0, 'LIST_ORDER_ITEMS', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
|
||||
$this->delete('/order/items', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('delete_order_items');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Get the query data
|
||||
$data = $_GET;
|
||||
// Check if the required fields are set
|
||||
if (!isset($data['id'])) { $response->error('Order Item ID is required', 400); }
|
||||
// Delete the order item
|
||||
(new order_items_o())->removeOrderItem($data['id']);
|
||||
// Return the list of departments
|
||||
$response->success(
|
||||
['message' => 'Order item deleted']
|
||||
);
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('departments', 'global', 1, 0, 'DELETE_ORDER_ITEMS', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace routes;
|
||||
|
||||
use classes\authentication;
|
||||
use classes\response;
|
||||
use objects\departments_o;
|
||||
use objects\logs_o;
|
||||
use objects\orders_o;
|
||||
use objects\users_o;
|
||||
use traits\route_t;
|
||||
|
||||
class orderRoute
|
||||
{
|
||||
use route_t;
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$this->get('/order', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('fetch_order');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Make sure the order id is set
|
||||
if (!(int)$this->fromRequest('id')) { $response->error('Order id is required', 400); }
|
||||
// Make sure the order exists
|
||||
if (!(new orders_o())->getOrderById($this->fromRequest('id'))->exists()) { $response->error('Order not found', 400); }
|
||||
// Log the incident
|
||||
(new logs_o())->add('orders', 'global', 1, $user->id, 'FETCH_ORDER', 'Successfully fetched order');
|
||||
// Return the list of departments
|
||||
$response->success(
|
||||
(new orders_o())->getOrderById($this->fromRequest('id'))->includeIncludes()->asArray()
|
||||
);
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('orders', 'global', 1, 0, 'FETCH_ORDER', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
|
||||
namespace routes;
|
||||
|
||||
use classes\authentication;
|
||||
use classes\response;
|
||||
use objects\departments_o;
|
||||
use objects\logs_o;
|
||||
use objects\orders_o;
|
||||
use objects\users_o;
|
||||
use traits\route_t;
|
||||
|
||||
class ordersRoute
|
||||
{
|
||||
use route_t;
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$this->get('/orders', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('list_orders');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Log the incident
|
||||
(new logs_o())->add('orders', 'global', 1, $user->id, 'LIST_ORDERS', 'Successfully listed orders');
|
||||
// Return the list of departments
|
||||
$response->success(
|
||||
(new orders_o())->listObjectsWithPaginationIfSet()
|
||||
);
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('orders', 'global', 1, 0, 'LIST_ORDERS', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
|
||||
$this->post('/orders', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('add_order');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Get the post data
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
// Check if the required fields are set
|
||||
$data = $this->getData($data, $response);
|
||||
// Validate the department
|
||||
if (!(new departments_o())->getDepartmentById((int)$data['department_id'])) {
|
||||
$response->error('Department not found', 400);
|
||||
}
|
||||
// Make sure the customer number set is valid
|
||||
if (!(new users_o())->getCustomerByIdOrCustomerNumber((int)$data['customer_id'])->exists() || empty($data['customer_id'])) {
|
||||
$response->error('Customer not found or invalid', 400);
|
||||
}
|
||||
// Check if the user requires a reference
|
||||
if ((new users_o())->getCustomerByIdOrCustomerNumber((int)$data['customer_id'])->requiresReference() && empty($data['reference'])) {
|
||||
$response->error('Reference is required by the customer', 400);
|
||||
}
|
||||
// Get the registration number
|
||||
$reg_1 = $data['reg_1'];
|
||||
// Get the registration numbers (If they are set, they 2-3 are optional)
|
||||
$reg_2 = $data['reg_2'] ?? '';
|
||||
$reg_3 = $data['reg_3'] ?? '';
|
||||
// Create the order
|
||||
$order = (new orders_o())->add((int)$data['customer_id'], $user->id, $data['reference'], $data['notes'], (int)$data['department_id'], (string)$reg_1, (string)$reg_2, (string)$reg_3);
|
||||
// Log the incident
|
||||
(new logs_o())->add('orders', $data['department_id'], 1, $user->id, 'ADD_ORDER', 'Successfully added an order (ID: ' . $data['department_id'] . ')');
|
||||
// Return a success message, containing the orders array
|
||||
$response->success($order->asArray());
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('orders', 'global', 1, 0, 'ADD_ORDER', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
|
||||
$this->put('/orders', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('edit_order');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Get the post data
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
// Check if the required fields are set
|
||||
if (!isset($data['id'])) { $response->error('ID is required', 400); }
|
||||
$data = $this->getData($data, $response);
|
||||
// Update the order
|
||||
(new orders_o())->edit((int)$data['id'], $user->id, (int)$data['customer_id'], $data['reference'], $data['notes'], (int)$data['department_id']);
|
||||
// Log the incident
|
||||
(new logs_o())->add('orders', $data['id'], 1, $user->id, 'EDIT_ORDER', 'Successfully updated an order (ID: ' . $data['id'] . ')');
|
||||
// Return a success message
|
||||
$response->success(['message' => 'Order updated successfully']);
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('orders', 'global', 1, 0, 'EDIT_ORDER', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $data
|
||||
* @param response $response
|
||||
* @return mixed
|
||||
*/
|
||||
private function getData(mixed $data, response $response): mixed
|
||||
{
|
||||
if (!isset($data['customer_id'])) {
|
||||
$response->error('Customer ID is required', 400);
|
||||
}
|
||||
if (!isset($data['department_id'])) {
|
||||
$response->error('Department ID is required', 400);
|
||||
}
|
||||
if (!isset($data['reference'])) {
|
||||
$response->error('Reference is required', 400);
|
||||
}
|
||||
if (!isset($data['notes'])) {
|
||||
$response->error('Notes is required', 400);
|
||||
}
|
||||
if (!isset($data['reg_1'])) {
|
||||
$response->error('Registration number 1 is required', 400);
|
||||
}
|
||||
if (strlen($data['reg_1']) < 4) {
|
||||
$response->error('Registration number 1 must be at least 4 characters', 400);
|
||||
}
|
||||
// Optional fields are not checked here, as they are optional and can be empty
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
namespace routes;
|
||||
|
||||
use classes\authentication;
|
||||
use objects\logs_o;
|
||||
use objects\plate_scanners_o;
|
||||
use objects\users_o;
|
||||
use traits\route_t;
|
||||
|
||||
class plateScannersRoute
|
||||
{
|
||||
use route_t;
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$this->get('/numberplatescanners', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('list_number_plate_scanners');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Log the incident
|
||||
(new logs_o())->add('numberplatescanners', 'global', 1, $user->id, 'LIST_NUMBER_PLATE_SCANNERS', 'Successfully listed number plate scanners');
|
||||
// Return the list of plate scanners
|
||||
$response->success(
|
||||
(new plate_scanners_o())->listObjects()
|
||||
);
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('numberplatescanners', 'global', 1, 0, 'LIST_NUMBER_PLATE_SCANNERS', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
|
||||
$this->post('/numberplatescanners', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('add_number_plate_scanner');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Get the post data
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
// Check if the required fields are set
|
||||
if (!isset($data['department_id'])) { $response->error('Department ID is required', 400); }
|
||||
if (!isset($data['name'])) { $response->error('Name is required', 400); }
|
||||
if (!isset($data['notes'])) { $response->error('Notes is required', 400); }
|
||||
// Add the number plate scanner
|
||||
(new plate_scanners_o())->add($data['department_id'], $data['name'], $data['notes']);
|
||||
// Log the incident
|
||||
(new logs_o())->add('numberplatescanners', 'global', 1, $user->id, 'ADD_NUMBER_PLATE_SCANNER', 'Successfully added a number plate scanner');
|
||||
// Return a success message
|
||||
$response->success(['message' => 'Number plate scanner added']);
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('numberplatescanners', 'global', 1, 0, 'ADD_NUMBER_PLATE_SCANNER', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
|
||||
$this->put('/numberplatescanners', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('edit_number_plate_scanner');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Get the post data
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
// Check if the required fields are set
|
||||
if (!isset($data['id'])) { $response->error('ID is required', 400); }
|
||||
if (!isset($data['department_id'])) { $response->error('Department ID is required', 400); }
|
||||
if (!isset($data['name'])) { $response->error('Name is required', 400); }
|
||||
if (!isset($data['notes'])) { $response->error('Notes is required', 400); }
|
||||
// Edit the number plate scanner
|
||||
(new plate_scanners_o())->edit($data['id'], $data['department_id'], $data['name'], $data['notes']);
|
||||
// Log the incident
|
||||
(new logs_o())->add('numberplatescanners', 'global', 1, $user->id, 'EDIT_NUMBER_PLATE_SCANNER', 'Successfully edited a number plate scanner');
|
||||
// Return a success message
|
||||
$response->success(['message' => 'Number plate scanner edited']);
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('numberplatescanners', 'global', 1, 0, 'EDIT_NUMBER_PLATE_SCANNER', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace routes;
|
||||
|
||||
use classes\authentication;
|
||||
use objects\logs_o;
|
||||
use objects\plate_scanners_o;
|
||||
use objects\plate_scans_o;
|
||||
use traits\route_t;
|
||||
|
||||
class plateScansRoute
|
||||
{
|
||||
use route_t;
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
|
||||
$this->post('/numberplatescans', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePlateScannerAuth();
|
||||
// Get the plate scanner object
|
||||
$plate_scanner = (new authentication())->get_plate_scanner();
|
||||
// Get the post data
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
// Check if the required fields are set
|
||||
if (!isset($data['plate'])) {
|
||||
$response->error('Missing required body parameter plate', 400);
|
||||
}
|
||||
// Add the number plate scanner
|
||||
(new plate_scans_o())->add($plate_scanner->id, $data['plate']);
|
||||
// Log the incident
|
||||
(new logs_o())->add('numberplatescans', $plate_scanner->department_id->value(), 1, 0, 'ADD_NUMBER_PLATE_SCANS', 'Successfully added a number plate scan' . $data['plate']);
|
||||
// Return a success message
|
||||
$response->success(['message' => 'License plate scan recorded.', 'plate' => $data['plate'], 'scanner' => $plate_scanner->name->value()], 201);
|
||||
});
|
||||
|
||||
$this->post('/numberplatescans/department', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('list_number_plate_scans_department');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Check if a department is set in the body
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
if (!isset($data['department_id'])) {
|
||||
$response->error('Missing required body parameter department', 400);
|
||||
}
|
||||
$this->requirePermission('list_number_plate_scans_department_' . $data['department_id']);
|
||||
// Check if the pagination parameters are set
|
||||
if (!isset($data['page'])) {
|
||||
$response->error('Missing required body parameter page', 400);
|
||||
}
|
||||
if (!isset($data['limit'])) {
|
||||
$response->error('Missing required body parameter limit', 400);
|
||||
}
|
||||
// Get the number plate scans
|
||||
$number_plate_scans = (new plate_scans_o())->getPlateScansByDepartment((int)$data['department_id'], (int)$data['page'], (int)$data['limit']);
|
||||
// Log the incident
|
||||
(new logs_o())->add('numberplatescans', $data['department_id'], 1, $user->id, 'LIST_NUMBER_PLATE_SCANS_DEPARTMENT', 'Successfully listed number plate scans for department: ' . $data['department_id']);
|
||||
// Return the number plate scans
|
||||
$response->success($number_plate_scans);
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('numberplatescans', 'global', 1, 0, 'LIST_NUMBER_PLATE_SCANS_DEPARTMENT', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
namespace routes;
|
||||
|
||||
use classes\authentication;
|
||||
use objects\logs_o;
|
||||
use objects\products_o;
|
||||
use traits\route_t;
|
||||
|
||||
class productsRoute
|
||||
{
|
||||
use route_t;
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$this->get('/products', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('list_products');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Check if the category is set in the request
|
||||
$data = $_GET ?? [];
|
||||
if (isset($data['category'])) {
|
||||
// Log the incident
|
||||
(new logs_o())->add('products', 'global', 1, $user->id, 'LIST_PRODUCTS', 'Successfully listed products in category ' . $data['category']);
|
||||
// Return the list of departments
|
||||
$response->success(
|
||||
(new products_o())->listObjectsByCategory($data['category'])
|
||||
);
|
||||
}
|
||||
// Log the incident
|
||||
(new logs_o())->add('products', 'global', 1, $user->id, 'LIST_PRODUCTS', 'Successfully listed products');
|
||||
// Return the list of departments
|
||||
$response->success(
|
||||
(new products_o())->listObjectsWithPaginationIfSet()
|
||||
);
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('products', 'global', 1, 0, 'LIST_PRODUCTS', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
|
||||
$this->post('/products', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('add_product');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Get the post data
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
// Check if the required fields are set
|
||||
if (!isset($data['name'])) { $response->error('Name is required', 400); }
|
||||
if (!isset($data['description'])) { $response->error('Description is required', 400); }
|
||||
if (!isset($data['price'])) { $response->error('Price is required', 400); }
|
||||
if (!isset($data['category'])) { $response->error('Category is required', 400); }
|
||||
if (!isset($data['piktogram'])) { $response->error('Piktogram is required', 400); }
|
||||
if (!isset($data['economicProductId'])) { $response->error('Economic product ID is required', 400); }
|
||||
// Add the product
|
||||
(new products_o())->add($data['name'], $data['description'], $data['price'], $data['category'], $data['piktogram'], $data['economicProductId']);
|
||||
// Log the incident
|
||||
(new logs_o())->add('products', 'global', 1, $user->id, 'ADD_PRODUCT', 'Product name: ' . $data['name']);
|
||||
// Return a success message
|
||||
$response->success(['message' => 'Product added successfully']);
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('products', 'global', 1, 0, 'ADD_PRODUCT', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
|
||||
$this->put('/products', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('edit_product');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Get the post data
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
// Check if the required fields are set
|
||||
if (!isset($data['id'])) { $response->error('ID is required', 400); }
|
||||
if (!isset($data['name'])) { $response->error('Name is required', 400); }
|
||||
if (!isset($data['description'])) { $response->error('Description is required', 400); }
|
||||
if (!isset($data['price'])) { $response->error('Price is required', 400); }
|
||||
if (!isset($data['category'])) { $response->error('Category is required', 400); }
|
||||
if (!isset($data['piktogram'])) { $response->error('Piktogram is required', 400); }
|
||||
if (!isset($data['economicProductId'])) { $response->error('Economic product ID is required', 400); }
|
||||
// Edit the product
|
||||
(new products_o())->edit($data['id'], $data['name'], $data['description'], $data['price'], $data['category'], $data['piktogram'], $data['economicProductId']);
|
||||
// Log the incident
|
||||
(new logs_o())->add('products', 'global', 1, $user->id, 'EDIT_PRODUCT', 'Product id: ' . $data['id']);
|
||||
// Return a success message
|
||||
$response->success(['message' => 'Product edited successfully']);
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('products', 'global', 1, 0, 'EDIT_PRODUCT', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace routes;
|
||||
|
||||
use classes\authentication;
|
||||
use objects\logs_o;
|
||||
use traits\route_t;
|
||||
|
||||
class sessionRoute
|
||||
{
|
||||
use route_t;
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$this->get('/auth/session', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('fetch_session');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Log the incident
|
||||
(new logs_o())->add('auth', 'global', 1, $user->id, 'FETCH_SESSION', 'User id: ' . $user->id);
|
||||
// Return the user object
|
||||
$response->success($user->getArray());
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('auth', 'global', 1, 0, 'FETCH_SESSION_FAILURE', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace routes;
|
||||
|
||||
use classes\authentication;
|
||||
use objects\customer_vehicles_o;
|
||||
use objects\logs_o;
|
||||
use objects\orders_o;
|
||||
use traits\route_t;
|
||||
|
||||
class userOrdersRoute
|
||||
{
|
||||
use route_t;
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$this->get('/user/orders', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('list_own_orders');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Log the incident
|
||||
(new logs_o())->add('orders', 'global', 1, $user->id, 'LIST_OWN_ORDERS', 'Successfully listed own orders');
|
||||
// Return the list of the user's orders
|
||||
$response->success(
|
||||
(new orders_o())->getCustomerOrdersPaginated(
|
||||
$user->customer_number->value(),
|
||||
($this->fromRequest('page') ?? 1),
|
||||
($this->fromRequest('limit') ?? 10),
|
||||
($this->fromRequest('order') ?? 'DESC')
|
||||
)
|
||||
);
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('orders', 'global', 1, 0, 'LIST_OWN_ORDERS', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
namespace routes;
|
||||
|
||||
use classes\authentication;
|
||||
use objects\logs_o;
|
||||
use objects\users_o;
|
||||
use traits\route_t;
|
||||
|
||||
class usersRoute
|
||||
{
|
||||
use route_t;
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$this->get('/users', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('list_users');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Log the incident
|
||||
(new logs_o())->add('users', 'global', 1, $user->id, 'LIST_USERS', 'Successfully listed users');
|
||||
// Return the list of users
|
||||
$response->success(
|
||||
(new users_o())->listObjects()
|
||||
);
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('users', 'global', 1, 0, 'LIST_USERS', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
|
||||
$this->get('/users/customer', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('get_user_from_customer_number');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Check if the customer number is valid
|
||||
if (!(new users_o())->automaticGetTargetUserFromRequest()->exists()) {
|
||||
// Log the incident
|
||||
(new logs_o())->add('users', 'global', 1, $user->id, 'GET_USER_FROM_CUSTOMER_NUMBER', 'Customer not found, not imported');
|
||||
$response->error('Customer not found', 400);
|
||||
}
|
||||
// Check
|
||||
// Log the incident
|
||||
(new logs_o())->add('users', 'global', 1, $user->id, 'GET_USER_FROM_CUSTOMER_NUMBER', 'Successfully retrieved user from customer number');
|
||||
// Return the list of users
|
||||
$response->success(
|
||||
(new users_o())->automaticGetTargetUserFromRequest()->getCustomerEcocomicData()->asArray()
|
||||
);
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('users', 'global', 1, 0, 'GET_USER_FROM_CUSTOMER_NUMBER', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
|
||||
$this->post('/users', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('add_user');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Get the post data
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
// Check if the required fields are set
|
||||
if (!isset($data['customer_number'])) { $response->error('Customer number is required', 400); }
|
||||
if (!isset($data['password'])) { $response->error('Password is required', 400); }
|
||||
// Add the user
|
||||
(new users_o())->add($data['customer_number'], $data['password']);
|
||||
// Log the incident
|
||||
(new logs_o())->add('users', 'global', 1, $user->id, 'ADD_USER', 'Successfully added a user');
|
||||
// Return a success message
|
||||
$response->success(['message' => 'User added']);
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('users', 'global', 1, 0, 'ADD_USER', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
|
||||
$this->put('/users', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('edit_user');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Get the post data
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
// Check if the required fields are set
|
||||
if (!isset($data['id'])) { $response->error('ID is required', 400); }
|
||||
if (!isset($data['customer_number'])) { $response->error('Customer number is required', 400); }
|
||||
// Check if a new role is set, if not, set it to null to prevent it from being updated
|
||||
if (!isset($data['role']) || $data['role'] === 'null' || $data['role'] === '') { $data['role'] = null; }
|
||||
// If the role is set, require the edit_user_role permission
|
||||
if ($data['role']) {
|
||||
$this->requirePermission('edit_user_role');
|
||||
}
|
||||
// Check if a new password is set, if not, set it to null to prevent it from being updated
|
||||
if (!isset($data['password']) || $data['password'] === 'null' || $data['password'] === '') { $data['password'] = null; }
|
||||
// If the password is set, require the edit_user_password permission
|
||||
if ($data['password']) {
|
||||
$this->requirePermission('edit_user_password');
|
||||
}
|
||||
// Edit the user
|
||||
(new users_o())->edit((int)$data['id'], (string)$data['customer_number'], $data['role'], $data['password']);
|
||||
// Log the incident
|
||||
(new logs_o())->add('users', 'global', 1, $user->id, 'EDIT_USER', 'Successfully edited a user with ID: ' . $data['id']);
|
||||
// Return a success message
|
||||
$response->success(['message' => 'User edited']);
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('users', 'global', 1, 0, 'EDIT_USER', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
namespace routes;
|
||||
|
||||
use classes\authentication;
|
||||
use objects\customer_vehicles_o;
|
||||
use objects\logs_o;
|
||||
use objects\users_o;
|
||||
use traits\route_t;
|
||||
|
||||
class vehiclesRoute
|
||||
{
|
||||
use route_t;
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$this->get('/user/vehicles', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('list_own_vehicles');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Log the incident
|
||||
(new logs_o())->add('vehicles', 'global', 1, $user->id, 'LIST_OWN_VEHICLES', 'Successfully listed own vehicles');
|
||||
// Return the list of the user's vehicles
|
||||
$response->success(
|
||||
(new customer_vehicles_o())->getCustomerVehiclesPaginated(
|
||||
$user->id,
|
||||
($this->fromRequest('page') ?? 1),
|
||||
($this->fromRequest('limit') ?? 10)
|
||||
)
|
||||
);
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('vehicles', 'global', 1, 0, 'LIST_OWN_VEHICLES', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
});
|
||||
|
||||
$this->post('/user/vehicles', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('add_vehicle');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Get the post data
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
// Check if the required fields are set
|
||||
$data = $this->getData($data, $response);
|
||||
// Make sure the registration number is valid
|
||||
$this->validateRegistrationNumber($data['reg'], $response);
|
||||
// Make sure the type is valid
|
||||
$this->validateType($data['type'], $response);
|
||||
// Make sure the notes are valid
|
||||
$this->validateNotes($data['notes'], $response);
|
||||
// Create a new vehicle
|
||||
$vehicle = (new customer_vehicles_o())->add(
|
||||
$user->id,
|
||||
$data['type'],
|
||||
$data['reg'],
|
||||
$data['notes']
|
||||
);
|
||||
// Log the incident
|
||||
(new logs_o())->add('vehicles', 'global', 1, $user->id, 'ADD_VEHICLE', 'Successfully added vehicle');
|
||||
// Return the new vehicle
|
||||
$response->success($vehicle->getArrayByObjectProperties());
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('vehicles', 'global', 1, 0, 'ADD_VEHICLE', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 401);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private function getData(mixed $data, $response)
|
||||
{
|
||||
if (!isset($data['type'])) {
|
||||
$response->error('Type is required', 400);
|
||||
}
|
||||
if (!isset($data['reg'])) {
|
||||
$response->error('Registration number is required', 400);
|
||||
}
|
||||
if (!isset($data['notes'])) {
|
||||
$response->error('Notes is required', 400);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function validateRegistrationNumber(mixed $reg, $response): void
|
||||
{
|
||||
if (!preg_match('/^[A-Z0-9]{4,10}$/', $reg)) {
|
||||
$response->error('Invalid registration number, it must be 4-10 characters long, and only contain uppercase letters and numbers', 400);
|
||||
}
|
||||
}
|
||||
|
||||
private function validateType(mixed $type, $response): void
|
||||
{
|
||||
// Make sure the type is more than 2 characters
|
||||
if (strlen($type) < 2) {
|
||||
$response->error('Type is too short, it must be at least 2 characters', 400);
|
||||
}
|
||||
// Make sure the type is less than 50 characters
|
||||
if (strlen($type) > 50) {
|
||||
$response->error('Type is too long, it must be less than 50 characters', 400);
|
||||
}
|
||||
}
|
||||
|
||||
private function validateNotes(mixed $notes, $response): void
|
||||
{
|
||||
// If the notes are set, make sure they are less than 250 characters
|
||||
if (isset($notes) && strlen($notes) > 250) {
|
||||
$response->error('Notes are too long, they must be less than 250 characters', 400);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
<?php
|
||||
|
||||
namespace traits;
|
||||
|
||||
use classes\response;
|
||||
use Exception;
|
||||
|
||||
trait db_object_t
|
||||
{
|
||||
private string $table; // The table of the objects in the database (e.g. users)
|
||||
public int $id; // The id of the object in the database
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->structure();
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
// Return the object as a string
|
||||
return json_encode($this->getArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the table of the objects in the database
|
||||
* @param string $table The table of the objects in the database
|
||||
*/
|
||||
public function setTable(string $table): void
|
||||
{
|
||||
$this->table = $table;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Structure: Define the table and fields of the objects in the database
|
||||
*/
|
||||
public function structure(): void
|
||||
{
|
||||
// Define the table and fields of the objects in the database
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current object row as an array
|
||||
* @return array The current object row as an array
|
||||
* @throws Exception If object not found
|
||||
*/
|
||||
public function getArray(): array
|
||||
{
|
||||
// Get the object from the database
|
||||
global $db;
|
||||
// Check if the id is set, if not throw an exception
|
||||
if (!isset($this->id)) {
|
||||
throw new Exception('Object not found');
|
||||
}
|
||||
$id = $this->id;
|
||||
$sql = "SELECT * FROM $this->table WHERE id = $id";
|
||||
$result = $db->query($sql);
|
||||
return $db->fetch_assoc($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* List ALL objects in the table
|
||||
* @return array The list of objects in the table
|
||||
*/
|
||||
public function listObjects(): array
|
||||
{
|
||||
global $db;
|
||||
$sql = "SELECT * FROM $this->table";
|
||||
$result = $db->query($sql);
|
||||
return $db->fetch_all($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* List objects in the table with pagination
|
||||
* @param int $page The page number
|
||||
* @param int $limit The number of objects per page
|
||||
* @return array The list of objects in the table
|
||||
*/
|
||||
public function listObjectsWithPagination(int $page, int $limit, string $search = null, array $filters = null): array
|
||||
{
|
||||
global /** @var response $response */
|
||||
$db, $response;
|
||||
$offset = ($page - 1) * $limit;
|
||||
// Get all the fields of the table
|
||||
$sql = "SHOW COLUMNS FROM $this->table";
|
||||
$result = $db->query($sql);
|
||||
$fields = $db->fetch_all($result);
|
||||
$searchfields = [];
|
||||
foreach ($fields as $field) {
|
||||
$searchfields[] = $field['Field'];
|
||||
}
|
||||
// Search for any similarities to the search query (Not case sensitive)
|
||||
$searchQuery = '';
|
||||
if ($search) {
|
||||
$searchQuery = 'WHERE ';
|
||||
$search = strtolower($search);
|
||||
$searchQuery .= '(';
|
||||
foreach ($searchfields as $field) {
|
||||
$searchQuery .= "LOWER($field) LIKE '%$search%' OR ";
|
||||
}
|
||||
$searchQuery = substr($searchQuery, 0, -4);
|
||||
$searchQuery .= ')';
|
||||
}
|
||||
// Filter the objects
|
||||
if ($filters) {
|
||||
if ($searchQuery) {
|
||||
$searchQuery .= ' AND ';
|
||||
} else {
|
||||
$searchQuery = 'WHERE ';
|
||||
}
|
||||
foreach ($filters as $field => $value) {
|
||||
$searchQuery .= "$field = $value AND ";
|
||||
}
|
||||
$searchQuery = substr($searchQuery, 0, -5);
|
||||
}
|
||||
// Get the objects with pagination
|
||||
$sql = "SELECT * FROM $this->table $searchQuery LIMIT $limit OFFSET $offset";
|
||||
$result = $db->query($sql);
|
||||
$array = $db->fetch_all($result);
|
||||
$sql = "SELECT COUNT(*) AS count FROM $this->table $searchQuery";
|
||||
$result = $db->query($sql);
|
||||
$row = $db->fetch_assoc($result);
|
||||
$total = $row['count'];
|
||||
$response->paginate($page, $limit, $total, $search, $filters);
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* List objects with pagination (if set)
|
||||
* @return array The list of objects in the table
|
||||
*/
|
||||
public function listObjectsWithPaginationIfSet(): array
|
||||
{
|
||||
global $response;
|
||||
$page = ((int) $response->getRequestParameter('page')) ?? null; // Get the page number
|
||||
$limit = ((int) $response->getRequestParameter('limit')) ?? null; // Get the number of objects per page
|
||||
$search = $response->getRequestParameter('search') ?? null; // Get the search query
|
||||
$filters = $response->getRequestParameter('filters') ?? null; // Get the filters ( Eg. department_id:1,role_id:2 OR department_id:1 )
|
||||
// Make the filters an array
|
||||
if ($filters) {
|
||||
$filters = explode(',', $filters);
|
||||
$temp = [];
|
||||
foreach ($filters as $filter) {
|
||||
$filter = explode(':', $filter);
|
||||
$temp[$filter[0]] = $filter[1];
|
||||
}
|
||||
$filters = $temp;
|
||||
}
|
||||
if ($page && $limit) {
|
||||
return $this->listObjectsWithPagination($page, $limit, $search, $filters);
|
||||
}
|
||||
return $this->listObjects();
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this object exist in the database?
|
||||
* @return bool True if the object exists in the database, false otherwise
|
||||
*/
|
||||
public function exists(): bool
|
||||
{
|
||||
// Check if the id is set
|
||||
if (!isset($this->id)) {
|
||||
return false;
|
||||
}
|
||||
// Check if the object exists in the database
|
||||
global $db;
|
||||
$id = $this->id;
|
||||
$sql = "SELECT * FROM $this->table WHERE id = $id";
|
||||
$result = $db->query($sql);
|
||||
return $result->num_rows > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
|
||||
namespace traits;
|
||||
|
||||
use classes\authentication;
|
||||
use objects\logs_o;
|
||||
|
||||
trait route_t
|
||||
{
|
||||
private string $route;
|
||||
public function __construct()
|
||||
{
|
||||
$this->route = $_SERVER['REQUEST_URI'];
|
||||
}
|
||||
|
||||
private function registerRoute($route, $method, $callback): void
|
||||
{
|
||||
global $router;
|
||||
$router->add($route, $method, $callback);
|
||||
}
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
// Add the routes here
|
||||
}
|
||||
|
||||
/**
|
||||
* GET route
|
||||
* @param string $route Example: /home, /home/{id}
|
||||
*/
|
||||
public function get(string $route, callable $callback): void
|
||||
{
|
||||
$this->registerRoute($route, 'GET', $callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* POST route
|
||||
* @param string $route Example: /home, /home/{id}
|
||||
*/
|
||||
public function post(string $route, callable $callback): void
|
||||
{
|
||||
$this->registerRoute($route, 'POST', $callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* PUT route
|
||||
* @param string $route Example: /home, /home/{id}
|
||||
*/
|
||||
public function put(string $route, callable $callback): void
|
||||
{
|
||||
$this->registerRoute($route, 'PUT', $callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* DELETE route
|
||||
* @param string $route Example: /home, /home/{id}
|
||||
*/
|
||||
public function delete(string $route, callable $callback): void
|
||||
{
|
||||
$this->registerRoute($route, 'DELETE', $callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* OPTIONS route
|
||||
* @param string $route Example: /home, /home/{id}
|
||||
*/
|
||||
public function options(string $route, callable $callback): void
|
||||
{
|
||||
$this->registerRoute($route, 'OPTIONS', $callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Match route
|
||||
* @param string $route Example: /home, /home/{id}
|
||||
*/
|
||||
private function match_route(string $route): bool
|
||||
{
|
||||
// Check if route is the same, or if it matches the regex pattern
|
||||
return $route === $this->route || preg_match($route, $this->route);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parameter from the route URL by index
|
||||
* @param string $index
|
||||
* @return string|null
|
||||
*/
|
||||
public function fromRoute(string $index): ?string
|
||||
{
|
||||
$params = explode('/', $this->route);
|
||||
$index = array_search($index, $params);
|
||||
return $params[$index] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Require permission
|
||||
* @param string $permission
|
||||
* @return bool
|
||||
*/
|
||||
public function requirePermission(string $permission): bool
|
||||
{
|
||||
global $response;
|
||||
// Check if the users authorization token has the required permission
|
||||
try {
|
||||
$user = (new authentication())->get_user();
|
||||
// If there is no user, return an error
|
||||
if (!$user) {
|
||||
(new logs_o())->add('global', 'global', 1, 0, 'AUTHENTICATION_FAILED', 'Authentication failed. Invalid, or missing token');
|
||||
$response->error('Authentication failed. Invalid or missing token.', 401);
|
||||
}
|
||||
if (!$user->hasPermission($permission)) {
|
||||
(new logs_o())->add('global', 'global', 1, $user->id, 'PERMISSION_DENIED', 'Permission denied. Missing permission: ' . $permission);
|
||||
$response->error('Permission denied. Missing permission: ' . $permission .' for user: ' . $user->id . ' In group: ' . $user->group_id->value(), 403);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$response->error($e->getMessage(), 400);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Require plate scanner authentication
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
public function requirePlateScannerAuth(): bool
|
||||
{
|
||||
global $response;
|
||||
// Check if the plate scanner has a valid API key
|
||||
try {
|
||||
$plate_scanner = (new authentication())->get_plate_scanner();
|
||||
if (!$plate_scanner) {
|
||||
(new logs_o())->add('global', 'global', 1, 0, 'AUTHENTICATION_FAILED', 'Authentication failed. Invalid, or missing API key');
|
||||
$response->error('Authentication failed. Invalid or missing API key.', 401);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$response->error($e->getMessage(), 400);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parameter from the query string by name
|
||||
* @param string $name
|
||||
* @return string|null
|
||||
*/
|
||||
public function fromQuery(string $name): ?string
|
||||
{
|
||||
return (isset($_GET[$name])) ? $_GET[$name] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data from the request body or query string by name
|
||||
* @param string $name
|
||||
* @return string|null
|
||||
*/
|
||||
public function fromRequest(string $name): ?string
|
||||
{
|
||||
return (isset($_POST[$name])) ? $_POST[$name] : $this->fromQuery($name);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace traits;
|
||||
|
||||
trait session_t
|
||||
{
|
||||
private string $session; // The session of the user
|
||||
}
|
||||
Reference in New Issue
Block a user