Add caching and Slack notification enhancements
Implemented caching for department and customer names to improve performance. Added Slack notifications for new bookings with detailed formatting. Refactored related methods to streamline functionality and ensure better code clarity.
This commit is contained in:
@@ -108,4 +108,9 @@ class db
|
||||
{
|
||||
return $this->conn->prepare($sql);
|
||||
}
|
||||
|
||||
public function num_rows(\mysqli_result|bool $result): int|string
|
||||
{
|
||||
return $result->num_rows;
|
||||
}
|
||||
}
|
||||
@@ -108,4 +108,33 @@ class redis implements redis_i
|
||||
$this->delete('department_webhook_' . $department_id);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function cache_department_name(int $department_id, string $department_name): self
|
||||
{
|
||||
// Cache the department name
|
||||
$this->set('department_name_' . $department_id, $department_name);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_department_name(int $department_id): string|null
|
||||
{
|
||||
// Get the department name
|
||||
return $this->get('department_name_' . $department_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function clear_department_name(int $department_id): self
|
||||
{
|
||||
// Clear the department name
|
||||
$this->delete('department_name_' . $department_id);
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ namespace classes;
|
||||
use GuzzleHttp\Client;
|
||||
use interfaces\notification_i;
|
||||
use objects\departments_o;
|
||||
use objects\users_o;
|
||||
use traits\notification_t;
|
||||
|
||||
|
||||
@@ -78,4 +79,28 @@ class slack implements notification_i
|
||||
return 'Failed to send message: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public function format_new_booking($id, $customer_number, string $wash_type, string $contact_email, string $reference_number, string $regNrTraekker, string $regNrTrailer, string $washCertificateEmail, string $date, int $department, $pickup_bool, string $notes, string $washCertificateStatus, string $washCertificateUrl, string $status): string
|
||||
{
|
||||
// Get the department name
|
||||
$department_name = (new departments_o())->getDepartmentName($department);
|
||||
// Get the customer name
|
||||
$customer_name = (new users_o())->getCustomerName($customer_number);
|
||||
// Format the message
|
||||
return "New booking created\n"
|
||||
. "ID: $id\n"
|
||||
. "Customer: $customer_name\n"
|
||||
. "Customer number: $customer_number\n"
|
||||
. "Wash type: $wash_type\n"
|
||||
. "Contact email: $contact_email\n"
|
||||
. "Reference number: $reference_number\n"
|
||||
. "RegNr Traekker: $regNrTraekker\n"
|
||||
. "RegNr Trailer: $regNrTrailer\n"
|
||||
. "Wash certificate email: $washCertificateEmail\n"
|
||||
. "Date: $date\n"
|
||||
. "Department: $department_name\n"
|
||||
. "Pickup: $pickup_bool\n"
|
||||
. "Notes: $notes\n"
|
||||
. "Status: $status";
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php global $DEBUG, $CONFIG_DB, $ENCRYPTION_KEY, $CORS, $WD, $db, $response, $request, $router, $redis;
|
||||
<?php global /** @var response $response */
|
||||
$DEBUG, $CONFIG_DB, $ENCRYPTION_KEY, $CORS, $WD, $db, $response, $request, $router, $redis;
|
||||
/**
|
||||
* This is the main entry point to the Truck Wash API.
|
||||
*/
|
||||
|
||||
@@ -69,4 +69,26 @@ interface redis_i
|
||||
* @return self
|
||||
*/
|
||||
public function clear_department_webhook(int $department_id): self;
|
||||
|
||||
/**
|
||||
* Cache a department name
|
||||
* @param int $department_id
|
||||
* @param string $department_name
|
||||
* @return self
|
||||
*/
|
||||
public function cache_department_name(int $department_id, string $department_name): self;
|
||||
|
||||
/**
|
||||
* Get a department name
|
||||
* @param int $department_id
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_department_name(int $department_id): string|null;
|
||||
|
||||
/**
|
||||
* Clear a department name
|
||||
* @param int $department_id
|
||||
* @return self
|
||||
*/
|
||||
public function clear_department_name(int $department_id): self;
|
||||
}
|
||||
+69
-38
@@ -5,6 +5,7 @@ namespace objects;
|
||||
use classes\db;
|
||||
use classes\object_property;
|
||||
use classes\response;
|
||||
use classes\slack;
|
||||
use traits\db_object_t;
|
||||
|
||||
class bookings_o extends db
|
||||
@@ -31,6 +32,74 @@ class bookings_o extends db
|
||||
$this->setTable('bookings');
|
||||
}
|
||||
|
||||
public function addOrUpdate($id, $customer_number, $wash_type, $contact_email, $reference_number, $regNrTraekker, $regNrTrailer, $washCertificateEmail, $date, $department, $pickup_bool, $notes, $washCertificateStatus, $washCertificateUrl, $status): void
|
||||
{
|
||||
global $db;
|
||||
// Avoid SQL injection
|
||||
$wash_type = $db->escape_string($wash_type);
|
||||
$contact_email = $db->escape_string($contact_email);
|
||||
$reference_number = $db->escape_string($reference_number);
|
||||
$regNrTraekker = $db->escape_string($regNrTraekker);
|
||||
$regNrTrailer = $db->escape_string($regNrTrailer);
|
||||
$washCertificateEmail = $db->escape_string($washCertificateEmail);
|
||||
$date = $db->escape_string($date);
|
||||
// Parse the department name to id
|
||||
$department = $this->getDepartmentIdByLegacyName($department);
|
||||
$notes = $db->escape_string($notes);
|
||||
$washCertificateStatus = $db->escape_string($washCertificateStatus);
|
||||
$washCertificateUrl = $db->escape_string($washCertificateUrl);
|
||||
$status = $db->escape_string($status);
|
||||
// Check if the entry already exists
|
||||
$sql = "SELECT * FROM $this->table WHERE id = $id";
|
||||
$result = $db->query($sql);
|
||||
if ($db->num_rows($result) === 0) {
|
||||
// Send a department webhook if the booking is new
|
||||
$slack = new slack();
|
||||
try {
|
||||
$slack->send_department_booking_notification($department, $slack->format_new_booking(
|
||||
$id,
|
||||
$customer_number,
|
||||
$wash_type,
|
||||
$contact_email,
|
||||
$reference_number,
|
||||
$regNrTraekker,
|
||||
$regNrTrailer,
|
||||
$washCertificateEmail,
|
||||
$date,
|
||||
$department,
|
||||
$pickup_bool,
|
||||
$notes,
|
||||
$washCertificateStatus,
|
||||
$washCertificateUrl,
|
||||
$status
|
||||
));
|
||||
} catch (\Exception $e) {
|
||||
// Log the error
|
||||
$logs = new logs_o();
|
||||
$logs->add('slack', 0, 3, 0, 'SEND_DEPARTMENT_BOOKING_NOTIFICATION', $e->getMessage());
|
||||
}
|
||||
}
|
||||
// Create a new record in the database ( Replace the code, if an entry already exists )
|
||||
$sql = "INSERT INTO $this->table (id, customer_number, wash_type, contact_email, reference_number, regNrTraekker, regNrTrailer, washCertificateEmail, date, department, pickup_bool, notes, washCertificateStatus, washCertificateUrl, status) VALUES ($id, $customer_number, '$wash_type', '$contact_email', '$reference_number', '$regNrTraekker', '$regNrTrailer', '$washCertificateEmail', '$date', '$department', $pickup_bool, '$notes', '$washCertificateStatus', '$washCertificateUrl', '$status') ON DUPLICATE KEY UPDATE customer_number = $customer_number, wash_type = '$wash_type', contact_email = '$contact_email', reference_number = '$reference_number', regNrTraekker = '$regNrTraekker', regNrTrailer = '$regNrTrailer', washCertificateEmail = '$washCertificateEmail', date = '$date', department = '$department', pickup_bool = $pickup_bool, notes = '$notes', washCertificateStatus = '$washCertificateStatus', washCertificateUrl = '$washCertificateUrl', status = '$status'";
|
||||
$db->query($sql);
|
||||
// Clear the cache
|
||||
redis->clear_department_booking_count($department);
|
||||
}
|
||||
|
||||
public function getDepartmentIdByLegacyName(string $departmentName): int
|
||||
{
|
||||
// Get the department id by the legacy name
|
||||
$departmentLegacyNames = [
|
||||
'køge' => 4,
|
||||
'taastrup' => 2,
|
||||
'aarhusc' => 5,
|
||||
'roskilde' => 6,
|
||||
'hvidovre' => 1,
|
||||
'glostrup' => 3,
|
||||
];
|
||||
return $departmentLegacyNames[strtolower($departmentName)] ?? 0;
|
||||
}
|
||||
|
||||
public function add(int $customer_number, string $wash_type, string $contact_email, string $reference_number, string $regNrTraekker, string $regNrTrailer, string $washCertificateEmail, string $date, string $department, int $pickup_bool, string $notes, string $washCertificateStatus, string $washCertificateUrl, string $status): void
|
||||
{
|
||||
global $db;
|
||||
@@ -58,44 +127,6 @@ class bookings_o extends db
|
||||
$this->id = $db->insert_id();
|
||||
}
|
||||
|
||||
public function getDepartmentIdByLegacyName(string $departmentName): int
|
||||
{
|
||||
// Get the department id by the legacy name
|
||||
$departmentLegacyNames = [
|
||||
'køge' => 4,
|
||||
'taastrup' => 2,
|
||||
'aarhusc' => 5,
|
||||
'roskilde' => 6,
|
||||
'hvidovre' => 1,
|
||||
'glostrup' => 3,
|
||||
];
|
||||
return $departmentLegacyNames[strtolower($departmentName)] ?? 0;
|
||||
}
|
||||
|
||||
public function addOrUpdate($id, $customer_number, $wash_type, $contact_email, $reference_number, $regNrTraekker, $regNrTrailer, $washCertificateEmail, $date, $department, $pickup_bool, $notes, $washCertificateStatus, $washCertificateUrl, $status): void
|
||||
{
|
||||
global $db;
|
||||
// Avoid SQL injection
|
||||
$wash_type = $db->escape_string($wash_type);
|
||||
$contact_email = $db->escape_string($contact_email);
|
||||
$reference_number = $db->escape_string($reference_number);
|
||||
$regNrTraekker = $db->escape_string($regNrTraekker);
|
||||
$regNrTrailer = $db->escape_string($regNrTrailer);
|
||||
$washCertificateEmail = $db->escape_string($washCertificateEmail);
|
||||
$date = $db->escape_string($date);
|
||||
// Parse the department name to id
|
||||
$department = $this->getDepartmentIdByLegacyName($department);
|
||||
$notes = $db->escape_string($notes);
|
||||
$washCertificateStatus = $db->escape_string($washCertificateStatus);
|
||||
$washCertificateUrl = $db->escape_string($washCertificateUrl);
|
||||
$status = $db->escape_string($status);
|
||||
// Create a new record in the database ( Replace the code, if an entry already exists )
|
||||
$sql = "INSERT INTO $this->table (id, customer_number, wash_type, contact_email, reference_number, regNrTraekker, regNrTrailer, washCertificateEmail, date, department, pickup_bool, notes, washCertificateStatus, washCertificateUrl, status) VALUES ($id, $customer_number, '$wash_type', '$contact_email', '$reference_number', '$regNrTraekker', '$regNrTrailer', '$washCertificateEmail', '$date', '$department', $pickup_bool, '$notes', '$washCertificateStatus', '$washCertificateUrl', '$status') ON DUPLICATE KEY UPDATE customer_number = $customer_number, wash_type = '$wash_type', contact_email = '$contact_email', reference_number = '$reference_number', regNrTraekker = '$regNrTraekker', regNrTrailer = '$regNrTrailer', washCertificateEmail = '$washCertificateEmail', date = '$date', department = '$department', pickup_bool = $pickup_bool, notes = '$notes', washCertificateStatus = '$washCertificateStatus', washCertificateUrl = '$washCertificateUrl', status = '$status'";
|
||||
$db->query($sql);
|
||||
// Clear the cache
|
||||
redis->clear_department_booking_count($department);
|
||||
}
|
||||
|
||||
public function getCustomerBookingsPaginated(int $customer_number, int $page = 1, int $limit = 10, array $order = ['id' => 'DESC'], string $search = null, array $filters = null): array
|
||||
{
|
||||
global /** @var response $response */
|
||||
|
||||
@@ -147,4 +147,21 @@ class departments_o extends db
|
||||
$this->getObjectProperties();
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDepartmentName(int $department): string
|
||||
{
|
||||
global $db;
|
||||
// Check if the department name is cached
|
||||
$name = redis->get_department_name($department);
|
||||
// If the department name is not cached, get it from the database
|
||||
if ($name === null) {
|
||||
$sql = "SELECT name FROM $this->table WHERE id = $department";
|
||||
$result = $db->query($sql);
|
||||
$result = $db->fetch_assoc($result);
|
||||
$name = $result['name'];
|
||||
// Cache the department name
|
||||
redis->cache_department_name($department, $name);
|
||||
}
|
||||
return redis->get_department_name($department);
|
||||
}
|
||||
}
|
||||
+14
-1
@@ -642,6 +642,19 @@ class users_o extends db
|
||||
return false;
|
||||
}
|
||||
|
||||
public function parseUsers(array $listObjectsWithPaginationIfSet): array
|
||||
{
|
||||
return self::parseCustomerNumbers($listObjectsWithPaginationIfSet);
|
||||
}
|
||||
|
||||
public function parseCustomerNumbers(array $listObjectsWithPaginationIfSet): array
|
||||
{
|
||||
foreach ( $listObjectsWithPaginationIfSet as $key => $value ) {
|
||||
$listObjectsWithPaginationIfSet[$key]['customer_name'] = $this->getCustomerName($value['customer_number']);
|
||||
}
|
||||
return $listObjectsWithPaginationIfSet;
|
||||
}
|
||||
|
||||
public function getCustomerName(int $customer_number): string|null
|
||||
{
|
||||
// Check if the customer name is cached
|
||||
@@ -652,7 +665,7 @@ class users_o extends db
|
||||
$economic = new economicCustomers();
|
||||
$customer_name = $economic->getCustomerName($customer_number);
|
||||
// Cache the customer name
|
||||
redis->cache_economic_customer_name($customer_number, $customer_name);
|
||||
redis->cache_economic_customer_name($customer_number, $customer_name ?? '');
|
||||
return $customer_name;
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace routes;
|
||||
|
||||
use classes\authentication;
|
||||
use classes\response;
|
||||
use objects\logs_o;
|
||||
use objects\users_o;
|
||||
use traits\route_t;
|
||||
@@ -15,7 +16,8 @@ class usersRoute
|
||||
{
|
||||
$this->get('/users', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
global /** @var response $response */
|
||||
$response;
|
||||
$this->requirePermission('list_users');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
@@ -24,8 +26,9 @@ class usersRoute
|
||||
// Log the incident
|
||||
(new logs_o())->add('users', 'global', 1, $user->id, 'LIST_USERS', 'Successfully listed users');
|
||||
// Return the list of users
|
||||
$users_o = new users_o();
|
||||
$response->success(
|
||||
(new users_o())->listObjects()
|
||||
$users_o->parseUsers($users_o->listObjectsWithPaginationIfSet())
|
||||
);
|
||||
} else {
|
||||
// Log the incident
|
||||
|
||||
Reference in New Issue
Block a user