/** * Roll back the Transaction * * It will execute the `down`action of the succeeded commands * or all if no exception has been thrown during the begin method. * * @param mixed $offset Allows to set the starting command * * @return mixed Returns the result of the last hook/command */ public function rollback($offset = null) { $this->_init(); $previous_return = null; $commands = array_reverse($this->commands, true); $offset = $offset ?: $this->offset_error; $start_rollback = is_null($offset) ? true : false; foreach ($commands as $index => $command) { if (!$start_rollback && $offset == $index) { $start_rollback = true; continue; } try { if (!$command->isEnabled() || !$start_rollback) { continue; } // pre hook $previous_return = $this->executeHooks(self::HOOK_PRE, self::DIRECTION_DOWN, $previous_return, $command); $previous_return = $command->runDown($previous_return); // post hook $previous_return = $this->executeHooks(self::HOOK_POST, self::DIRECTION_DOWN, $previous_return, $command); } catch (\Exception $e) { $ie = new TransactionException($e->getMessage(), $e->getCode()); $ie->setCommand($command); $ie->setDirection(self::DIRECTION_DOWN); throw $ie; } if ($this->offset_start == $index) { break; } } return $previous_return; }