Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 26 additions & 3 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ jobs:
strategy:
matrix:
php-versions: ['8.3', '8.4']
name: PHP ${{ matrix.php-versions }}
doctrine-orm: ['^2.19.7', '^3.0']
name: PHP ${{ matrix.php-versions }} / doctrine/orm ${{ matrix.doctrine-orm }}
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
Expand All @@ -26,12 +27,34 @@ jobs:
- uses: actions/cache@v4
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-
key: ${{ runner.os }}-composer-${{ matrix.doctrine-orm }}-${{ hashFiles('**/composer.json') }}
restore-keys: ${{ runner.os }}-composer-${{ matrix.doctrine-orm }}-
- name: Require doctrine/orm ${{ matrix.doctrine-orm }}
run: composer require doctrine/orm:${{ matrix.doctrine-orm }} --no-update
- name: composer install
run: composer install --no-progress --prefer-dist --optimize-autoloader
- run: sudo /etc/init.d/mysql start
- name: phpunit
run: php vendor/bin/phpunit

phpcs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with:
php-version: '8.3'
- name: Get composer cache directory
id: composer-cache
run: |
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- uses: actions/cache@v4
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
restore-keys: ${{ runner.os }}-composer-
- name: composer install
run: composer install --no-progress --prefer-dist --optimize-autoloader
- name: phpcs
run: php vendor/bin/phpcs
11 changes: 8 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,24 @@
"minimum-stability": "stable",
"require": {
"php": "^8.3",
"doctrine/collections": "^1.8.0|^2.2",
"doctrine/common": "^3.4.4",
"doctrine/event-manager": "^1.2|^2.0",
"doctrine/orm": "^2.19.7",
"doctrine/orm": "^2.19.7|^3.0",
"doctrine/persistence": "^2.5.7|^3.4.0",
"psr/log": "^1.0.0|^2.0.0|^3.0.0",
"symfony/cache": "^6.4|^7.4"
},
"require-dev": {
"hostnet/database-test-lib": "^2.0.2",
"hostnet/phpcs-tool": "^9.1.0",
"doctrine/dbal": "^3.2|^4.0",
"hostnet/database-test-lib": "^2.0.6",
"hostnet/phpcs-tool": "^9.1.5",
"phpspec/prophecy-phpunit": "^2.5.0",
"phpunit/phpunit": "^9.4"
},
"conflict": {
"symfony/var-exporter": ">=8.0"
},
"autoload": {
"psr-4": {
"Hostnet\\Component\\EntityTracker\\": "src/"
Expand Down
7 changes: 3 additions & 4 deletions src/Listener/EntityChangedListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@

namespace Hostnet\Component\EntityTracker\Listener;

use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Event\PreFlushEventArgs;
use Doctrine\Persistence\ObjectManager;
use Doctrine\Persistence\Proxy;
use Hostnet\Component\EntityTracker\Attributes\Tracked;
use Hostnet\Component\EntityTracker\Event\EntityChangedEvent;
use Hostnet\Component\EntityTracker\Events;
Expand Down Expand Up @@ -37,7 +36,7 @@ public function __construct(
$this->logger = $logger ? : new NullLogger();
}

private function isTracked(ObjectManager $em, object $entity): bool
private function isTracked(EntityManagerInterface $em, object $entity): bool
{
$cache_key = base64_encode('TRACKED-' . get_class($entity));
$cached_item = $this->is_tracked_cache->getItem($cache_key);
Expand Down Expand Up @@ -86,7 +85,7 @@ public function preFlush(PreFlushEventArgs $event): void
}

foreach ($updates as $entity) {
if ($entity instanceof Proxy && !$entity->__isInitialized()) {
if ($em->getUnitOfWork()->isUninitializedObject($entity)) {
continue;
}

Expand Down
5 changes: 2 additions & 3 deletions src/Provider/EntityMutationMetadataProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
use Doctrine\ORM\PersistentCollection;
use Doctrine\ORM\UnitOfWork;
use Psr\Log\LoggerInterface;
Expand Down Expand Up @@ -68,11 +67,11 @@ public function getMutatedFields(EntityManagerInterface $em, object $entity, ?ob
$associations = [];

foreach ($metadata->getAssociationMappings() as $name => $mapping) {
if ($mapping['type'] === ClassMetadataInfo::ONE_TO_ONE && !$mapping['isOwningSide']) {
if ($mapping['type'] === ClassMetadata::ONE_TO_ONE && !$mapping['isOwningSide']) {
continue;
}

if ($mapping['type'] & ClassMetadataInfo::TO_MANY) {
if ($mapping['type'] & ClassMetadata::TO_MANY) {
continue;
}
$associations[] = $name;
Expand Down
28 changes: 19 additions & 9 deletions test/Listener/EntityChangedListenerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use Doctrine\Common\EventManager;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Event\PreFlushEventArgs;
use Doctrine\Persistence\Proxy;
use Doctrine\ORM\UnitOfWork;
use Hostnet\Component\EntityTracker\Attributes\Tracked;
use Hostnet\Component\EntityTracker\Event\EntityChangedEvent;
use Hostnet\Component\EntityTracker\Events;
Expand All @@ -33,6 +33,7 @@ class EntityChangedListenerTest extends TestCase
private $meta_mutation_provider;
private $event_manager;
private $em;
private $unit_of_work;
private $logger;
private $event;

Expand All @@ -46,11 +47,13 @@ protected function setUp(): void
$this->meta_provider = $this->prophesize(EntityMetadataProvider::class);
$this->meta_mutation_provider = $this->prophesize(EntityMutationMetadataProvider::class);
$this->em = $this->prophesize(EntityManagerInterface::class);
$this->unit_of_work = $this->prophesize(UnitOfWork::class);
$this->event = $this->prophesize(PreFlushEventArgs::class);
$this->event_manager = $this->prophesize(EventManager::class);
$this->logger = $this->prophesize(LoggerInterface::class);

$this->em->getEventManager()->willReturn($this->event_manager->reveal());
$this->em->getUnitOfWork()->willReturn($this->unit_of_work->reveal());

$this->listener = new EntityChangedListener(
$this->meta_provider->reveal(),
Expand Down Expand Up @@ -93,6 +96,7 @@ public function testPreFlushUnmanaged(): void
$this->meta_provider
->getAttributeFromEntity(Argument::any(), $this->em->reveal(), $entity)
->willReturn(new Tracked());
$this->unit_of_work->isUninitializedObject($entity)->willReturn(false);
$this->logger->debug(Argument::cetera())->shouldBeCalled();
$this->meta_mutation_provider->isEntityManaged($this->em->reveal(), $entity)->willReturn(true);
$this->meta_mutation_provider->createOriginalEntity($this->em->reveal(), $entity)->willReturn(null);
Expand All @@ -118,6 +122,7 @@ public function testPreFlushWithoutMutatedFields(): void
$this->meta_provider
->getAttributeFromEntity(Argument::any(), $this->em->reveal(), $entity)
->willReturn(new Tracked());
$this->unit_of_work->isUninitializedObject($entity)->willReturn(false);
$this->meta_mutation_provider->isEntityManaged($this->em->reveal(), $entity)->willReturn(true);
$this->meta_mutation_provider->createOriginalEntity($this->em->reveal(), $entity)->willReturn($original);
$this->meta_mutation_provider->getMutatedFields($this->em->reveal(), $entity, $entity)->willReturn([]);
Expand All @@ -138,6 +143,7 @@ public function testPreFlushWithMutatedFields(): void
$this->meta_provider
->getAttributeFromEntity(Argument::any(), $this->em->reveal(), $entity)
->willReturn(new Tracked());
$this->unit_of_work->isUninitializedObject($entity)->willReturn(false);
$this->logger->debug(Argument::cetera())->shouldBeCalled();
$this->meta_mutation_provider->isEntityManaged($this->em->reveal(), $entity)->willReturn(true);
$this->meta_mutation_provider->createOriginalEntity($this->em->reveal(), $entity)->willReturn($original);
Expand All @@ -159,6 +165,7 @@ public function testPreFlushWithNewAttributedEntity(): void
$this->meta_provider
->getAttributeFromEntity(Tracked::class, $this->em->reveal(), $entity)
->willReturn(new Tracked())->shouldBeCalled();
$this->unit_of_work->isUninitializedObject($entity)->willReturn(false);
$this->logger->debug(Argument::cetera())->shouldBeCalled();
$this->meta_mutation_provider->isEntityManaged($this->em->reveal(), $entity)->willReturn(true);
$this->meta_mutation_provider->createOriginalEntity($this->em->reveal(), $entity)->willReturn(null);
Expand Down Expand Up @@ -186,6 +193,8 @@ public function testPreFlushWithNewEntityCached(): void
$this->meta_provider
->getAttributeFromEntity(Tracked::class, $this->em->reveal(), $entity)
->willReturn(new Tracked())->shouldBeCalledTimes(1);
$this->unit_of_work->isUninitializedObject($entity)->willReturn(false);
$this->unit_of_work->isUninitializedObject($entity_2nd_flush)->willReturn(false);
$this->event_manager
->dispatchEvent(Events::ENTITY_CHANGED, Argument::type(EntityChangedEvent::class))
->shouldBeCalledTimes(2);
Expand All @@ -194,9 +203,9 @@ public function testPreFlushWithNewEntityCached(): void
$this->listener->preFlush(new PreFlushEventArgs($this->em->reveal()));
}

public function testPreFlushWithProxy(): void
public function testPreFlushWithUninitializedEntity(): void
{
$entity = $this->prophesize(Proxy::class)->reveal();
$entity = new \stdClass();
$this->meta_mutation_provider
->getFullChangeSet($this->em->reveal())
->willReturn($this->genericEntityDataProvider($entity));
Expand All @@ -206,28 +215,29 @@ public function testPreFlushWithProxy(): void
$this->meta_provider
->getAttributeFromEntity(Argument::any(), $this->em->reveal(), $entity)
->willReturn(new Tracked());
$this->unit_of_work->isUninitializedObject($entity)->willReturn(true);
$this->meta_mutation_provider->isEntityManaged($this->em->reveal(), $entity)->willReturn(true);
$this->listener->preFlush(new PreFlushEventArgs($this->em->reveal()));
}

public function testPreFlushWithInitializedProxy(): void
public function testPreFlushWithInitializedEntity(): void
{
$original = new \stdClass();
$original->id = 0;

$entity = $this->prophesize(Proxy::class);
$entity = new \stdClass();
$this->meta_mutation_provider
->getFullChangeSet($this->em->reveal())
->willReturn($this->genericEntityDataProvider($entity->reveal()));
->willReturn($this->genericEntityDataProvider($entity));
$this->meta_provider
->getAttributeFromEntity(Argument::any(), $this->em->reveal(), $entity)
->willReturn(new Tracked());
$this->meta_mutation_provider->isEntityManaged($this->em->reveal(), $entity->reveal())->willReturn(true);
$entity->__isInitialized()->willReturn(true);
$this->meta_mutation_provider->isEntityManaged($this->em->reveal(), $entity)->willReturn(true);
$this->unit_of_work->isUninitializedObject($entity)->willReturn(false);
$this->logger->debug(Argument::cetera())->shouldBeCalled();
$this->meta_mutation_provider->createOriginalEntity($this->em->reveal(), $entity)->willReturn($original);
$this->meta_mutation_provider
->getMutatedFields($this->em->reveal(), $entity->reveal(), $original)
->getMutatedFields($this->em->reveal(), $entity, $original)
->willReturn(['id']);

$this->event_manager
Expand Down
Loading