Change bootstrap to look for metadata directories from modules.
This commit is contained in:
+35
-19
@@ -8,23 +8,14 @@ use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\Mapping\AnsiQuoteStrategy;
|
||||
use Doctrine\ORM\Tools\Setup;
|
||||
use Doctrine\ORM\Tools\SchemaTool;
|
||||
use Monolog\Logger;
|
||||
use Monolog\Handler\RotatingFileHandler;
|
||||
|
||||
use LotGD\Core\Exceptions\ArgumentException;
|
||||
use LotGD\Core\Exceptions\InvalidConfigurationException;
|
||||
|
||||
class Bootstrap
|
||||
{
|
||||
private static $annotationMetaDataDirectories = [];
|
||||
|
||||
public static function registerAnnotationMetaDataDirectory(string $directory)
|
||||
{
|
||||
if (is_dir($directory) === false) {
|
||||
throw new ArgumentException("{$directory} needs to be a valdid directory");
|
||||
}
|
||||
|
||||
self::$annotationMetaDataDirectories[] = $directory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Game object, with all the necessary configuration.
|
||||
* @throws InvalidConfigurationException
|
||||
@@ -38,21 +29,16 @@ class Bootstrap
|
||||
}
|
||||
$config = new Configuration($configFilePath);
|
||||
|
||||
$logger = new \Monolog\Logger('lotgd');
|
||||
$logger = new Logger('lotgd');
|
||||
// Add lotgd as the prefix for the log filenames.
|
||||
$logger->pushHandler(new \Monolog\Handler\RotatingFileHandler($config->getLogPath() . DIRECTORY_SEPARATOR . 'lotgd', 14));
|
||||
$logger->pushHandler(new RotatingFileHandler($config->getLogPath() . DIRECTORY_SEPARATOR . 'lotgd', 14));
|
||||
|
||||
$v = Game::getVersion();
|
||||
$logger->info("Bootstrap constructing game (Daenerys 🐲{$v}).");
|
||||
|
||||
$pdo = new \PDO($config->getDatabaseDSN(), $config->getDatabaseUser(), $config->getDatabasePassword());
|
||||
|
||||
// Read db annotations from model files
|
||||
$annotationMetaDataDirectories = array_merge(
|
||||
[__DIR__ . '/Models'],
|
||||
self::$annotationMetaDataDirectories
|
||||
);
|
||||
$configuration = Setup::createAnnotationMetadataConfiguration($annotationMetaDataDirectories, true);
|
||||
$configuration = Setup::createAnnotationMetadataConfiguration(Bootstrap::generateAnnotationDirectories($logger, new ComposerManager($logger)), true);
|
||||
|
||||
// Set a quote
|
||||
$configuration->setQuoteStrategy(new AnsiQuoteStrategy());
|
||||
@@ -68,4 +54,34 @@ class Bootstrap
|
||||
|
||||
return new Game($config, $entityManager, $eventManager, $logger);
|
||||
}
|
||||
|
||||
public static function generateAnnotationDirectories(Logger $logger, ComposerManager $manager): array
|
||||
{
|
||||
// Read db annotations from our own model files.
|
||||
$directories = [__DIR__ . '/Models'];
|
||||
|
||||
// Find other annotation directories from installed modules.
|
||||
$modulePackages = $manager->getModulePackages();
|
||||
foreach ($modulePackages as $p) {
|
||||
$name = $p->getName();
|
||||
$extra = $p->getExtra();
|
||||
if (!empty($extra['lotgd-namespace'])) {
|
||||
$n = $extra['lotgd-namespace'];
|
||||
|
||||
// Find the directory for this namespace by using the autoloader
|
||||
// to find the required Module class.
|
||||
$autoloader = require(ComposerManager::findAutoloader());
|
||||
$path = $autoloader->findFile($n . 'Module');
|
||||
if ($path === false) {
|
||||
$logger->error("Module {$name} lacks a {$n}Module class.");
|
||||
continue;
|
||||
}
|
||||
|
||||
$directories[] = dirname($path);
|
||||
} else {
|
||||
$logger->error("Module {$name} lacks a 'lotgd-namespace' entry in its composer 'extra' field. Its database models will not be properly loaded.");
|
||||
}
|
||||
}
|
||||
return $directories;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace LotGD\Core\Tests\AdditionalEntities;
|
||||
|
||||
use Doctrine\ORM\Mapping\Entity;
|
||||
use Doctrine\ORM\Mapping\Table;
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @Table(name="Users")
|
||||
*/
|
||||
class UserEntity
|
||||
{
|
||||
/** @Id @Column(type="integer") @GeneratedValue */
|
||||
private $id;
|
||||
/** @Column(type="string", length=50); */
|
||||
private $name;
|
||||
|
||||
public function getId(): int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setName(string $name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
}
|
||||
+34
-17
@@ -3,11 +3,25 @@ declare(strict_types=1);
|
||||
|
||||
namespace LotGD\Core\Tests;
|
||||
|
||||
use Composer\Package\PackageInterface;
|
||||
|
||||
use Monolog\Logger;
|
||||
use Monolog\Handler\NullHandler;
|
||||
|
||||
use LotGD\Core\Bootstrap;
|
||||
use LotGD\Core\Tests\AdditionalEntities\UserEntity;
|
||||
use LotGD\Core\ComposerManager;
|
||||
use LotGD\Core\Tests\FakeModule\UserEntity;
|
||||
|
||||
class BootstrapTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
private $logger;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->logger = new Logger('test');
|
||||
$this->logger->pushHandler(new NullHandler());
|
||||
}
|
||||
|
||||
public function testGame()
|
||||
{
|
||||
$g = Bootstrap::createGame();
|
||||
@@ -16,26 +30,29 @@ class BootstrapTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertNotNull($g->getLogger());
|
||||
}
|
||||
|
||||
public function testDoctrineReadsAnnotationsFromAdditionalMetaDataDirectory()
|
||||
public function testGenerateAnnotationDirectories()
|
||||
{
|
||||
Bootstrap::registerAnnotationMetaDataDirectory(__DIR__ . "/AdditionalEntities");
|
||||
$composerManager = $this->getMockBuilder(ComposerManager::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$g = Bootstrap::createGame();
|
||||
$package = $this->getMockForAbstractClass(PackageInterface::class);
|
||||
$package->method('getExtra')->willReturn(array(
|
||||
'lotgd-namespace' => 'LotGD\\Core\\Tests\\FakeModule\\',
|
||||
));
|
||||
|
||||
$user = new UserEntity();
|
||||
$user->setName("Monthy");
|
||||
$composerManager->method('getModulePackages')->willReturn(array($package));
|
||||
|
||||
$g->getEntityManager()->persist($user);
|
||||
$g->getEntityManager()->flush();
|
||||
$result = Bootstrap::generateAnnotationDirectories($this->logger, $composerManager);
|
||||
$expected = __DIR__ . DIRECTORY_SEPARATOR . 'FakeModule';
|
||||
|
||||
$id = $user->getId();
|
||||
$this->assertInternalType("int", $id);
|
||||
|
||||
$g->getEntityManager()->clear();
|
||||
$user = $g->getEntityManager()->getRepository(UserEntity::class)->find($id);
|
||||
|
||||
$this->assertInternalType("int", $user->getId());
|
||||
$this->assertInternalType("string", $user->getName());
|
||||
$this->assertSame("Monthy", $user->getName());
|
||||
$string = implode(', ', $result);
|
||||
$found = false;
|
||||
foreach ($result as $r) {
|
||||
if (realpath($r) == $expected) {
|
||||
$found = true;
|
||||
}
|
||||
}
|
||||
$this->assertTrue($found, "Annotation directories [{$string}] does not contain {$expected}.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace LotGD\Core\Tests\FakeModule;
|
||||
|
||||
use LotGD\Core\Module;
|
||||
|
||||
class FakeModule extends Module {
|
||||
public static function onRegister(Game $g) {}
|
||||
public static function onUnregister(Game $g) {}
|
||||
}
|
||||
Reference in New Issue
Block a user