190 lines
7.7 KiB
PHP
190 lines
7.7 KiB
PHP
<?php
|
|
if (!defined('ABSPATH')) exit;
|
|
|
|
class Fusion_WooDoo_REST_Endpoints {
|
|
|
|
public function __construct() {
|
|
add_action('rest_api_init', [$this, 'register_routes']);
|
|
}
|
|
|
|
public function register_routes(): void {
|
|
$namespace = 'fusion-woodoo/v1';
|
|
|
|
register_rest_route($namespace, '/order/update', [
|
|
'methods' => WP_REST_Server::CREATABLE,
|
|
'callback' => [$this, 'handle_order_update'],
|
|
'permission_callback' => [$this, 'verify_api_key'],
|
|
'args' => [
|
|
'order_id' => ['required' => true, 'validate_callback' => 'is_numeric'],
|
|
'status' => ['required' => false, 'sanitize_callback' => 'sanitize_text_field'],
|
|
'tracking_number' => ['required' => false, 'sanitize_callback' => 'sanitize_text_field'],
|
|
'shipping_carrier' => ['required' => false, 'sanitize_callback' => 'sanitize_text_field'],
|
|
],
|
|
]);
|
|
|
|
register_rest_route($namespace, '/order/invoice', [
|
|
'methods' => WP_REST_Server::CREATABLE,
|
|
'callback' => [$this, 'handle_order_invoice'],
|
|
'permission_callback' => [$this, 'verify_api_key'],
|
|
'args' => [
|
|
'order_id' => ['required' => true, 'validate_callback' => 'is_numeric'],
|
|
'pdf_data' => ['required' => true],
|
|
'filename' => ['required' => false, 'sanitize_callback' => 'sanitize_file_name'],
|
|
],
|
|
]);
|
|
|
|
register_rest_route($namespace, '/order/delivery', [
|
|
'methods' => WP_REST_Server::CREATABLE,
|
|
'callback' => [$this, 'handle_order_delivery'],
|
|
'permission_callback' => [$this, 'verify_api_key'],
|
|
'args' => [
|
|
'order_id' => ['required' => true, 'validate_callback' => 'is_numeric'],
|
|
'pdf_data' => ['required' => true],
|
|
'filename' => ['required' => false, 'sanitize_callback' => 'sanitize_file_name'],
|
|
],
|
|
]);
|
|
|
|
register_rest_route($namespace, '/order/messages', [
|
|
'methods' => WP_REST_Server::CREATABLE,
|
|
'callback' => [$this, 'handle_order_messages'],
|
|
'permission_callback' => [$this, 'verify_api_key'],
|
|
'args' => [
|
|
'order_id' => ['required' => true, 'validate_callback' => 'is_numeric'],
|
|
'messages' => ['required' => true],
|
|
],
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Validate Bearer token from Authorization header.
|
|
*/
|
|
public function verify_api_key(WP_REST_Request $request): bool|WP_Error {
|
|
$auth_header = $request->get_header('authorization');
|
|
if (empty($auth_header) || !str_starts_with($auth_header, 'Bearer ')) {
|
|
return new WP_Error('missing_auth', __('Authorization header missing or malformed.', 'fusion-woodoo'), ['status' => 401]);
|
|
}
|
|
|
|
$provided_key = trim(substr($auth_header, 7));
|
|
$stored_key = get_option('fusion_woodoo_api_key', '');
|
|
|
|
if (empty($stored_key) || !hash_equals($stored_key, $provided_key)) {
|
|
return new WP_Error('invalid_api_key', __('Invalid API key.', 'fusion-woodoo'), ['status' => 403]);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* POST /order/update — update order status and tracking info.
|
|
*/
|
|
public function handle_order_update(WP_REST_Request $request): WP_REST_Response|WP_Error {
|
|
$order_id = (int) $request->get_param('order_id');
|
|
$order = wc_get_order($order_id);
|
|
|
|
if (!$order) {
|
|
return new WP_Error('order_not_found', __('Order not found.', 'fusion-woodoo'), ['status' => 404]);
|
|
}
|
|
|
|
if ($status = $request->get_param('status')) {
|
|
$order->update_meta_data('_odoo_order_status', sanitize_text_field($status));
|
|
}
|
|
if ($tracking = $request->get_param('tracking_number')) {
|
|
$order->update_meta_data('_odoo_tracking_number', sanitize_text_field($tracking));
|
|
}
|
|
if ($carrier = $request->get_param('shipping_carrier')) {
|
|
$order->update_meta_data('_odoo_shipping_carrier', sanitize_text_field($carrier));
|
|
}
|
|
|
|
$order->save();
|
|
|
|
return rest_ensure_response(['success' => true, 'order_id' => $order_id]);
|
|
}
|
|
|
|
/**
|
|
* POST /order/invoice — store base64-encoded invoice PDF.
|
|
*/
|
|
public function handle_order_invoice(WP_REST_Request $request): WP_REST_Response|WP_Error {
|
|
return $this->save_pdf($request, 'invoices', '_odoo_invoice_pdf');
|
|
}
|
|
|
|
/**
|
|
* POST /order/delivery — store base64-encoded delivery PDF.
|
|
*/
|
|
public function handle_order_delivery(WP_REST_Request $request): WP_REST_Response|WP_Error {
|
|
return $this->save_pdf($request, 'deliveries', '_odoo_delivery_pdf');
|
|
}
|
|
|
|
/**
|
|
* POST /order/messages — store Odoo messages array against the order.
|
|
*/
|
|
public function handle_order_messages(WP_REST_Request $request): WP_REST_Response|WP_Error {
|
|
$order_id = (int) $request->get_param('order_id');
|
|
$order = wc_get_order($order_id);
|
|
|
|
if (!$order) {
|
|
return new WP_Error('order_not_found', __('Order not found.', 'fusion-woodoo'), ['status' => 404]);
|
|
}
|
|
|
|
$messages = $request->get_param('messages');
|
|
if (!is_array($messages)) {
|
|
return new WP_Error('invalid_messages', __('Messages must be a JSON array.', 'fusion-woodoo'), ['status' => 400]);
|
|
}
|
|
|
|
// Sanitize each message entry
|
|
$sanitized = array_map(function($msg) {
|
|
return [
|
|
'author' => sanitize_text_field($msg['author'] ?? ''),
|
|
'date' => sanitize_text_field($msg['date'] ?? ''),
|
|
'body' => wp_kses_post($msg['body'] ?? ''),
|
|
'type' => sanitize_text_field($msg['type'] ?? 'note'),
|
|
];
|
|
}, $messages);
|
|
|
|
$order->update_meta_data('_odoo_messages', $sanitized);
|
|
$order->save();
|
|
|
|
return rest_ensure_response(['success' => true, 'count' => count($sanitized)]);
|
|
}
|
|
|
|
/**
|
|
* Shared logic to decode and store a PDF file.
|
|
*/
|
|
private function save_pdf(WP_REST_Request $request, string $folder, string $meta_key): WP_REST_Response|WP_Error {
|
|
$order_id = (int) $request->get_param('order_id');
|
|
$order = wc_get_order($order_id);
|
|
|
|
if (!$order) {
|
|
return new WP_Error('order_not_found', __('Order not found.', 'fusion-woodoo'), ['status' => 404]);
|
|
}
|
|
|
|
$pdf_data = $request->get_param('pdf_data');
|
|
$decoded = base64_decode($pdf_data, true);
|
|
if ($decoded === false) {
|
|
return new WP_Error('invalid_pdf', __('Invalid base64-encoded PDF data.', 'fusion-woodoo'), ['status' => 400]);
|
|
}
|
|
|
|
$filename = $request->get_param('filename') ?: ($folder . '-' . $order_id . '-' . time() . '.pdf');
|
|
$filename = sanitize_file_name($filename);
|
|
$upload = wp_upload_dir();
|
|
$save_dir = $upload['basedir'] . '/fusion-woodoo/' . $folder . '/';
|
|
|
|
if (!file_exists($save_dir)) {
|
|
wp_mkdir_p($save_dir);
|
|
file_put_contents($save_dir . '.htaccess', 'deny from all');
|
|
}
|
|
|
|
$file_path = $save_dir . $filename;
|
|
$bytes = file_put_contents($file_path, $decoded);
|
|
|
|
if ($bytes === false) {
|
|
return new WP_Error('file_write_error', __('Could not save PDF to disk.', 'fusion-woodoo'), ['status' => 500]);
|
|
}
|
|
|
|
$relative = str_replace($upload['basedir'], '', $file_path);
|
|
$order->update_meta_data($meta_key, $relative);
|
|
$order->save();
|
|
|
|
return rest_ensure_response(['success' => true, 'path' => $relative]);
|
|
}
|
|
}
|