From b55bc593f9b229feb18982b26e032e830299c4f4 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Thu, 20 Mar 2014 22:44:47 -0700 Subject: [PATCH] CRM-14370 - API Kernel - Extract TransactionSubscriber --- Civi/API/Kernel.php | 14 ---- Civi/API/Subscriber/TransactionSubscriber.php | 80 +++++++++++++++++++ Civi/Core/Container.php | 1 + 3 files changed, 81 insertions(+), 14 deletions(-) create mode 100644 Civi/API/Subscriber/TransactionSubscriber.php diff --git a/Civi/API/Kernel.php b/Civi/API/Kernel.php index 8d982e1983..310fe8a917 100644 --- a/Civi/API/Kernel.php +++ b/Civi/API/Kernel.php @@ -99,11 +99,6 @@ class Kernel { $apiRequest = $this->dispatcher->dispatch(Events::PREPARE, new PrepareEvent(NULL, $apiRequest))->getApiRequest(); - if (strtolower($action) == 'create' || strtolower($action) == 'delete' || strtolower($action) == 'submit') { - $apiRequest['is_transactional'] = 1; - $transaction = new \CRM_Core_Transaction(); - } - // support multi-lingual requests if ($language = \CRM_Utils_Array::value('option.language', $params)) { _civicrm_api_set_locale($language); @@ -202,9 +197,6 @@ class Kernel { $data['tip'] = "add debug=1 to your API call to have more info about the error"; } $err = civicrm_api3_create_error($e->getMessage(), $data, $apiRequest); - if (!empty($apiRequest['is_transactional'])) { - $transaction->rollback(); - } $this->dispatcher->dispatch(Events::EXCEPTION, new ExceptionEvent($e, NULL, $apiRequest)); return $err; } @@ -224,9 +216,6 @@ class Kernel { ) { $err['trace'] = $e->getTraceAsString(); } - if (!empty($apiRequest['is_transactional'])) { - $transaction->rollback(); - } $this->dispatcher->dispatch(Events::EXCEPTION, new ExceptionEvent($e, NULL, $apiRequest)); return $err; } @@ -239,9 +228,6 @@ class Kernel { if (!empty($apiRequest['params']['debug'])) { $err['trace'] = $e->getTraceAsString(); } - if (!empty($apiRequest['is_transactional'])) { - $transaction->rollback(); - } $this->dispatcher->dispatch(Events::EXCEPTION, new ExceptionEvent($e, NULL, $apiRequest)); return $err; } diff --git a/Civi/API/Subscriber/TransactionSubscriber.php b/Civi/API/Subscriber/TransactionSubscriber.php new file mode 100644 index 0000000000..050058ef02 --- /dev/null +++ b/Civi/API/Subscriber/TransactionSubscriber.php @@ -0,0 +1,80 @@ + array('onApiPrepare', Events::W_EARLY), + Events::RESPOND => array('onApiRespond', Events::W_MIDDLE), + Events::EXCEPTION => array('onApiException', Events::W_EARLY), + ); + } + + /** + * @var array<\CRM_Core_Transaction> + */ + private $stack = array(); + + /** + * Open a new transaction instance (if appropriate in the current policy) + * + * @param \Civi\API\Event\Event $event + */ + function onApiPrepare(\Civi\API\Event\Event $event) { + $apiRequest = $event->getApiRequest(); + if (strtolower($apiRequest['action']) == 'create' || strtolower($apiRequest['action']) == 'delete' || strtolower($apiRequest['action']) == 'submit') { + $apiRequest['is_transactional'] = 1; + + $this->stack[] = new \CRM_Core_Transaction(); + } else { + $this->stack[] = NULL; + } + } + + /** + * Close any pending transactions + */ + function onApiRespond() { + array_pop($this->stack); + } + + /** + * Rollback the pending transaction + * + * @param \Civi\API\Event\ExceptionEvent $event + */ + function onApiException(\Civi\API\Event\ExceptionEvent $event) { + $transaction = array_pop($this->stack); + if ($transaction !== NULL) { + $transaction->rollback(); + } + } +} \ No newline at end of file diff --git a/Civi/Core/Container.php b/Civi/Core/Container.php index 98b69a813d..954c5ef2e5 100644 --- a/Civi/Core/Container.php +++ b/Civi/Core/Container.php @@ -86,6 +86,7 @@ class Container { * @return \Civi\API\Kernel */ public function createApiKernel($dispatcher) { + $dispatcher->addSubscriber(new \Civi\API\Subscriber\TransactionSubscriber()); $dispatcher->addListener(\Civi\API\Events::AUTHORIZE, function($event) { // dummy placeholder $event->authorize(); -- 2.25.1