Add booking synchronization and API integration

Implemented methods for booking synchronization, including fetching, parsing, and updating bookings from a remote API. Added caching mechanisms and data validation for customer names, department names, and booking details. Integrated new API trait and remote booking class to improve scalability and enable automated tests for booking modules.
This commit is contained in:
Jepp9350
2025-01-20 15:49:08 +01:00
parent 851d5f3e4c
commit 635ad0fa04
14 changed files with 653 additions and 110 deletions
+8 -1
View File
@@ -56,6 +56,10 @@ class redis implements redis_i
*/
public function cache_economic_customer_name(int $customer_number, string $customer_name): self
{
// If the customer name is empty, or null, set it to 'IS_EMPTY_OR_NULL'
if (empty($customer_name)) {
$customer_name = 'IS_EMPTY_OR_NULL';
}
// Cache the economic customer name
$this->set('economic_customer_name_' . $customer_number, $customer_name);
return $this;
@@ -114,7 +118,10 @@ class redis implements redis_i
*/
public function cache_department_name(int $department_id, string $department_name): self
{
// Cache the department name
// Cache the department name (If it is not empty or null)
if (!empty($department_name)) {
$department_name = 'IS_EMPTY_OR_NULL';
}
$this->set('department_name_' . $department_id, $department_name);
return $this;
}
+6 -3
View File
@@ -31,7 +31,7 @@ class slack implements notification_i
return $this;
}
private function get_department_webhook(int $department_id): string
private function get_department_webhook(int $department_id): string|null
{
// Check if the department webhook is cached
$webhook = redis->get_department_webhook($department_id);
@@ -41,8 +41,11 @@ class slack implements notification_i
$department->id = $department_id;
$department->getObjectProperties();
$webhook = $department->slack_webhook->value();
// Cache the department webhook
redis->cache_department_webhook($department_id, $webhook);
// Cache the department webhook (If it is not empty or null)
if (!empty($webhook)) {
redis->cache_department_webhook($department_id, $webhook);
}
return null;
}
return redis->get_department_webhook($department_id);
}
+151
View File
@@ -0,0 +1,151 @@
<?php
namespace classes;
use interfaces\wordpress_bookings_remote_i;
use traits\wordpress_api_object_t;
class wordpress_bookings_remote implements wordpress_bookings_remote_i
{
use wordpress_api_object_t;
protected array $booking_cache = [];
protected wash_certificate_store $wash_certificate_store;
public function __construct()
{
// Run wordpress_api_object_t constructor
$this->wordpress_api_object_t_construct();
$this->wash_certificate_store = new wash_certificate_store();
}
/**
* @inheritDoc
*/
public function get_all_wash_ids(): array
{
// Get all the wash IDs
return $this->request('get_all_wash_ids');
}
/**
* @inheritDoc
*/
public function get_all_bookings(): array
{
// Get all the bookings
return $this->request('get_all_wash_bookings');
}
/**
* @inheritDoc
*/
public function get_last_wash_id(): int
{
// Get the last wash ID
$result = $this->request('get_last_wash_id');
return $result["success"] ? (int)$result["data"]["last_wash_id"] : 0;
}
/**
* @inheritDoc
*/
public function parse_bookings(array $bookings): array
{
// Parse all the bookings
$parsed_bookings = [];
foreach ( $bookings as $booking ) {
$parsed_booking = $this->parse_booking($booking);
if ($parsed_booking !== null) {
// Check if the booking has a wash certificate
$parsed_bookings[] = $parsed_booking;
}
}
return $parsed_bookings;
}
/**
* @inheritDoc
*/
public function parse_booking(array|int $booking): array|null
{
// Check if the booking is an integer, and get the booking by the ID
if (is_int($booking)) {
$booking = $this->get_booking($booking);
}
// Check if the success is false
if (isset($booking["success"])) {
if (!$booking["success"]) {
return null;
} else {
$booking = $booking["data"]["booking"];
}
} else if (isset($booking["id"])) {
// Check if the booking property is set
} else {
return null;
}
$this->booking_cache[$booking["id"]] = [
"id" => (int)$booking["id"],
"customer_number" => (int)$booking["customer_number"],
"wash_type" => (string)$booking["wash_type"],
"contact_email" => (string)$booking["contact_email"],
"reference_number" => (string)$booking["reference_number"],
"regNrTraekker" => (string)$booking["regNrTraekker"],
"regNrTrailer" => (string)$booking["regNrTrailer"],
"washCertificateEmail" => (string)$booking["washCertificateEmail"],
"date" => (string)$booking["date"],
"department" => (string)$booking["department"],
"pickup_bool" => (boolean)$booking["pickup_bool"] ? 'true' : 'false',
"notes" => (string)$booking["notes"],
"washCertificateStatus" => (string)$booking["washCertificateStatus"],
"washCertificateUrl" => (string)$booking["washCertificateUrl"],
"status" => (string)$booking["status"]
];
// If the status is pending, check if the booking has a wash certificate
if ($this->booking_cache[$booking["id"]]["status"] === 'pending') {
$this->booking_cache[$booking["id"]]["status"] = $this->check_booking_has_wash_certificate($booking) ? 'completed' : 'pending';
}
return $this->booking_cache[$booking["id"]];
}
/**
* @inheritDoc
*/
public function get_booking(int $id): array
{
// Get the booking by the ID
return $this->request('get_wash_booking', ['wash_id' => $id]);
}
/**
* @inheritDoc
*/
public function check_booking_has_wash_certificate(array $booking): bool
{
// Check if the booking has a wash certificate
return $this->wash_certificate_store->washCertificateExists($booking['id']);
}
/**
* @inheritDoc
*/
public function check_booking_has_expected_keys(array $booking, array $expected_keys): bool
{
// Check if the booking has the expected keys
return count(array_intersect($expected_keys, array_keys($booking))) === count($expected_keys);
}
/**
* @inheritDoc
*/
public function get_booking_cache(): array
{
// Get the booking cache
return $this->booking_cache;
}
}
+7 -4
View File
@@ -4,10 +4,6 @@ if (php_sapi_name() !== 'cli') {
exit;
}
$args = $argv;
echo "This is the CLI script";
echo "\n";
echo "Arguments: ";
print_r($args);
// If the first argument is 'run', switch to the second argument
if ($args[1] === 'run') {
@@ -28,6 +24,13 @@ if ($args[1] === 'run') {
echo "Running the slack test script";
require_once 'tests/slackModule/SlackModuleTest.php';
break;
case 'bookingSync-test':
echo "Running the bookingSync test script";
require_once 'tests/bookingModule/bookingSyncTest.php';
break;
case 'bookingSync':
require_once 'cron/SyncBookings.php';
break;
default:
echo "Invalid script name";
break;
-3
View File
@@ -31,8 +31,5 @@ $htaccess = "
// Write the .htaccess file (This is not really ideal, but it works for now. This is because the .htaccess file is changed by cPanel, and it's not going to be kept there anyway.)
file_put_contents(__DIR__ . '/.htaccess', $htaccess);
// Get the current time
$now = time();
// Log the time of the cron job
file_put_contents(__DIR__ . '/cron.log', date('Y-m-d H:i:s', $now) . ' - Cron job executed in ' . (time() - $now) . ' seconds ( ' . (microtime(true) - $now) . 'ms )' . PHP_EOL, FILE_APPEND);
+19
View File
@@ -0,0 +1,19 @@
<?php
/**
* This script is used to sync bookings from the remote API to the local database.
* It is run as a cron job.
*
* index.php run bookingSync
*/
// prevent direct access
use objects\bookings_o;
if (!defined('WD')) {
exit;
}
// Sync the bookings
$bookings_o = new bookings_o();
$bookings_o->syncBookings();
+1
View File
@@ -40,6 +40,7 @@ require_once 'classes/ratelimit.php';
require_once 'classes/wash_certificate_store.php';
require_once 'classes/redis.php';
require_once 'classes/slack.php';
require_once 'classes/wordpress_bookings_remote.php';
/**
* Modules
@@ -0,0 +1,65 @@
<?php
namespace interfaces;
interface wordpress_bookings_remote_i
{
/**
* Get booking by ID from the remote API
* @param int $id
* @return array
*/
public function get_booking(int $id): array;
/**
* Parse booking data, and return it as an array
* @param array|int $booking
* @return array|null The parsed booking data, or null if the booking was not found
*/
public function parse_booking(array|int $booking): array|null;
/**
* Get all wash IDs from the remote API
* @return array
*/
public function get_all_wash_ids(): array;
/**
* Get all bookings from the remote API
* @return array
*/
public function get_all_bookings(): array;
/**
* Get the last wash ID from the remote API
* @return int
*/
public function get_last_wash_id(): int;
/**
* Parse multiple bookings
* @param array $bookings
* @return array
*/
public function parse_bookings(array $bookings): array;
/**
* Check if a booking has the expected keys
* @param array $booking
* @param array $expected_keys
* @return bool
*/
public function check_booking_has_expected_keys(array $booking, array $expected_keys): bool;
/**
* Check if a booking has a wash certificate
* @param array $booking
*/
public function check_booking_has_wash_certificate(array $booking): bool;
/**
* Get the booking cache
* @return array
*/
public function get_booking_cache(): array;
}
+143 -75
View File
@@ -6,6 +6,7 @@ use classes\db;
use classes\object_property;
use classes\response;
use classes\slack;
use classes\wordpress_bookings_remote;
use traits\db_object_t;
class bookings_o extends db
@@ -27,11 +28,153 @@ class bookings_o extends db
public object_property $washCertificateUrl;
public object_property $status;
private static function isCancelled(int $id): bool
{
global $db;
// Check if the booking has been cancelled
$sql = "SELECT status FROM bookings WHERE id = $id";
$result = $db->query($sql);
$row = $db->fetch_assoc($result);
return $row['status'] === 'cancelled';
}
public function structure(): void
{
$this->setTable('bookings');
}
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 */
$db, $response;
// Add the customer number to the filters
$filters['customer_number'] = $customer_number;
// List the objects with pagination
$array = $this->listObjectsWithPagination($page, $limit, $search, $filters, $order);
// Get the total number of objects
$total = $this->getTotalObjects($search, $filters);
$response->paginate($page, $limit, $total);
return $array;
}
public function getDepartmentBookingsUnfulfilledCount(int $department_id): int
{
global /** @var response $response */
$db, $response;
// Check if the count is cached
if (redis->get_department_booking_count($department_id)) {
$response->add_meta('cached', true);
return redis->get_department_booking_count($department_id);
}
$sql = "SELECT COUNT(*) as count FROM $this->table WHERE department = $department_id AND status = 'pending'";
$result = $db->query($sql);
$row = $db->fetch_assoc($result);
// Cache the count
redis->cache_department_booking_count($department_id, $row['count']);
return $row['count'];
}
public function delete(int $id): void
{
$this->id = $id;
$this->getObjectProperties();
// Set the status to cancelled
$this->status->set('cancelled');
// Remove the cache
redis->clear_department_booking_count($this->department->value());
}
public function getObjectProperties(): void
{
$this->customer_number = new object_property($this->table, $this->id, 'customer_number', 'int', true);
$this->wash_type = new object_property($this->table, $this->id, 'wash_type', 'string', true);
$this->contact_email = new object_property($this->table, $this->id, 'contact_email', 'string', true);
$this->reference_number = new object_property($this->table, $this->id, 'reference_number', 'string', true);
$this->regNrTraekker = new object_property($this->table, $this->id, 'regNrTraekker', 'string', true);
$this->regNrTrailer = new object_property($this->table, $this->id, 'regNrTrailer', 'string', true);
$this->washCertificateEmail = new object_property($this->table, $this->id, 'washCertificateEmail', 'string', true);
$this->date = new object_property($this->table, $this->id, 'date', 'string', true);
$this->department = new object_property($this->table, $this->id, 'department', 'string', true);
$this->pickup_bool = new object_property($this->table, $this->id, 'pickup_bool', 'int', true);
$this->notes = new object_property($this->table, $this->id, 'notes', 'string', true);
$this->washCertificateStatus = new object_property($this->table, $this->id, 'washCertificateStatus', 'string', true);
$this->washCertificateUrl = new object_property($this->table, $this->id, 'washCertificateUrl', 'string', true);
$this->status = new object_property($this->table, $this->id, 'status', 'string', true);
}
public function parseBookings(array $listObjectsWithPaginationIfSet): array
{
// Parse the customer numbers
$bookings = $this->parseCustomerNumbers($listObjectsWithPaginationIfSet);
return $bookings;
}
public function parseCustomerNumbers(array $listObjectsWithPaginationIfSet): array
{
// Parse the customer numbers
foreach ( $listObjectsWithPaginationIfSet as $key => $value ) {
$listObjectsWithPaginationIfSet[$key]['customer_name'] = redis->get_economic_customer_name($value['customer_number']) ?? (new users_o())->getCustomerName($value['customer_number']);
}
return $listObjectsWithPaginationIfSet;
}
public function syncBookings(): array
{
global /** @var response $response */
$db, $response;
$wordpress_bookings_remote = new wordpress_bookings_remote();
// Get all the bookings from the remote API
$bookings = $wordpress_bookings_remote->get_all_bookings()['data']['all_wash_bookings'];
// Parse the bookings
$parsed_bookings = $wordpress_bookings_remote->parse_bookings($bookings);
// Remove the cancelled bookings from the $parsed_bookings array
$cancelled_bookings = $this->getAllCancelledBookings();
foreach ( $cancelled_bookings as $cancelled_booking ) {
// Remove the cancelled booking from the parsed bookings
foreach ( $parsed_bookings as $key => $parsed_booking ) {
if ((int)$parsed_booking['id'] === (int)$cancelled_booking['id']) {
unset($parsed_bookings[$key]);
}
}
}
// Sync the bookings
foreach ( $parsed_bookings as $booking ) {
// Add or update the booking
$this->addOrUpdate(
$booking['id'],
$booking['customer_number'],
$booking['wash_type'],
$booking['contact_email'],
$booking['reference_number'],
$booking['regNrTraekker'],
$booking['regNrTrailer'],
$booking['washCertificateEmail'],
$booking['date'],
$booking['department'],
$booking['pickup_bool'] === 'true' ? 1 : 0,
$booking['notes'],
$booking['washCertificateStatus'],
$booking['washCertificateUrl'],
$booking['status']
);
}
return [
"bookings" => count($bookings),
"cancelled" => count($cancelled_bookings),
"parsed" => count($parsed_bookings),
];
}
public function getAllCancelledBookings(): array
{
global $db;
// Get all the cancelled bookings
$sql = "SELECT * FROM $this->table WHERE status = 'cancelled'";
$result = $db->query($sql);
return $db->fetch_all($result);
}
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;
@@ -127,79 +270,4 @@ class bookings_o extends db
$this->id = $db->insert_id();
}
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 */
$db, $response;
// Add the customer number to the filters
$filters['customer_number'] = $customer_number;
// List the objects with pagination
$array = $this->listObjectsWithPagination($page, $limit, $search, $filters, $order);
// Get the total number of objects
$total = $this->getTotalObjects($search, $filters);
$response->paginate($page, $limit, $total);
return $array;
}
public function getDepartmentBookingsUnfulfilledCount(int $department_id): int
{
global /** @var response $response */
$db, $response;
// Check if the count is cached
if (redis->get_department_booking_count($department_id)) {
$response->add_meta('cached', true);
return redis->get_department_booking_count($department_id);
}
$sql = "SELECT COUNT(*) as count FROM $this->table WHERE department = $department_id AND status = 'pending'";
$result = $db->query($sql);
$row = $db->fetch_assoc($result);
// Cache the count
redis->cache_department_booking_count($department_id, $row['count']);
return $row['count'];
}
public function delete(int $id): void
{
$this->id = $id;
$this->getObjectProperties();
// Set the status to cancelled
$this->status->set('cancelled');
// Remove the cache
redis->clear_department_booking_count($this->department->value());
}
public function getObjectProperties(): void
{
$this->customer_number = new object_property($this->table, $this->id, 'customer_number', 'int', true);
$this->wash_type = new object_property($this->table, $this->id, 'wash_type', 'string', true);
$this->contact_email = new object_property($this->table, $this->id, 'contact_email', 'string', true);
$this->reference_number = new object_property($this->table, $this->id, 'reference_number', 'string', true);
$this->regNrTraekker = new object_property($this->table, $this->id, 'regNrTraekker', 'string', true);
$this->regNrTrailer = new object_property($this->table, $this->id, 'regNrTrailer', 'string', true);
$this->washCertificateEmail = new object_property($this->table, $this->id, 'washCertificateEmail', 'string', true);
$this->date = new object_property($this->table, $this->id, 'date', 'string', true);
$this->department = new object_property($this->table, $this->id, 'department', 'string', true);
$this->pickup_bool = new object_property($this->table, $this->id, 'pickup_bool', 'int', true);
$this->notes = new object_property($this->table, $this->id, 'notes', 'string', true);
$this->washCertificateStatus = new object_property($this->table, $this->id, 'washCertificateStatus', 'string', true);
$this->washCertificateUrl = new object_property($this->table, $this->id, 'washCertificateUrl', 'string', true);
$this->status = new object_property($this->table, $this->id, 'status', 'string', true);
}
public function parseBookings(array $listObjectsWithPaginationIfSet): array
{
// Parse the customer numbers
$bookings = $this->parseCustomerNumbers($listObjectsWithPaginationIfSet);
return $bookings;
}
public function parseCustomerNumbers(array $listObjectsWithPaginationIfSet): array
{
// Parse the customer numbers
foreach ( $listObjectsWithPaginationIfSet as $key => $value ) {
$listObjectsWithPaginationIfSet[$key]['customer_name'] = redis->get_economic_customer_name($value['customer_number']) ?? (new users_o())->getCustomerName($value['customer_number']);
}
return $listObjectsWithPaginationIfSet;
}
}
+13 -7
View File
@@ -155,13 +155,19 @@ class departments_o extends db
$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);
try {
$this->id = $department;
$this->getObjectProperties();
$name = $this->name->value();
// Cache the department name (If it is not empty or null)
if (!empty($name)) {
redis->cache_department_name($department, $name);
}
} catch (\Exception $e) {
$name = 'Unable to get department name: ' . $department;
}
return $name;
}
return redis->get_department_name($department);
return redis->get_department_name($department) ?? 'Unable to get department name: ' . $department;
}
}
+16 -15
View File
@@ -195,6 +195,7 @@ class users_o extends db
$array = [
'id' => (int)$this->id,
'customer_number' => (int)$this->customer_number->value(),
'customer_name' => $this->getCustomerName($this->customer_number->value()),
'display_name' => $this->display_name->value(),
'group_id' => (int)$this->group_id->value(),
'created_at' => $this->created_at->value(),
@@ -219,6 +220,20 @@ class users_o extends db
return $array;
}
public function getCustomerName(int $customer_number): string|null
{
// Check if the customer name is cached
if (redis->get_economic_customer_name($customer_number) !== null) {
return redis->get_economic_customer_name($customer_number);
}
// Get the customer name from the external source
$economic = new economicCustomers();
$customer_name = $economic->getCustomerName($customer_number);
// Cache the customer name
redis->cache_economic_customer_name($customer_number, $customer_name ?? '');
return $customer_name;
}
public function getNotes(): array
{
global $db;
@@ -634,7 +649,7 @@ class users_o extends db
return true;
}
// Get the record from the database
$sql = "SELECT * FROM bookings WHERE id = $id AND user_id = " . $this->id;
$sql = "SELECT * FROM bookings WHERE id = $id AND customer_number = " . $this->customer_number->value();
$result = $db->query($sql);
if ($result->num_rows > 0) {
return true;
@@ -654,18 +669,4 @@ class users_o extends db
}
return $listObjectsWithPaginationIfSet;
}
public function getCustomerName(int $customer_number): string|null
{
// Check if the customer name is cached
if (redis->get_economic_customer_name($customer_number)) {
return redis->get_economic_customer_name($customer_number);
}
// Get the customer name from the external source
$economic = new economicCustomers();
$customer_name = $economic->getCustomerName($customer_number);
// Cache the customer name
redis->cache_economic_customer_name($customer_number, $customer_name ?? '');
return $customer_name;
}
}
+24 -2
View File
@@ -59,8 +59,9 @@ class bookingsRoute
// Log the incident
(new logs_o())->add('bookings', 'global', 1, $user->id, 'LIST_OWN_BOOKINGS', 'Successfully listed own bookings');
// Return the list of departments
$bookings_o = new bookings_o();
$response->success(
(new bookings_o())->getCustomerBookingsPaginated(
$bookings_o->parseBookings($bookings_o->getCustomerBookingsPaginated(
$user->customer_number->value(),
($this->fromRequest('page') ?? 1),
($this->fromRequest('limit') ?? 10),
@@ -68,7 +69,7 @@ class bookingsRoute
$this->fromRequest('search') === null ? '' : $this->fromRequest('search'),
$this->fromRequest('filters') === null ? [] :
$response->parseFilters($this->fromRequest('filters')) ?? []
)
))
);
} else {
// Log the incident
@@ -230,5 +231,26 @@ class bookingsRoute
["message" => "Booking deleted"]
);
});
$this->post('/superuser/bookings/sync/all', function () {
// Require the user to be logged in
global /** @var response $response */
$response;
$this->requirePermission('sync_all_bookings');
// Get the user object
$user = (new authentication())->get_user();
// Check if the request was successful
if (!$user->exists()) {
$response->error('User not found', 400);
}
// Log the incident
(new logs_o())->add('bookings', 'global', 1, $user->id, 'SYNC_ALL_BOOKINGS', 'Successfully synced all bookings');
// Sync all bookings
(new bookings_o())->syncBookings();
// Return success
$response->success(
["message" => "All bookings synced"]
);
});
}
}
+142
View File
@@ -0,0 +1,142 @@
<?php
// prevent direct access
use classes\wordpress_bookings_remote;
if (!defined('WD')) {
exit;
}
function warn($message): void
{
echo "\n\033[33m$message\033[0m\n";
}
// Test if we can fetch a booking.
$booking_id = 155;
$wordpress_bookings_remote = new wordpress_bookings_remote();
// Get the last wash ID from the remote API.
$last_wash_id = $wordpress_bookings_remote->get_last_wash_id();
if (empty($last_wash_id)) {
warn("Failed to fetch the last wash ID");
return;
}
echo "\nLast wash ID fetched successfully from the remote API\n";
echo "\nLast wash ID: $last_wash_id\n";
// Get all wash IDs from the remote API.
$wash_ids = $wordpress_bookings_remote->get_all_wash_ids()['data']['all_wash_ids'];
if (empty($wash_ids)) {
warn("Failed to fetch wash IDs");
return;
}
echo "\nWash IDs fetched successfully from the remote API\n";
echo "\nWash IDs: (count: " . count($wash_ids) . ")\n";
// Parse all bookings from the remote API.
$bookings = $wordpress_bookings_remote->parse_bookings($wordpress_bookings_remote->get_all_bookings());
if (empty($bookings)) {
warn("Failed to fetch bookings");
return;
}
// Get all bookings from the remote API.
$bookings = $wordpress_bookings_remote->get_all_bookings();
if (empty($bookings)) {
warn("Failed to fetch bookings");
return;
}
echo "\nBookings fetched successfully from the remote API\n";
echo "\nBookings: (count: " . count($bookings['data']['all_wash_bookings']) . ")\n";
$booking = $wordpress_bookings_remote->parse_booking($booking_id);
$bookings_o = new \objects\bookings_o();
if (empty($booking)) {
warn("Failed to fetch booking with ID $booking_id");
} else {
// Test if the booking has the expected keys.
$expected_keys = [
'id',
'customer_number',
'wash_type',
'contact_email',
'reference_number',
'regNrTraekker',
'regNrTrailer',
'washCertificateEmail',
'date',
'department',
'pickup_bool',
'notes',
'washCertificateStatus',
'washCertificateUrl',
'status',
];
foreach ( $expected_keys as $key ) {
if (!array_key_exists($key, $booking)) {
warn("Booking with ID $booking_id is missing key $key");
return;
}
}
echo "\nBooking with ID $booking_id fetched successfully\n";
// Check if the booking wash certificate exists.
$wash_certificate_store = new \classes\wash_certificate_store();
if (!$wash_certificate_store->washCertificateExists($booking['id'])) {
warn("Booking with ID $booking_id does not have a wash certificate");
} else {
echo "\nBooking with ID $booking_id has a wash certificate\n";
$booking['washCertificateUrl'] = 'Protected URL';
$booking['washCertificateStatus'] = 'completed';
// Print the booking data.
echo "\nBooking data:\n";
print_r($booking);
// Save the booking data to database.
$bookings_o->addOrUpdate(
$booking['id'],
$booking['customer_number'],
$booking['wash_type'],
$booking['contact_email'],
$booking['reference_number'],
$booking['regNrTraekker'],
$booking['regNrTrailer'],
$booking['washCertificateEmail'],
$booking['date'],
$booking['department'],
$booking['pickup_bool'] === 'true' ? 1 : 0,
$booking['notes'],
$booking['washCertificateStatus'],
$booking['washCertificateUrl'],
$booking['status']
);
echo "\nBooking data saved to database\n";
}
}
echo "\nSyncing bookings to the remote API... This may take a while\n";
// Sync all bookings to the remote API.
$start = microtime(true);
$sync = $bookings_o->syncBookings();
$end = microtime(true);
echo "\nBookings synced to the remote API\n";
echo "\nTime taken: " . ($end - $start) . " seconds\n";
echo "\nTime per booking: " . (($end - $start) / count($bookings['data']['all_wash_bookings'])) . " seconds\n";
echo "\nSync: \n";
print_r($sync);
+58
View File
@@ -0,0 +1,58 @@
<?php
namespace traits;
trait wordpress_api_object_t
{
protected string $API_URL; // The URL of the WordPress API
protected string $API_KEY; // The key of the WordPress API
public function __construct()
{
$this->wordpress_api_object_t_construct();
}
public function wordpress_api_object_t_construct(): void
{
global $EMAIL_WASH_CERTIFICATE_TOKEN, $WORDPRESS_API_URL;
// Make sure the WordPress API configuration is set
if (!isset($EMAIL_WASH_CERTIFICATE_TOKEN) || !isset($WORDPRESS_API_URL)) {
throw new \Exception('WordPress API configuration is not set');
}
// Apply the WordPress API configuration
$this->API_KEY = $EMAIL_WASH_CERTIFICATE_TOKEN;
$this->API_URL = $WORDPRESS_API_URL;
}
public function debug(): void
{
echo 'API URL: ' . $this->API_URL . '<br>';
echo 'API KEY: ' . $this->API_KEY . '<br>';
}
public function request($invoke = 'example', $data = []): array
{
// Add the auth_key to the data
$data['auth_key'] = $this->API_KEY;
$data['invoke'] = $invoke;
$data['action'] = 'twc_api_endpoints';
// Send a post request to the API
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->API_URL);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
curl_close($ch);
// Check if the response is an error
if ($response === false) {
return ['error' => 'Curl error: ' . curl_error($ch)];
}
// If the response is not JSON, return it as is
if ($response[0] !== '{') {
return ['response' => $response];
}
return json_decode($response, true);
}
}