WebOrbiton
v1.0.0.1

StocketBase

100 lines · 3.9 KB
  1. <?php
  2. ​
  3. declare(strict_types=1);
  4. ​
  5. if (count(get_included_files()) === 1) {
  6. http_response_code(403);
  7. exit;
  8. }
  9. ​
  10. if (!Auth::hasRoleAtLeast(Auth::ROLE_STORE_MANAGER)) {
  11. return ['You don\'t have access to orders.', 'error', null];
  12. }
  13. ​
  14. $orderId = (int) ($_POST['order_id'] ?? 0);
  15. $allowedStatuses = ['pending', 'paid', 'processing', 'fulfilled', 'shipped', 'completed', 'canceled', 'refunded', 'failed'];
  16. $status = in_array($_POST['status'] ?? '', $allowedStatuses, true) ? $_POST['status'] : null;
  17. $trackingNumber = trim((string) ($_POST['tracking_number'] ?? ''));
  18. $trackingUrl = trim((string) ($_POST['tracking_url'] ?? ''));
  19. if ($trackingUrl !== '' && (!preg_match('#^https?://#i', $trackingUrl) || filter_var($trackingUrl, FILTER_VALIDATE_URL) === false)) {
  20. return ['The tracking link should start with http:// or https://.', 'error', $orderId > 0 ? $orderId : null];
  21. }
  22. $trackingNumber = mb_substr($trackingNumber, 0, 120);
  23. $note = mb_substr($note, 0, 2000);
  24. $note = trim((string) ($_POST['note'] ?? ''));
  25. ​
  26. if ($orderId <= 0 || $status === null) {
  27. return ['Something doesn\'t look right with that order. Please try again.', 'error', null];
  28. }
  29. ​
  30. $usersDb = Database::users();
  31. $statement = $usersDb->prepare('SELECT * FROM orders WHERE id = :id LIMIT 1');
  32. $statement->execute(['id' => $orderId]);
  33. $order = $statement->fetch();
  34. ​
  35. if (!$order) {
  36. return ['We couldn\'t find that order.', 'error', null];
  37. }
  38. ​
  39. $fulfilledAt = $order['fulfilled_at'];
  40. $shippedAt = $order['shipped_at'];
  41. if ($status === 'fulfilled' && $fulfilledAt === null) {
  42. $fulfilledAt = date('Y-m-d H:i:s');
  43. }
  44. if ($status === 'shipped' && $shippedAt === null) {
  45. $shippedAt = date('Y-m-d H:i:s');
  46. }
  47. ​
  48. $update = $usersDb->prepare(
  49. 'UPDATE orders SET status = :status, tracking_number = :tracking_number, tracking_url = :tracking_url,
  50. fulfilled_at = :fulfilled_at, shipped_at = :shipped_at, updated_at = NOW() WHERE id = :id'
  51. );
  52. $update->execute([
  53. 'status' => $status,
  54. 'tracking_number' => $trackingNumber !== '' ? $trackingNumber : null,
  55. 'tracking_url' => $trackingUrl !== '' ? $trackingUrl : null,
  56. 'fulfilled_at' => $fulfilledAt,
  57. 'shipped_at' => $shippedAt,
  58. 'id' => $orderId,
  59. ]);
  60. ​
  61. $usersDb->prepare(
  62. 'INSERT INTO order_status_history (order_id, status, note, changed_by_team_account_id) VALUES (:order_id, :status, :note, :account_id)'
  63. )->execute([
  64. 'order_id' => $orderId,
  65. 'status' => $status,
  66. 'note' => $note !== '' ? $note : null,
  67. 'account_id' => $currentUser['id'],
  68. ]);
  69. ​
  70. $notifyCustomer = isset($_POST['notify_customer']);
  71. $recipientEmail = null;
  72. if ($order['user_account_id']) {
  73. $accountStatement = $usersDb->prepare('SELECT email FROM user_accounts WHERE id = :id LIMIT 1');
  74. $accountStatement->execute(['id' => $order['user_account_id']]);
  75. $recipientEmail = $accountStatement->fetchColumn() ?: null;
  76. } else {
  77. $recipientEmail = $order['guest_email'] ?: null;
  78. }
  79. ​
  80. if ($notifyCustomer && $recipientEmail && is_file(__DIR__ . '/../includes/mailer.php') && is_file(__DIR__ . '/../includes/mail-templates.php')) {
  81. require_once __DIR__ . '/../includes/mailer.php';
  82. require_once __DIR__ . '/../includes/mail-templates.php';
  83. if (class_exists('Mailer') && class_exists('MailTemplates')) {
  84. $updatedOrder = array_merge($order, [
  85. 'status' => $status,
  86. 'tracking_number' => $trackingNumber !== '' ? $trackingNumber : null,
  87. 'tracking_url' => $trackingUrl !== '' ? $trackingUrl : null,
  88. ]);
  89. try {
  90. $email = MailTemplates::orderStatusEmail($updatedOrder, $status);
  91. Mailer::send($recipientEmail, $email['subject'], $email['html']);
  92. } catch (Throwable $mailException) {
  93. error_log('StocketBase: order status email failed — ' . $mailException->getMessage());
  94. return ['Status saved, but the email to the customer didn\'t go out.', 'error', $orderId];
  95. }
  96. }
  97. }
  98. ​
  99. return ['Status saved.', 'success', $orderId];
  100. ​