Skip to content

Commit

Permalink
Make:entity dispatches event with incomplete argument
Browse files Browse the repository at this point in the history
Resolves issue KnpLabs#481 by checking for a null reflection class pointer before
using the pointer, in each of the event subscribers.
  • Loading branch information
Edward Barnard committed Jan 19, 2020
1 parent 0259a78 commit 060fc53
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/vendor
composer.lock

.idea
.phpunit.result.cache

config/secrets/*
4 changes: 4 additions & 0 deletions src/EventSubscriber/BlameableSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ public function __construct(
public function loadClassMetadata(LoadClassMetadataEventArgs $loadClassMetadataEventArgs): void
{
$classMetadata = $loadClassMetadataEventArgs->getClassMetadata();
if ($classMetadata->reflClass === null) {
// Class has not yet been fully built, ignore this event
return;
}

if (! is_a($classMetadata->reflClass->getName(), BlameableInterface::class, true)) {
return;
Expand Down
4 changes: 4 additions & 0 deletions src/EventSubscriber/SoftDeletableSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ public function onFlush(OnFlushEventArgs $onFlushEventArgs): void
public function loadClassMetadata(LoadClassMetadataEventArgs $loadClassMetadataEventArgs): void
{
$classMetadata = $loadClassMetadataEventArgs->getClassMetadata();
if ($classMetadata->reflClass === null) {
// Class has not yet been fully built, ignore this event
return;
}

if (! is_a($classMetadata->reflClass->getName(), SoftDeletableInterface::class, true)) {
return;
Expand Down
5 changes: 5 additions & 0 deletions src/EventSubscriber/TimestampableSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ public function __construct(EntityManagerInterface $entityManager)
public function loadClassMetadata(LoadClassMetadataEventArgs $loadClassMetadataEventArgs): void
{
$classMetadata = $loadClassMetadataEventArgs->getClassMetadata();
if ($classMetadata->reflClass === null) {
// Class has not yet been fully built, ignore this event
return;
}

if (! is_a($classMetadata->reflClass->getName(), TimestampableInterface::class, true)) {
return;
}
Expand Down
4 changes: 4 additions & 0 deletions src/EventSubscriber/TranslatableSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ public function __construct(
public function loadClassMetadata(LoadClassMetadataEventArgs $loadClassMetadataEventArgs): void
{
$classMetadata = $loadClassMetadataEventArgs->getClassMetadata();
if ($classMetadata->reflClass === null) {
// Class has not yet been fully built, ignore this event
return;
}

if ($classMetadata->isMappedSuperclass) {
return;
Expand Down
4 changes: 4 additions & 0 deletions src/EventSubscriber/TreeSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ final class TreeSubscriber implements EventSubscriber
public function loadClassMetadata(LoadClassMetadataEventArgs $loadClassMetadataEventArgs): void
{
$classMetadata = $loadClassMetadataEventArgs->getClassMetadata();
if ($classMetadata->reflClass === null) {
// Class has not yet been fully built, ignore this event
return;
}

if (! is_a($classMetadata->reflClass->getName(), TreeNodeInterface::class, true)) {
return;
Expand Down
4 changes: 4 additions & 0 deletions src/EventSubscriber/UuidableSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ final class UuidableSubscriber implements EventSubscriber
public function loadClassMetadata(LoadClassMetadataEventArgs $loadClassMetadataEventArgs): void
{
$classMetadata = $loadClassMetadataEventArgs->getClassMetadata();
if ($classMetadata->reflClass === null) {
// Class has not yet been fully built, ignore this event
return;
}

if (! is_a($classMetadata->reflClass->getName(), UuidableInterface::class, true)) {
return;
Expand Down
37 changes: 37 additions & 0 deletions tests/ORM/TimestampableMakeEntityTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

namespace Knp\DoctrineBehaviors\Tests\ORM;

use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
use Doctrine\ORM\Events;
use Doctrine\ORM\Mapping\ClassMetadata;
use Knp\DoctrineBehaviors\Tests\AbstractBehaviorTestCase;

/**
* When console make:entity creates a new class, the event arguments are not fully populated
*
* This test emulates the event dispatch near the end of method
* Doctrine\ORM\Mapping\ClassMetadataFactory::doLoadMetadata()
*
* @property EntityManager $entityManager
*/
final class TimestampableMakeEntityTest extends AbstractBehaviorTestCase
{
public function testMakeEntityEmptyEvent(): void
{
$className = 'App\Entity\MyClass';
$class = new ClassMetadata($className);
$eventArgs = new LoadClassMetadataEventArgs($class, $this->entityManager);
$doctrineEventManager = $this->entityManager->getEventManager();
$doctrineEventManager->dispatchEvent(Events::loadClassMetadata, $eventArgs);
$this->expectNotToPerformAssertions();
}

protected function provideCustomConfig(): ?string
{
return __DIR__ . '/../config/config_test_with_timestampable_entity.yaml';
}
}
26 changes: 26 additions & 0 deletions tests/config/config_test_with_timestampable_entity.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
services:
_defaults:
public: true
autowire: true

Knp\DoctrineBehaviors\EventSubscriber\BlameableSubscriber:
tags:
- { name: 'doctrine.event_subscriber' }
Knp\DoctrineBehaviors\EventSubscriber\LoggableSubscriber:
tags:
- { name: 'doctrine.event_subscriber' }
Knp\DoctrineBehaviors\EventSubscriber\SluggableSubscriber:
tags:
- { name: 'doctrine.event_subscriber' }
Knp\DoctrineBehaviors\EventSubscriber\SoftDeletableSubscriber:
tags:
- { name: 'doctrine.event_subscriber' }
Knp\DoctrineBehaviors\EventSubscriber\TimestampableSubscriber:
tags:
- { name: 'doctrine.event_subscriber' }
Knp\DoctrineBehaviors\EventSubscriber\TreeSubscriber:
tags:
- { name: 'doctrine.event_subscriber' }
Knp\DoctrineBehaviors\EventSubscriber\UuidableSubscriber:
tags:
- { name: 'doctrine.event_subscriber' }

0 comments on commit 060fc53

Please sign in to comment.