Implement dependency injection

This commit is contained in:
Jeremy Dormitzer 2019-01-17 22:53:11 -05:00
parent 8e88b1dc29
commit aba516fd34
6 changed files with 230 additions and 43 deletions

View File

@ -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"

124
composer.lock generated
View File

@ -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",

View File

@ -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 )
);
}
}
}
?>

View File

@ -0,0 +1,88 @@
<?php
namespace ActivityPub\Config;
use ActivityPub\Crypto\HttpSignatureService;
use ActivityPub\Database\PrefixNamingStrategy;
use ActivityPub\Objects\ObjectsService;
use ActivityPub\Utils\SimpleDateTimeProvider;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Tools\Setup;
use GuzzleHttp\Client;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
/**
* The ActivityPubModule is responsible for setting up all the services for the library
*/
class ActivityPubModule
{
/**
* @var ContainerBuilder
*/
private $injector;
public function __construct( $options )
{
$defaults = array(
'isDevMode' => 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 )
);
}
}
}
?>

View File

@ -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;
}
/**

View File

@ -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
);
}