From aba516fd34e2675dd6c5a78d210e48ab2429114a Mon Sep 17 00:00:00 2001 From: Jeremy Dormitzer Date: Thu, 17 Jan 2019 22:53:11 -0500 Subject: [PATCH] Implement dependency injection --- composer.json | 1 + composer.lock | 124 +++++++++++++++++++++++++++- src/ActivityPub.php | 47 ++--------- src/Config/ActivityPubModule.php | 88 ++++++++++++++++++++ src/Objects/ObjectsService.php | 6 +- test/Objects/ObjectsServiceTest.php | 7 +- 6 files changed, 230 insertions(+), 43 deletions(-) create mode 100644 src/Config/ActivityPubModule.php diff --git a/composer.json b/composer.json index d3bd53e..33467e6 100644 --- a/composer.json +++ b/composer.json @@ -27,6 +27,7 @@ "guzzlehttp/guzzle": "^6.3", "phpseclib/phpseclib": "^2.0", "psr/http-message": "^1.0", + "symfony/dependency-injection": "^4.2", "symfony/http-kernel": "^4.2", "symfony/psr-http-message-bridge": "^1.1", "zendframework/zend-diactoros": "^1.8" diff --git a/composer.lock b/composer.lock index 6d33c9d..b2e2eae 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4fdd0e94241c59ddd2c9763881167989", + "content-hash": "d765cce5f542dc7c2bee097427f2318e", "packages": [ { "name": "doctrine/annotations", @@ -1186,6 +1186,55 @@ ], "time": "2018-12-16T17:45:25+00:00" }, + { + "name": "psr/container", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "time": "2017-02-14T16:28:37+00:00" + }, { "name": "psr/http-message", "version": "1.0.1", @@ -1516,6 +1565,79 @@ "homepage": "https://symfony.com", "time": "2019-01-03T09:07:35+00:00" }, + { + "name": "symfony/dependency-injection", + "version": "v4.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "a28dda9df1d5494367454cad91e44751ac53921c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/a28dda9df1d5494367454cad91e44751ac53921c", + "reference": "a28dda9df1d5494367454cad91e44751ac53921c", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "psr/container": "^1.0", + "symfony/contracts": "^1.0" + }, + "conflict": { + "symfony/config": "<4.2", + "symfony/finder": "<3.4", + "symfony/proxy-manager-bridge": "<3.4", + "symfony/yaml": "<3.4" + }, + "provide": { + "psr/container-implementation": "1.0", + "symfony/service-contracts-implementation": "1.0" + }, + "require-dev": { + "symfony/config": "~4.2", + "symfony/expression-language": "~3.4|~4.0", + "symfony/yaml": "~3.4|~4.0" + }, + "suggest": { + "symfony/config": "", + "symfony/expression-language": "For using expressions in service container configuration", + "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", + "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", + "symfony/yaml": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\DependencyInjection\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony DependencyInjection Component", + "homepage": "https://symfony.com", + "time": "2019-01-05T16:37:49+00:00" + }, { "name": "symfony/event-dispatcher", "version": "v4.2.2", diff --git a/src/ActivityPub.php b/src/ActivityPub.php index 70114a7..f15bb42 100644 --- a/src/ActivityPub.php +++ b/src/ActivityPub.php @@ -3,13 +3,9 @@ namespace ActivityPub; require_once __DIR__ . '/../vendor/autoload.php'; -use ActivityPub\Database\PrefixNamingStrategy; +use ActivityPub\Config\ActivityPubModule; use ActivityPub\Http\ControllerResolver; -use ActivityPub\Objects\ObjectsService; -use ActivityPub\Utils\SimpleDateTimeProvider; -use Doctrine\ORM\EntityManager; use Doctrine\ORM\Tools\SchemaTool; -use Doctrine\ORM\Tools\Setup; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\HttpKernel; use Symfony\Component\EventDispatcher; @@ -19,8 +15,10 @@ use Symfony\Component\HttpKernel\EventListener\ExceptionListener; class ActivityPub { - private $entityManager; - private $objectService; + /** + * @var ActivityPubModule + */ + private $module; /** * Constructs a new ActivityPub instance @@ -30,23 +28,7 @@ class ActivityPub */ public function __construct( array $opts ) { - $defaults = array( - 'isDevMode' => false, - 'dbPrefix' => '', - ); - $options = array_merge( $defaults, $opts ); - $this->validateOptions( $options ); - - $dbConfig = Setup::createAnnotationMetadataConfiguration( - array( __DIR__ . '/Entities' ), $options['isDevMode'] - ); - $namingStrategy = new PrefixNamingStrategy( $options['dbPrefix'] ); - $dbConfig->setNamingStrategy( $namingStrategy ); - $dbParams = $options['dbOptions']; - $this->entityManager = EntityManager::create( $dbParams, $dbConfig ); - - $dateTimeProvider = new SimpleDateTimeProvider(); - $this->objectService = new ObjectsService($this->entityManager, $dateTimeProvider); + $this->module = new ActivityPubModule( $opts ); } /** @@ -77,21 +59,10 @@ class ActivityPub public function updateSchema() { - $schemaTool = new SchemaTool( $this->entityManager ); - $classes = $this->entityManager->getMetadataFactory()->getAllMetadata(); + $entityManager = $this->module->get( 'entityManager' ); + $schemaTool = new SchemaTool( $entityManager ); + $classes = $entityManager->getMetadataFactory()->getAllMetadata(); $schemaTool->updateSchema( $classes ); } - - private function validateOptions( $opts ) - { - $required = array( 'dbOptions' ); - $actual = array_keys( $opts ); - $missing = array_diff( $required, $actual ); - if ( count( $missing ) > 0 ) { - throw new InvalidArgumentException( - 'Missing required options: ' . print_r( $missing, t ) - ); - } - } } ?> diff --git a/src/Config/ActivityPubModule.php b/src/Config/ActivityPubModule.php new file mode 100644 index 0000000..f30281d --- /dev/null +++ b/src/Config/ActivityPubModule.php @@ -0,0 +1,88 @@ + false, + 'dbPrefix' => '', + ); + $options = array_merge( $defaults, $options ); + $this->validateOptions( $options ); + + $this->injector = new ContainerBuilder; + + $dbConfig = Setup::createAnnotationMetadataConfiguration( + array( __DIR__ . '/../Entities' ), $options['isDevMode'] + ); + $namingStrategy = new PrefixNamingStrategy( $options['dbPrefix'] ); + $dbConfig->setNamingStrategy( $namingStrategy ); + $dbParams = $options['dbOptions']; + + $this->injector->register( 'entityManager', EntityManager::class ) + ->setArguments( array( $dbParams, $dbConfig ) ) + ->setFactory( array( EntityManager::class, 'create' ) ); + + $this->injector->register( 'httpClient', Client::class ) + ->addArgument( array( 'http_errors' => false ) ); + + $this->injector->register( 'dateTimeProvider', SimpleDateTimeProvider::class ); + + $this->injector->register( 'objectsService', ObjectsService::class ) + ->addArgument( new Reference( 'entityManager' ) ) + ->addArgument( new Reference( 'dateTimeProvider' ) ) + ->addArgument( new Reference( 'httpClient' ) ); + + $this->injector->register( 'httpSignatureService', HttpSignatureService::class ) + ->addArgument( new Reference( 'dateTimeProvider' ) ); + + $this->injector->register( 'signatureListener', SignatureListener::class ) + ->addArgument( new Reference( 'httpSignatureService' ) ) + ->addArgument( new Reference( 'objectsService' ) ); + } + + /** + * Returns the service identified by $id + * + * @param string $id The id of the service instance to get + * @return object The service instance + */ + public function get( string $id ) + { + return $this->injector->get( $id ); + } + + private function validateOptions( $options ) + { + $required = array( 'dbOptions' ); + $actual = array_keys( $options ); + $missing = array_diff( $required, $actual ); + if ( count( $missing ) > 0 ) { + throw new InvalidArgumentException( + 'Missing required options: ' . print_r( $missing, t ) + ); + } + } + +} +?> diff --git a/src/Objects/ObjectsService.php b/src/Objects/ObjectsService.php index 95cd178..3db1ac5 100644 --- a/src/Objects/ObjectsService.php +++ b/src/Objects/ObjectsService.php @@ -25,11 +25,13 @@ class ObjectsService */ protected $httpClient; - public function __construct( EntityManager $entityManager, DateTimeProvider $dateTimeProvider ) + public function __construct( EntityManager $entityManager, + DateTimeProvider $dateTimeProvider, + Client $client) { $this->entityManager = $entityManager; $this->dateTimeProvider = $dateTimeProvider; - $this->httpClient = new Client( array( 'http_errors' => false ) ); + $this->httpClient = $client; } /** diff --git a/test/Objects/ObjectsServiceTest.php b/test/Objects/ObjectsServiceTest.php index c4c2426..250a8b5 100644 --- a/test/Objects/ObjectsServiceTest.php +++ b/test/Objects/ObjectsServiceTest.php @@ -8,10 +8,11 @@ use ActivityPub\Test\Config\ArrayDataSet; use ActivityPub\Entities\ActivityPubObject; use ActivityPub\Entities\Field; use Doctrine\ORM\EntityManager; -use Doctrine\ORM\Tools\Setup; use ActivityPub\Objects\ObjectsService; use ActivityPub\Database\PrefixNamingStrategy; use ActivityPub\Test\TestUtils\TestDateTimeProvider; +use Doctrine\ORM\Tools\Setup; +use GuzzleHttp\Client; use PHPUnit\DbUnit\TestCaseTrait; class ObjectsServiceTest extends SQLiteTestCase @@ -19,6 +20,7 @@ class ObjectsServiceTest extends SQLiteTestCase protected $entityManager; protected $objectsService; protected $dateTimeProvider; + protected $httpClient; protected function getDataSet() { @@ -41,8 +43,9 @@ class ObjectsServiceTest extends SQLiteTestCase $this->dateTimeProvider = new TestDateTimeProvider( array( 'create' => new DateTime( "12:00" ), 'update' => new DateTime( "12:01" ) ) ); + $this->httpClient = new Client( array( 'http_errors' => false ) ); $this->objectsService = new ObjectsService( - $this->entityManager, $this->dateTimeProvider + $this->entityManager, $this->dateTimeProvider, $this->httpClient ); }