Added the files from MVP

This commit is contained in:
Jepp9350
2024-12-16 08:54:03 +01:00
parent b831ad9332
commit 914f5ba1b0
56 changed files with 4697 additions and 0 deletions
+109
View File
@@ -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
View File
@@ -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;
}
}
+49
View File
@@ -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);
}
}
+58
View File
@@ -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);
}
}
+29
View File
@@ -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;
}
}
+8
View File
@@ -0,0 +1,8 @@
<?php
namespace classes;
class request
{
}
+133
View File
@@ -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);
}
}
+108
View File
@@ -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;
}
}
+10
View File
@@ -0,0 +1,10 @@
<?php
namespace classes;
use traits\session_t;
class session
{
use session_t;
}
+23
View File
@@ -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
];
}
+94
View File
@@ -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();
}
+11
View File
@@ -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;
}
+9
View File
@@ -0,0 +1,9 @@
<?php
namespace interfaces;
interface encrypt_i
{
public function encrypt(string $data): string;
public function decrypt(string $data): string;
}
+8
View File
@@ -0,0 +1,8 @@
<?php
namespace interfaces;
interface ratelimit_i
{
public function enforceIP(string $ip): bool;
}
+16
View File
@@ -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,
];
}
}
+67
View File
@@ -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');
}
}
+78
View File
@@ -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;
}
}
+93
View File
@@ -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);
}
}
+124
View File
@@ -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()
];
}
}
+73
View File
@@ -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);
}
}
+68
View File
@@ -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(),
];
}
}
+52
View File
@@ -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();
}
}
+146
View File
@@ -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;
}
}
+192
View File
@@ -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());
}
}
+99
View File
@@ -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;
}
}
+84
View File
@@ -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;
}
}
+114
View File
@@ -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(),
];
}
}
+111
View File
@@ -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);
}
}
+74
View File
@@ -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);
}
}
+357
View File
@@ -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;
}
}
+78
View File
@@ -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())
);
});
}
}
+115
View File
@@ -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);
}
});
}
}
+105
View File
@@ -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);
}
});
}
}
+53
View File
@@ -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);
}
});
}
}
+94
View File
@@ -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);
}
});
}
}
+202
View File
@@ -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);
}
});
}
}
+18
View File
@@ -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!']);
});
}
}
+42
View File
@@ -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]);
});
}
}
+22
View File
@@ -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);
});
}
}
+99
View File
@@ -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);
}
});
}
}
+45
View File
@@ -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);
}
});
}
}
+140
View File
@@ -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;
}
}
+96
View File
@@ -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);
}
});
}
}
+73
View File
@@ -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);
}
});
}
}
+111
View File
@@ -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);
}
});
}
}
+35
View File
@@ -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);
}
});
}
}
+44
View File
@@ -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);
}
});
}
}
+133
View File
@@ -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);
}
});
}
}
+121
View File
@@ -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);
}
}
}
+172
View File
@@ -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;
}
}
+160
View File
@@ -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);
}
}
+8
View File
@@ -0,0 +1,8 @@
<?php
namespace traits;
trait session_t
{
private string $session; // The session of the user
}