| 1 |
<?php |
| 2 |
|
| 3 |
namespace ReviewX\Utilities; |
| 4 |
|
| 5 |
\defined("ABSPATH") || exit; |
| 6 |
use Exception; |
| 7 |
use Throwable; |
| 8 |
class TransactionManager |
| 9 |
{ |
| 10 |
/** |
| 11 |
* Run a task with potential rollback. |
| 12 |
* |
| 13 |
* @param callable $wpCallback Should return the data needed for SaaS or true on success. |
| 14 |
* @param callable $saasCallback Receives the result of $wpCallback. |
| 15 |
* @return mixed The SaaS response or false on failure. |
| 16 |
*/ |
| 17 |
public static function run(callable $wpCallback, callable $saasCallback) |
| 18 |
{ |
| 19 |
global $wpdb; |
| 20 |
try { |
| 21 |
// Start WP Transaction |
| 22 |
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Raw transaction start |
| 23 |
$wpdb->query('START TRANSACTION'); |
| 24 |
// 1. Perform WP updates |
| 25 |
$wpResult = $wpCallback(); |
| 26 |
if ($wpResult === \false || \is_wp_error($wpResult)) { |
| 27 |
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Raw transaction rollback |
| 28 |
$wpdb->query('ROLLBACK'); |
| 29 |
return $wpResult; |
| 30 |
} |
| 31 |
// 2. Perform SaaS updates |
| 32 |
$saasResponse = $saasCallback($wpResult); |
| 33 |
// Handle SaaS Response success check |
| 34 |
$isSuccess = \false; |
| 35 |
if (\method_exists($saasResponse, 'getStatusCode')) { |
| 36 |
$status = $saasResponse->getStatusCode(); |
| 37 |
$isSuccess = $status >= 200 && $status < 300; |
| 38 |
} |
| 39 |
if (!$isSuccess) { |
| 40 |
// SaaS failed, rollback WP |
| 41 |
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Raw transaction rollback |
| 42 |
$wpdb->query('ROLLBACK'); |
| 43 |
return $saasResponse; |
| 44 |
} |
| 45 |
// Both succeeded |
| 46 |
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Raw transaction commit |
| 47 |
$wpdb->query('COMMIT'); |
| 48 |
return $saasResponse; |
| 49 |
} catch (Throwable $e) { |
| 50 |
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Raw transaction rollback |
| 51 |
$wpdb->query('ROLLBACK'); |
| 52 |
throw $e; |
| 53 |
} |
| 54 |
} |
| 55 |
} |
| 56 |
|