diff --git a/lib/Doctrine/ORM/EntityManager.php b/lib/Doctrine/ORM/EntityManager.php index 0679ce85b..d8ef431ab 100644 --- a/lib/Doctrine/ORM/EntityManager.php +++ b/lib/Doctrine/ORM/EntityManager.php @@ -19,7 +19,7 @@ namespace Doctrine\ORM; -use Closure, Exception, +use Exception, Doctrine\Common\EventManager, Doctrine\Common\Persistence\ObjectManager, Doctrine\DBAL\Connection, @@ -210,15 +210,19 @@ class EntityManager implements ObjectManager * If an exception occurs during execution of the function or flushing or transaction commit, * the transaction is rolled back, the EntityManager closed and the exception re-thrown. * - * @param Closure $func The function to execute transactionally. + * @param callable $func The function to execute transactionally. * @return mixed Returns the non-empty value returned from the closure or true instead */ - public function transactional(Closure $func) + public function transactional($func) { + if (!is_callable($func)) { + throw new \InvalidArgumentException('Expected argument of type "callable", got "' . gettype($func) . '"'); + } + $this->conn->beginTransaction(); try { - $return = $func($this); + $return = call_user_func($func, $this); $this->flush(); $this->conn->commit(); diff --git a/tests/Doctrine/Tests/ORM/EntityManagerTest.php b/tests/Doctrine/Tests/ORM/EntityManagerTest.php index 4c4787763..7de921359 100644 --- a/tests/Doctrine/Tests/ORM/EntityManagerTest.php +++ b/tests/Doctrine/Tests/ORM/EntityManagerTest.php @@ -155,4 +155,21 @@ class EntityManagerTest extends \Doctrine\Tests\OrmTestCase $this->assertEquals('foo', $return); } -} \ No newline at end of file + + public function testTransactionalAcceptsVariousCallables() + { + $this->assertSame('callback', $this->_em->transactional(array($this, 'transactionalCallback'))); + } + + public function testTransactionalThrowsInvalidArgumentExceptionIfNonCallablePassed() + { + $this->setExpectedException('InvalidArgumentException', 'Expected argument of type "callable", got "object"'); + $this->_em->transactional($this); + } + + public function transactionalCallback($em) + { + $this->assertSame($this->_em, $em); + return 'callback'; + } +}