_group = new \SplStack(); $this->beginTransaction(); return; } /** * Raise an exception as a string. * * @param bool $previous Whether raise previous exception if exists. * @return string */ public function raise($previous = false) { $out = parent::raise($previous); if (0 >= count($this)) { return $out; } $out .= "\n\n" . 'Contains the following exceptions:'; foreach ($this as $exception) { $out .= "\n\n" . ' • ' . str_replace( "\n", "\n" . ' ', $exception->raise($previous) ); } return $out; } /** * Begin a transaction. * * @return \Hoa\Exception\Group */ public function beginTransaction() { $this->_group->push(new \ArrayObject()); return $this; } /** * Rollback a transaction. * * @return \Hoa\Exception\Group */ public function rollbackTransaction() { if (1 >= count($this->_group)) { return $this; } $this->_group->pop(); return $this; } /** * Commit a transaction. * * @return \Hoa\Exception\Group */ public function commitTransaction() { if (false === $this->hasUncommittedExceptions()) { $this->_group->pop(); return $this; } foreach ($this->_group->pop() as $index => $exception) { $this[$index] = $exception; } return $this; } /** * Check if there is uncommitted exceptions. * * @return bool */ public function hasUncommittedExceptions() { return 1 < count($this->_group) && 0 < count($this->_group->top()); } /** * Check if an index in the group exists. * * @param mixed $index Index. * @return bool */ public function offsetExists($index) { foreach ($this->_group as $group) { if (isset($group[$index])) { return true; } } return false; } /** * Get an exception from the group. * * @param mixed $index Index. * @return Exception */ public function offsetGet($index) { foreach ($this->_group as $group) { if (isset($group[$index])) { return $group[$index]; } } return null; } /** * Set an exception in the group. * * @param mixed $index Index. * @param Exception $exception Exception. * @return void */ public function offsetSet($index, $exception) { if (!($exception instanceof \Exception)) { return null; } $group = $this->_group->top(); if (null === $index || true === is_int($index)) { $group[] = $exception; } else { $group[$index] = $exception; } return; } /** * Remove an exception in the group. * * @param mixed $index Index. * @return void */ public function offsetUnset($index) { foreach ($this->_group as $group) { if (isset($group[$index])) { unset($group[$index]); } } return; } /** * Get committed exceptions in the group. * * @return \ArrayObject */ public function getExceptions() { return $this->_group->bottom(); } /** * Get an iterator over all exceptions (committed or not). * * @return \ArrayIterator */ public function getIterator() { return $this->getExceptions()->getIterator(); } /** * Count the number of committed exceptions. * * @return int */ public function count() { return count($this->getExceptions()); } /** * Count the stack size, i.e. the number of opened transactions. * * @return int */ public function getStackSize() { return count($this->_group); } }