dao = $dao; $this->beginStmt = $beginStmt; $this->commitStmt = $commitStmt; $this->rollbackStmt = $rollbackStmt; $this->callbacks = [ \CRM_Core_Transaction::PHASE_PRE_COMMIT => [], \CRM_Core_Transaction::PHASE_POST_COMMIT => [], \CRM_Core_Transaction::PHASE_PRE_ROLLBACK => [], \CRM_Core_Transaction::PHASE_POST_ROLLBACK => [], ]; } public function inc() { $this->refCount++; } public function dec() { $this->refCount--; } /** * @return bool */ public function isEmpty() { return ($this->refCount == 0); } /** * @return bool */ public function isRollbackOnly() { return !$this->doCommit; } public function setRollbackOnly() { $this->doCommit = FALSE; } /** * Begin frame processing. * * @throws \CRM_Core_Exception */ public function begin() { if ($this->state !== self::F_NEW) { throw new \CRM_Core_Exception('State is not F_NEW'); }; $this->state = self::F_ACTIVE; if ($this->beginStmt) { $this->dao->query($this->beginStmt); } } /** * Finish frame processing. * * @param int $newState * * @throws \CRM_Core_Exception */ public function finish($newState = self::F_DONE) { if ($this->state == self::F_FORCED) { return; } if ($this->state !== self::F_ACTIVE) { throw new \CRM_Core_Exception('State is not F_ACTIVE'); }; $this->state = $newState; if ($this->doCommit) { $this->invokeCallbacks(\CRM_Core_Transaction::PHASE_PRE_COMMIT); if ($this->commitStmt) { $this->dao->query($this->commitStmt); } $this->invokeCallbacks(\CRM_Core_Transaction::PHASE_POST_COMMIT); } else { $this->invokeCallbacks(\CRM_Core_Transaction::PHASE_PRE_ROLLBACK); if ($this->rollbackStmt) { $this->dao->query($this->rollbackStmt); } $this->invokeCallbacks(\CRM_Core_Transaction::PHASE_POST_ROLLBACK); } } public function forceRollback() { $this->setRollbackOnly(); $this->finish(self::F_FORCED); } /** * Add a transaction callback. * * Pre-condition: isActive() * * @param int $phase * A constant; one of: self::PHASE_{PRE,POST}_{COMMIT,ROLLBACK}. * @param mixed $callback * A PHP callback. * @param array|NULL $params Optional values to pass to callback. * See php manual call_user_func_array for details. * @param null $id */ public function addCallback($phase, $callback, $params = NULL, $id = NULL) { if ($id) { $this->callbacks[$phase][$id] = [ 'callback' => $callback, 'parameters' => (is_array($params) ? $params : [$params]), ]; } else { $this->callbacks[$phase][] = [ 'callback' => $callback, 'parameters' => (is_array($params) ? $params : [$params]), ]; } } /** * @param int $phase */ public function invokeCallbacks($phase) { if (is_array($this->callbacks[$phase])) { foreach ($this->callbacks[$phase] as $cb) { call_user_func_array($cb['callback'], $cb['parameters']); } } } }