Skip to content

Commit

Permalink
Doctrine event support
Browse files Browse the repository at this point in the history
  • Loading branch information
lstrojny committed Feb 5, 2012
1 parent 0eda0a4 commit 7783fca
Show file tree
Hide file tree
Showing 8 changed files with 320 additions and 1 deletion.
2 changes: 2 additions & 0 deletions .gitignore
@@ -0,0 +1,2 @@
/nbproject
/vendor/doctrine2
9 changes: 8 additions & 1 deletion autoload.php
@@ -1,5 +1,12 @@
<?php
set_include_path(__DIR__ . '/src' . PATH_SEPARATOR . get_include_path());
set_include_path(
__DIR__ . '/src' . PATH_SEPARATOR
. __DIR__ . '/vendor/doctrine2/lib' . PATH_SEPARATOR
. __DIR__ . '/vendor/doctrine2/lib/vendor/doctrine-common/lib' . PATH_SEPARATOR
. __DIR__ . '/vendor/doctrine2/lib/vendor/doctrine-dbal/lib' . PATH_SEPARATOR
. __DIR__ . '/vendor/doctrine2/lib/vendor/Symfony' . PATH_SEPARATOR
. get_include_path()
);

spl_autoload_register(function($className) {
require_once strtr($className, '\\', '/') . '.php';
Expand Down
23 changes: 23 additions & 0 deletions src/Procrastinator/Deferred/DoctrineEventConditionalDeferred.php
@@ -0,0 +1,23 @@
<?php
namespace Procrastinator\Deferred;
use InvalidArgumentException;

class DoctrineEventConditionalDeferred extends CallbackDeferred
{
private $events;

public function __construct($name, $callback, $events)
{
if (!$events) {
throw new InvalidArgumentException('No events specified');
}

parent::__construct($name, $callback);
$this->events = (array) $events;
}

public function getEvents()
{
return $this->events;
}
}
@@ -0,0 +1,153 @@
<?php
namespace Procrastinator\Executor\Decorator;

use Procrastinator\Deferred\Deferred;
use Procrastinator\Deferred\DoctrineEventConditionalDeferred;
use Doctrine\Common\EventArgs;

class DoctrineEventConditionalExecutorDecorator extends ExecutorDecorator
{
private $events = array();

public function postConnect(EventArgs $args)
{
$this->rememberEvent(__FUNCTION__);
}

public function onSchemaCreateTable(EventArgs $args)
{
$this->rememberEvent(__FUNCTION__);
}

public function onSchemaCreateTableColumn(EventArgs $args)
{
$this->rememberEvent(__FUNCTION__);
}

public function onSchemaDropTable(EventArgs $args)
{
$this->rememberEvent(__FUNCTION__);
}

public function onSchemaAlterTable(EventArgs $args)
{
$this->rememberEvent(__FUNCTION__);
}

public function onSchemaAlterTableAddColumn(EventArgs $args)
{
$this->rememberEvent(__FUNCTION__);
}

public function onSchemaAlterTableRemoveColumn(EventArgs $args)
{
$this->rememberEvent(__FUNCTION__);
}

public function onSchemaAlterTableChangeColumn(EventArgs $args)
{
$this->rememberEvent(__FUNCTION__);
}

public function onSchemaAlterTableRenameColumn(EventArgs $args)
{
$this->rememberEvent(__FUNCTION__);
}

public function onSchemaColumnDefinition(EventArgs $args)
{
$this->rememberEvent(__FUNCTION__);
}

public function onSchemaIndexDefinition(EventArgs $args)
{
$this->rememberEvent(__FUNCTION__);
}

public function preRemove(EventArgs $args)
{
$this->rememberEvent(__FUNCTION__);
}

public function postRemove(EventArgs $args)
{
$this->rememberEvent(__FUNCTION__);
}

public function prePersist(EventArgs $args)
{
$this->rememberEvent(__FUNCTION__);
}

public function postPersist(EventArgs $args)
{
$this->rememberEvent(__FUNCTION__);
}

public function preUpdate(EventArgs $args)
{
$this->rememberEvent(__FUNCTION__);
}

public function postUpdate(EventArgs $args)
{
$this->rememberEvent(__FUNCTION__);
}

public function postLoad(EventArgs $args)
{
$this->rememberEvent(__FUNCTION__);
}

public function loadClassMetadata(EventArgs $args)
{
$this->rememberEvent(__FUNCTION__);
}

public function preFlush(EventArgs $args)
{
$this->rememberEvent(__FUNCTION__);
}

public function onFlush(EventArgs $args)
{
$this->rememberEvent(__FUNCTION__);
}

public function postFlush(EventArgs $args)
{
$this->rememberEvent(__FUNCTION__);
}

public function onClear(EventArgs $args)
{
$this->rememberEvent(__FUNCTION__);
}

public function execute(Deferred $deferred)
{
if (!$deferred instanceof DoctrineEventConditionalDeferred) {
parent::execute($deferred);
return;
}

foreach ($deferred->getEvents() as $event) {
if ($this->eventWasFired($event)) {
parent::execute($deferred);
break;
}
}
}

private function eventWasFired($event)
{
return in_array($event, $this->events, true);
}

private function rememberEvent($event)
{
if (!$this->eventWasFired($event)) {
$this->events[] = $event;
}
}
}
@@ -0,0 +1,35 @@
<?php
namespace Procrastinator\Deferred;

use PHPUnit_Framework_TestCase as TestCase;

class DoctrineEventConditionalDeferredTest extends TestCase
{
public function testEventsMustBeGiven()
{
$this->setExpectedException('InvalidArgumentException', 'No events specified');
new DoctrineEventConditionalDeferred('test', array($this, __FUNCTION__), null);
}

public function testEventsMustBeGiven2()
{
$this->setExpectedException('InvalidArgumentException', 'No events specified');
new DoctrineEventConditionalDeferred('test', array($this, __FUNCTION__), array());
}

public function testEventsAreCastedToArray()
{
$deferred = new DoctrineEventConditionalDeferred('test', array($this, __FUNCTION__), 'evt');
$this->assertSame(array('evt'), $deferred->getEvents());
$this->assertSame('test', $deferred->getName());
$this->assertSame(array($this, __FUNCTION__), $deferred->getCallback());
}

public function testSpecifyingMoreThanOneEventIsPossible()
{
$deferred = new DoctrineEventConditionalDeferred('test', array($this, __FUNCTION__), array('evt1', 'evt2'));
$this->assertSame(array('evt1', 'evt2'), $deferred->getEvents());
$this->assertSame('test', $deferred->getName());
$this->assertSame(array($this, __FUNCTION__), $deferred->getCallback());
}
}
@@ -0,0 +1,96 @@
<?php
namespace Procrastinator\Executor\Decorator;

namespace Procrastinator\Executor\Decorator;

use PHPUnit_Framework_TestCase as TestCase;
use Procrastinator\Deferred\CallbackDeferred;
use Doctrine\Common\EventArgs;
use ReflectionClass;

class DoctrineEventConditionalExecutorDecoratorTest extends TestCase
{
private $executor;
private $decorator;
private $executable;
private $deferred;
private $doctrineDeferred;

public function setUp()
{
if (!class_exists('Doctrine\ORM\Events')) {
$this->markTestSkipped('Doctrine not present');
}

$this->executor = $this->getMockBuilder('Procrastinator\Executor\Executor')
->getMock();
$this->decorator = new DoctrineEventConditionalExecutorDecorator($this->executor);
$this->executable = $this->getMockBuilder('Procrastinator\Executable')
->getMock();
$this->deferred = $this->getMockBuilder('Procrastinator\Deferred\Deferred')
->getMock();
$this->doctrineDeferred = $this->getMockBuilder('Procrastinator\Deferred\DoctrineEventConditionalDeferred')
->disableOriginalConstructor()
->getMock();
}

public function testStartExecutionCallsFinishRequestAndThanWrapped()
{
$this->executor->expects($this->once())->method('startExecution')->with($this->executable);
$this->decorator->startExecution($this->executable);
}

public function testEndExecutionCallsWrapped()
{
$this->executor->expects($this->once())->method('endExecution')->with($this->executable);
$this->decorator->endExecution($this->executable);
}

public function testExecuteCallsWrappedForNormalDeferreds()
{
$this->executor->expects($this->once())->method('execute')->with($this->deferred);
$this->decorator->execute($this->deferred);
}

public function testDoctrineConditionalDeferredIsNotExecutedIfEventNotFired()
{
$this->doctrineDeferred->expects($this->once())->method('getEvents')->will($this->returnValue(array('evt')));
$this->executor->expects($this->never())->method('execute');
$this->decorator->execute($this->doctrineDeferred);
}

public function provideDoctrineEvents()
{
$events = array();
$dbalEvents = new ReflectionClass('Doctrine\DBAL\Events');
foreach ($dbalEvents->getConstants() as $constant) {
$this->assertSame($constant, constant('Doctrine\DBAL\Events::' . $constant));
$events[] = $constant;
}

$ormEvents = new ReflectionClass('Doctrine\ORM\Events');
foreach ($ormEvents->getConstants() as $constant) {
$this->assertSame($constant, constant('Doctrine\ORM\Events::' . $constant));
$events[] = $constant;
}

$this->assertSame($events, array_unique($events));

foreach ($events as $k => $v) {
$events[$k] = array($v);
}

return $events;
}

/**
* @dataProvider provideDoctrineEvents
*/
public function testDoctrineConditionalDeferredIsExecutedIfEventFired($event)
{
$this->doctrineDeferred->expects($this->once())->method('getEvents')->will($this->returnValue(array('evt1', $event, 'evt2')));
$this->decorator->{$event}(EventArgs::getEmptyInstance());
$this->executor->expects($this->once())->method('execute')->with($this->doctrineDeferred);
$this->decorator->execute($this->doctrineDeferred);
}
}
3 changes: 3 additions & 0 deletions vendor.sh
@@ -0,0 +1,3 @@
#!/bin/sh
git clone -q https://github.com/doctrine/doctrine2.git vendor/doctrine2
cd vendor/doctrine2 && git submodule init && git submodule update && cd -
Empty file added vendor/.gitadd
Empty file.

0 comments on commit 7783fca

Please sign in to comment.