-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for entity listeners (#45)
* Add support for defining entity listeners * Apply fixes from StyleCI [ci skip] [skip ci]
- Loading branch information
1 parent
499147c
commit 8c3359f
Showing
6 changed files
with
317 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
<?php | ||
|
||
namespace LaravelDoctrine\Fluent\Builders; | ||
|
||
use Doctrine\ORM\Events; | ||
use Doctrine\ORM\Mapping\Builder\ClassMetadataBuilder; | ||
use InvalidArgumentException; | ||
use LaravelDoctrine\Fluent\Buildable; | ||
|
||
/** | ||
* @method EntityListeners preRemove(string $listener, string $method = null) | ||
* @method EntityListeners postRemove(string $listener, string $method = null) | ||
* @method EntityListeners prePersist(string $listener, string $method = null) | ||
* @method EntityListeners postPersist(string $listener, string $method = null) | ||
* @method EntityListeners preUpdate(string $listener, string $method = null) | ||
* @method EntityListeners postUpdate(string $listener, string $method = null) | ||
* @method EntityListeners postLoad(string $listener, string $method = null) | ||
* @method EntityListeners loadClassMetadata(string $listener, string $method = null) | ||
* @method EntityListeners onClassMetadataNotFound(string $listener, string $method = null) | ||
* @method EntityListeners preFlush(string $listener, string $method = null) | ||
* @method EntityListeners onFlush(string $listener, string $method = null) | ||
* @method EntityListeners postFlush(string $listener, string $method = null) | ||
* @method EntityListeners onClear(string $listener, string $method = null) | ||
*/ | ||
class EntityListeners implements Buildable | ||
{ | ||
/** | ||
* @var ClassMetadataBuilder | ||
*/ | ||
private $builder; | ||
|
||
/** | ||
* @var array | ||
*/ | ||
private $events = [ | ||
Events::preRemove => [], | ||
Events::postRemove => [], | ||
Events::prePersist => [], | ||
Events::postPersist => [], | ||
Events::preUpdate => [], | ||
Events::postUpdate => [], | ||
Events::postLoad => [], | ||
Events::loadClassMetadata => [], | ||
Events::onClassMetadataNotFound => [], | ||
Events::preFlush => [], | ||
Events::onFlush => [], | ||
Events::postFlush => [], | ||
Events::onClear => [], | ||
]; | ||
|
||
/** | ||
* LifecycleEvents constructor. | ||
* | ||
* @param ClassMetadataBuilder $builder | ||
*/ | ||
public function __construct(ClassMetadataBuilder $builder) | ||
{ | ||
$this->builder = $builder; | ||
} | ||
|
||
/** | ||
* Magically call all methods that match an event name. | ||
* | ||
* @param string $event | ||
* @param array $args | ||
* | ||
* @throws InvalidArgumentException | ||
* | ||
* @return LifecycleEvents | ||
*/ | ||
public function __call($event, $args) | ||
{ | ||
if (array_key_exists($event, $this->events)) { | ||
array_unshift($args, $event); | ||
|
||
return call_user_func_array([$this, 'add'], $args); | ||
} | ||
|
||
throw new InvalidArgumentException('Fluent builder method ['.$event.'] does not exist'); | ||
} | ||
|
||
/** | ||
* @param string $event | ||
* @param string $class | ||
* @param string|null $method | ||
* | ||
* @return EntityListeners | ||
*/ | ||
private function add($event, $class, $method = null) | ||
{ | ||
$this->events[$event][] = [ | ||
'class' => $class, | ||
'method' => $method ?: $event, | ||
]; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* Execute the build process. | ||
*/ | ||
public function build() | ||
{ | ||
foreach ($this->events as $event => $listeners) { | ||
foreach ($listeners as $listener) { | ||
$this->builder->getClassMetadata()->addEntityListener($event, $listener['class'], $listener['method']); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
<?php | ||
|
||
namespace Tests\Builders; | ||
|
||
use Doctrine\ORM\Events; | ||
use Doctrine\ORM\Mapping\Builder\ClassMetadataBuilder; | ||
use Doctrine\ORM\Mapping\ClassMetadataInfo; | ||
use LaravelDoctrine\Fluent\Builders\EntityListeners; | ||
use Symfony\Component\VarDumper\Cloner\Stub; | ||
use Tests\Stubs\Entities\StubEntity; | ||
use Tests\Stubs\StubEntityListener; | ||
|
||
class EntityListenersTest extends \PHPUnit_Framework_TestCase | ||
{ | ||
/** | ||
* @var EntityListeners | ||
*/ | ||
protected $builder; | ||
|
||
/** | ||
* @var ClassMetadataBuilder | ||
*/ | ||
protected $fluent; | ||
|
||
protected function setUp() | ||
{ | ||
$this->fluent = new ClassMetadataBuilder( | ||
new ClassMetadataInfo(StubEntity::class) | ||
); | ||
|
||
$this->builder = new EntityListeners($this->fluent); | ||
} | ||
|
||
/** | ||
* @dataProvider eventsProvider | ||
* | ||
* @param string $event | ||
* @param string $listener | ||
* @param string|null $method | ||
* @param string $expectedMethod | ||
*/ | ||
public function test_can_add_event_listeners($event, $listener, $method = null, $expectedMethod) | ||
{ | ||
$this->builder->{$event}($listener, $method); | ||
|
||
$this->builder->build(); | ||
|
||
$this->assertTrue( | ||
isset($this->fluent->getClassMetadata()->entityListeners[$event]) | ||
); | ||
|
||
$this->assertCount( | ||
1, $this->fluent->getClassMetadata()->entityListeners[$event] | ||
); | ||
|
||
$this->assertEquals([ | ||
[ | ||
'class' => $listener, | ||
'method' => $expectedMethod | ||
] | ||
], $this->fluent->getClassMetadata()->entityListeners[$event]); | ||
} | ||
|
||
public function test_can_add_multiple_entity_listeners_per_event() | ||
{ | ||
$this->builder | ||
->onClear(StubEntityListener::class, 'onClear') | ||
->onClear(StubEntityListener::class, 'handle'); | ||
|
||
$this->builder->build(); | ||
|
||
$this->assertTrue( | ||
isset($this->fluent->getClassMetadata()->entityListeners['onClear']) | ||
); | ||
|
||
$this->assertCount( | ||
2, $this->fluent->getClassMetadata()->entityListeners['onClear'] | ||
); | ||
|
||
$this->assertEquals([ | ||
[ | ||
'class' => StubEntityListener::class, | ||
'method' => 'onClear' | ||
], | ||
[ | ||
'class' => StubEntityListener::class, | ||
'method' => 'handle' | ||
] | ||
], $this->fluent->getClassMetadata()->entityListeners['onClear']); | ||
} | ||
|
||
/** | ||
* @return array | ||
*/ | ||
public function eventsProvider() | ||
{ | ||
return [ | ||
[Events::preRemove, StubEntityListener::class, 'preRemove', 'preRemove'], | ||
[Events::postRemove, StubEntityListener::class, 'handle', 'handle'], | ||
[Events::prePersist, StubEntityListener::class, 'handle', 'handle'], | ||
[Events::postPersist, StubEntityListener::class, 'handle', 'handle'], | ||
[Events::preUpdate, StubEntityListener::class, 'handle', 'handle'], | ||
[Events::postUpdate, StubEntityListener::class, 'handle', 'handle'], | ||
[Events::postLoad, StubEntityListener::class, 'handle', 'handle'], | ||
[Events::loadClassMetadata, StubEntityListener::class, 'handle', 'handle'], | ||
[Events::onClassMetadataNotFound, StubEntityListener::class, 'handle', 'handle'], | ||
[Events::preFlush, StubEntityListener::class, 'handle', 'handle'], | ||
[Events::onFlush, StubEntityListener::class, 'handle', 'handle'], | ||
[Events::postFlush, StubEntityListener::class, 'handle', 'handle'], | ||
[Events::onClear, StubEntityListener::class, 'handle', 'handle'], | ||
[Events::onClear, StubEntityListener::class, null, 'onClear'], | ||
]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<?php | ||
|
||
namespace Tests\Stubs; | ||
|
||
class StubEntityListener | ||
{ | ||
public function handle() | ||
{ | ||
} | ||
|
||
public function swipeFloor() | ||
{ | ||
} | ||
|
||
public function cleanToilet() | ||
{ | ||
} | ||
|
||
public function preRemove() | ||
{ | ||
} | ||
|
||
public function onClear() | ||
{ | ||
} | ||
} |