Skip to content

Commit

Permalink
Avoid Symfony 5.1 deprecations (#95)
Browse files Browse the repository at this point in the history
This involves the event dispatcher.
  • Loading branch information
Jean85 authored Jun 12, 2020
1 parent 543971a commit 2ffbb5b
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 55 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ jobs:
- stage: "Analysis"
name: "phpstan"
script:
- docker-compose run --no-deps --rm php bin/phpstan analyze -l7 src/ tests/
- docker-compose run --no-deps --rm php bin/phpstan analyze --memory-limit -l7 src/ tests/

- stage: "Analysis"
name: "cs-check"
Expand Down
6 changes: 3 additions & 3 deletions src/Capsule/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@

namespace Facile\MongoDbBundle\Capsule;

use Facile\MongoDbBundle\Event\EventDispatcherCheck;
use Facile\MongoDbBundle\Event\QueryEvent;
use Facile\MongoDbBundle\Models\Query;
use MongoDB\Collection as MongoCollection;
use MongoDB\Driver\Manager;
use MongoDB\Driver\ReadPreference;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy;

/**
* Class Collection.
Expand Down Expand Up @@ -221,7 +221,7 @@ private function prepareQuery(string $method, $filters = null, $data = null, arr
);

$event = new QueryEvent($query);
if (class_exists(LegacyEventDispatcherProxy::class)) {
if (EventDispatcherCheck::isPSR14Compliant()) {
$this->eventDispatcher->dispatch($event, QueryEvent::QUERY_PREPARED);
} else {
$this->eventDispatcher->dispatch(QueryEvent::QUERY_PREPARED, $event);
Expand Down Expand Up @@ -261,7 +261,7 @@ private function notifyQueryExecution(Query $queryLog)
$queryLog->setExecutionTime(microtime(true) - $queryLog->getStart());

$event = new QueryEvent($queryLog);
if (class_exists(LegacyEventDispatcherProxy::class)) {
if (EventDispatcherCheck::isPSR14Compliant()) {
$this->eventDispatcher->dispatch($event, QueryEvent::QUERY_EXECUTED);
} else {
$this->eventDispatcher->dispatch(QueryEvent::QUERY_EXECUTED, $event);
Expand Down
17 changes: 17 additions & 0 deletions src/DependencyInjection/MongoDbBundleExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Facile\MongoDbBundle\DependencyInjection;

use Facile\MongoDbBundle\Event\ConnectionEvent;
use Facile\MongoDbBundle\Event\EventDispatcherCheck;
use Facile\MongoDbBundle\Event\QueryEvent;
use Facile\MongoDbBundle\Services\ClientRegistry;
use Facile\MongoDbBundle\Services\ConnectionFactory;
Expand All @@ -16,6 +17,8 @@
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;

/**
Expand All @@ -34,6 +37,7 @@ public function load(array $configs, ContainerBuilder $container)
$loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
$loader->load('services.xml');

$this->decorateEventDispatcher($container);
$this->defineClientRegistry($config, $container->getParameter('kernel.debug'));
$this->defineConnectionFactory();
$this->defineConnections($config['connections']);
Expand Down Expand Up @@ -118,4 +122,17 @@ private function defineDriverOptionsFactory(array $config)
{
return isset($config['driverOptions']) ? new Reference($config['driverOptions']) : null;
}

/**
* This is needed to avoid the EventDispatcher deprecation from 4.3
*/
private function decorateEventDispatcher(): void
{
if (EventDispatcherCheck::shouldUseLegacyProxy()) {
$definition = $this->containerBuilder->getDefinition('facile_mongo_db.event_dispatcher');
$definition->setClass(LegacyEventDispatcherProxy::class);
$definition->setFactory([LegacyEventDispatcherProxy::class, 'decorate']);
$definition->setArguments([new Definition(EventDispatcher::class)]);
}
}
}
23 changes: 23 additions & 0 deletions src/Event/EventDispatcherCheck.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace Facile\MongoDbBundle\Event;

use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy;

/**
* This class provides the checks needed to avoid the EventDispatcher deprecations from 4.3
* The Event class has been removed in Symfony 5, so its absence is used as a trigger to stop using the LegacyEventDispatcherProxy.
*/
class EventDispatcherCheck
{
public static function isPSR14Compliant(): bool
{
return ! class_exists(Event::class) || class_exists(LegacyEventDispatcherProxy::class);
}

public static function shouldUseLegacyProxy(): bool
{
return class_exists(Event::class) && class_exists(LegacyEventDispatcherProxy::class);
}
}
4 changes: 2 additions & 2 deletions src/Services/ClientRegistry.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@

use Facile\MongoDbBundle\Capsule\Client as BundleClient;
use Facile\MongoDbBundle\Event\ConnectionEvent;
use Facile\MongoDbBundle\Event\EventDispatcherCheck;
use Facile\MongoDbBundle\Models\ClientConfiguration;
use Facile\MongoDbBundle\Services\DriverOptions\DriverOptionsInterface;
use MongoDB\Client;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy;

/**
* Class ClientRegistry.
Expand Down Expand Up @@ -162,7 +162,7 @@ public function getClient(string $name, string $databaseName = null): Client
$this->clients[$clientKey] = $this->buildClient($name, $conf->getUri(), $options, $conf->getDriverOptions());

$event = new ConnectionEvent($clientKey);
if (class_exists(LegacyEventDispatcherProxy::class)) {
if (EventDispatcherCheck::isPSR14Compliant()) {
$this->eventDispatcher->dispatch($event, ConnectionEvent::CLIENT_CREATED);
} else {
$this->eventDispatcher->dispatch(ConnectionEvent::CLIENT_CREATED, $event);
Expand Down
96 changes: 49 additions & 47 deletions tests/Functional/Capsule/CollectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

declare(strict_types=1);

namespace Facile\MongoDbBundle\Tests\Functional\Capsule;

use Facile\MongoDbBundle\Capsule\Collection;
use Facile\MongoDbBundle\Event\EventDispatcherCheck;
use Facile\MongoDbBundle\Event\QueryEvent;
use Facile\MongoDbBundle\Tests\Functional\AppTestCase;
use MongoDB\Driver\Manager;
Expand All @@ -25,119 +28,109 @@ private function getManager(): Manager
public function test_construction()
{
$manager = $this->getManager();
$ev = self::prophesize(EventDispatcherInterface::class);
$ev = $this->mockEventDispatcher(0);

$coll = new Collection($manager, 'test_client', 'testdb', 'test_collection', [], $ev->reveal());
$coll = new Collection($manager, 'test_client', 'testdb', 'test_collection', [], $ev);

self::assertInstanceOf(\MongoDB\Collection::class, $coll);
}

public function test_insertOne()
{
$manager = $this->getManager();
$ev = self::prophesize(EventDispatcherInterface::class);
$this->assertEventsDispatching($ev);
$ev = $this->mockEventDispatcher(1);

$coll = new Collection($manager, 'test_client', 'testdb', 'test_collection', [], $ev->reveal());
$coll = new Collection($manager, 'test_client', 'testdb', 'test_collection', [], $ev);

$coll->insertOne(['test' => 1]);
}

public function test_updateOne()
{
$manager = $this->getManager();
$ev = self::prophesize(EventDispatcherInterface::class);
$this->assertEventsDispatching($ev);
$ev = $this->mockEventDispatcher(1);

$coll = new Collection($manager, 'test_client', 'testdb', 'test_collection', [], $ev->reveal());
$coll = new Collection($manager, 'test_client', 'testdb', 'test_collection', [], $ev);

$coll->updateOne(['filter' => 1], ['$set' => ['testField' => 1]]);
}

public function test_count()
{
$manager = $this->getManager();
$ev = self::prophesize(EventDispatcherInterface::class);
$this->assertEventsDispatching($ev);
$ev = $this->mockEventDispatcher(1);

$coll = new Collection($manager, 'test_client', 'testdb', 'test_collection', [], $ev->reveal());
$coll = new Collection($manager, 'test_client', 'testdb', 'test_collection', [], $ev);

$coll->count(['test' => 1]);
}

public function test_find()
{
$manager = $this->getManager();
$ev = self::prophesize(EventDispatcherInterface::class);
$this->assertEventsDispatching($ev);
$ev = $this->mockEventDispatcher(1);

$coll = new Collection($manager, 'test_client', 'testdb', 'test_collection', [], $ev->reveal());
$coll = new Collection($manager, 'test_client', 'testdb', 'test_collection', [], $ev);

$coll->find([]);
}

public function test_findOne()
{
$manager = $this->getManager();
$ev = self::prophesize(EventDispatcherInterface::class);
$this->assertEventsDispatching($ev);
$ev = $this->mockEventDispatcher(1);

$coll = new Collection($manager, 'test_client', 'testdb', 'test_collection', [], $ev->reveal());
$coll = new Collection($manager, 'test_client', 'testdb', 'test_collection', [], $ev);

$coll->findOne([]);
}

public function test_findOneAndUpdate()
{
$manager = $this->getManager();
$ev = self::prophesize(EventDispatcherInterface::class);
$this->assertEventsDispatching($ev);
$ev = $this->mockEventDispatcher(1);

$coll = new Collection($manager, 'test_client', 'testdb', 'test_collection', [], $ev->reveal());
$coll = new Collection($manager, 'test_client', 'testdb', 'test_collection', [], $ev);

$coll->findOneAndUpdate([], ['$set' => ['country' => 'us']]);
}

public function test_findOneAndDelete()
{
$manager = $this->getManager();
$ev = self::prophesize(EventDispatcherInterface::class);
$this->assertEventsDispatching($ev);
$ev = $this->mockEventDispatcher(1);

$coll = new Collection($manager, 'test_client', 'testdb', 'test_collection', [], $ev->reveal());
$coll = new Collection($manager, 'test_client', 'testdb', 'test_collection', [], $ev);

$coll->findOneAndDelete([]);
}

public function test_deleteOne()
{
$manager = $this->getManager();
$ev = self::prophesize(EventDispatcherInterface::class);
$this->assertEventsDispatching($ev);
$ev = $this->mockEventDispatcher(1);

$coll = new Collection($manager, 'test_client', 'testdb', 'test_collection', [], $ev->reveal());
$coll = new Collection($manager, 'test_client', 'testdb', 'test_collection', [], $ev);

$coll->deleteOne([]);
}

public function test_replaceOne()
{
$manager = $this->getManager();
$ev = self::prophesize(EventDispatcherInterface::class);
$this->assertEventsDispatching($ev);
$ev = $this->mockEventDispatcher(1);

$coll = new Collection($manager, 'test_client', 'testdb', 'test_collection', [], $ev->reveal());
$coll = new Collection($manager, 'test_client', 'testdb', 'test_collection', [], $ev);

$coll->replaceOne([], []);
}

public function test_aggregate()
{
$manager = $this->getManager();
$ev = self::prophesize(EventDispatcherInterface::class);
$this->assertEventsDispatching($ev);
$ev = $this->mockEventDispatcher(5);

$coll = new Collection($manager, 'test_client', 'testdb', 'test_collection', [], $ev->reveal());
$coll = new Collection($manager, 'test_client', 'testdb', 'test_collection', [], $ev);

$coll->deleteMany([]);

Expand Down Expand Up @@ -165,36 +158,45 @@ public function test_aggregate()
public function test_deleteMany()
{
$manager = $this->getManager();
$ev = self::prophesize(EventDispatcherInterface::class);
$this->assertEventsDispatching($ev);
$ev = $this->mockEventDispatcher(1);

$coll = new Collection($manager, 'test_client', 'testdb', 'test_collection', [], $ev->reveal());
$coll = new Collection($manager, 'test_client', 'testdb', 'test_collection', [], $ev);

$coll->deleteMany([]);
}

public function test_distinct()
{
$manager = $this->getManager();
$ev = self::prophesize(EventDispatcherInterface::class);
$this->assertEventsDispatching($ev);
$ev = $this->mockEventDispatcher(1);

$coll = new Collection($manager, 'test_client', 'testdb', 'test_collection', [], $ev->reveal());
$coll = new Collection($manager, 'test_client', 'testdb', 'test_collection', [], $ev);

$coll->distinct('field');
}

/**
* @param $ev
*/
protected function assertEventsDispatching($ev)
private function mockEventDispatcher(int $times): EventDispatcherInterface
{
if (class_exists(LegacyEventDispatcherProxy::class)) {
$ev->dispatch(Argument::type(QueryEvent::class), QueryEvent::QUERY_PREPARED)->shouldBeCalled();
$ev->dispatch(Argument::type(QueryEvent::class), QueryEvent::QUERY_EXECUTED)->shouldBeCalled();
$ed = $this->prophesize(EventDispatcherInterface::class);

if (EventDispatcherCheck::isPSR14Compliant()) {
$ed->dispatch(Argument::type(QueryEvent::class), QueryEvent::QUERY_PREPARED)
->shouldBeCalledTimes($times)
->willReturnArgument(0);
$ed->dispatch(Argument::type(QueryEvent::class), QueryEvent::QUERY_EXECUTED)
->shouldBeCalledTimes($times)
->willReturnArgument(0);
} else {
$ev->dispatch(QueryEvent::QUERY_PREPARED, Argument::type(QueryEvent::class))->shouldBeCalled();
$ev->dispatch(QueryEvent::QUERY_EXECUTED, Argument::type(QueryEvent::class))->shouldBeCalled();
$ed->dispatch(QueryEvent::QUERY_PREPARED, Argument::type(QueryEvent::class))
->shouldBeCalledTimes($times);
$ed->dispatch(QueryEvent::QUERY_EXECUTED, Argument::type(QueryEvent::class))
->shouldBeCalledTimes($times);
}

if (EventDispatcherCheck::shouldUseLegacyProxy()) {
return LegacyEventDispatcherProxy::decorate($ed->reveal());
}

return $ed->reveal();
}
}
2 changes: 1 addition & 1 deletion tests/Functional/Command/LoadFixturesCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

class LoadFixturesCommandTest extends AppTestCase
{
/** @var Database $conn */
/** @var Database */
private $conn;

protected function setUp(): void
Expand Down
7 changes: 6 additions & 1 deletion tests/Unit/Services/ClientRegistryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Facile\MongoDbBundle\Tests\Unit\Services;

use Facile\MongoDbBundle\Event\ConnectionEvent;
use Facile\MongoDbBundle\Event\EventDispatcherCheck;
use Facile\MongoDbBundle\Services\ClientRegistry;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
Expand Down Expand Up @@ -98,7 +99,7 @@ private function mockEventDispatcher(): EventDispatcherInterface
{
$ed = $this->prophesize(EventDispatcherInterface::class);

if (class_exists(LegacyEventDispatcherProxy::class)) {
if (EventDispatcherCheck::isPSR14Compliant()) {
$ed->dispatch(Argument::type(ConnectionEvent::class), ConnectionEvent::CLIENT_CREATED)
->shouldBeCalledOnce()
->willReturnArgument(0);
Expand All @@ -107,6 +108,10 @@ private function mockEventDispatcher(): EventDispatcherInterface
->shouldBeCalledOnce();
}

if (EventDispatcherCheck::shouldUseLegacyProxy()) {
return LegacyEventDispatcherProxy::decorate($ed->reveal());
}

return $ed->reveal();
}
}

0 comments on commit 2ffbb5b

Please sign in to comment.