diff --git a/.travis.yml b/.travis.yml index 0d3bc4f..3ae44ff 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ language: php php: - - 5.5 - 5.6 - 7.0 - 7.1 diff --git a/composer.json b/composer.json index bccf08b..95e47e3 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,7 @@ } ], "require": { - "php": ">=5.5.0", + "php": ">=5.6.0", "doctrine/orm": "2.5.*", "doctrine/inflector": "^1.1" }, @@ -36,6 +36,7 @@ "gedmo/doctrine-extensions": "^2.4" }, "autoload": { + "files": ["src/helpers.php"], "psr-4": { "LaravelDoctrine\\Fluent\\": "src/", "Gedmo\\": "lib/" diff --git a/src/FluentDriver.php b/src/FluentDriver.php index 452f931..72abe00 100644 --- a/src/FluentDriver.php +++ b/src/FluentDriver.php @@ -23,10 +23,9 @@ class FluentDriver implements MappingDriver protected $fluentFactory; /** - * Initializes a new FileDriver that looks in the given path(s) for mapping - * documents and operates in the specified operating mode. + * Initializes a new FluentDriver that will load given Mapping classes / objects. * - * @param string[] $mappings + * @param string[]|Mapping[] $mappings */ public function __construct(array $mappings = []) { @@ -79,35 +78,33 @@ public function isTransient($className) } /** - * @param string[] $mappings + * Adds an array of mapping classes / objects to the driver. + * + * @param string[]|Mapping[] $mappings + * + * @throws MappingException + * @throws InvalidArgumentException */ public function addMappings(array $mappings = []) { - foreach ($mappings as $class) { - if (!class_exists($class)) { - throw new InvalidArgumentException("Mapping class [{$class}] does not exist"); - } - - $mapping = new $class(); - - if (!$mapping instanceof Mapping) { - throw new InvalidArgumentException("Mapping class [{$class}] should implement ".Mapping::class); - } - + foreach ($mappings as $mapping) { $this->addMapping($mapping); } } /** - * @param Mapping $mapping + * @param string|Mapping $mapping * * @throws MappingException + * @throws InvalidArgumentException * * @return void */ - public function addMapping(Mapping $mapping) + public function addMapping($mapping) { - $this->mappers->add($mapping); + $this->mappers->add($mapping instanceof Mapping ? + $mapping : $this->createMapping($mapping) + ); } /** @@ -139,4 +136,28 @@ protected function getFluent(ClassMetadata $metadata) { return call_user_func($this->fluentFactory, $metadata); } + + /** + * Create a mapping object from a mapping class, assuming an empty constructor. + * + * @param string $class + * + * @throws InvalidArgumentException + * + * @return Mapping + */ + protected function createMapping($class) + { + if (!class_exists($class)) { + throw new InvalidArgumentException("Mapping class [{$class}] does not exist"); + } + + $mapping = new $class(); + + if (!$mapping instanceof Mapping) { + throw new InvalidArgumentException("Mapping class [{$class}] should implement ".Mapping::class); + } + + return $mapping; + } } diff --git a/src/helpers.php b/src/helpers.php new file mode 100644 index 0000000..e8c89a5 --- /dev/null +++ b/src/helpers.php @@ -0,0 +1,75 @@ +getFileName(); + if ($sourceFile === false || !array_key_exists($sourceFile, $includedFiles)) { + continue; + } + + if ($rc->isAbstract() || $rc->isInterface()) { + continue; + } + + if (!$rc->implementsInterface(Mapping::class)) { + continue; + } + + $mappings[] = $rc->newInstanceWithoutConstructor(); + } + + return $mappings; +} diff --git a/tests/FluentDriverTest.php b/tests/FluentDriverTest.php index 8f8dc62..b256678 100644 --- a/tests/FluentDriverTest.php +++ b/tests/FluentDriverTest.php @@ -19,6 +19,7 @@ use Tests\Stubs\Mappings\StubEmbeddableMapping; use Tests\Stubs\Mappings\StubEntityMapping; use Tests\Stubs\Mappings\StubMappedSuperClassMapping; +use function LaravelDoctrine\Fluent\mappingsFrom; class FluentDriverTest extends \PHPUnit_Framework_TestCase { @@ -229,6 +230,53 @@ public function test_allow_other_fluent_implementations() $driver->getMappers()->addMapper('fake', new EntityMapper($mapping)); $driver->loadMetadataForClass('fake', new ClassMetadataInfo('fake')); } + + /** + * This is not "only" a FluentDriver test. + * This tests the `mappingsFrom` function, in conjunction with the driver's ability + * to receive both Mapping class names or Mapping objects. + */ + public function test_it_can_be_built_with_paths_using_the_provided_helper() + { + $driver = new FluentDriver(array_merge( + mappingsFrom([__DIR__ . '/Stubs/Mappings']), + [FakeClassMapping::class] + )); + + $classNames = $driver->getAllClassNames(); + $this->assertContains(StubEntity::class, $classNames); + $this->assertContains(StubEmbeddable::class, $classNames); + $this->assertContains(StubMappedSuperClass::class, $classNames); + $this->assertContains(FakeEntity::class, $classNames); + + $driver->loadMetadataForClass( + StubEntity::class, new ClassMetadataInfo(StubEntity::class) + ); + $this->assertInstanceOf( + EntityMapper::class, $driver->getMappers()->getMapperFor(StubEntity::class) + ); + + $driver->loadMetadataForClass( + StubEmbeddable::class, new ClassMetadataInfo(StubEmbeddable::class) + ); + $this->assertInstanceOf( + EmbeddableMapper::class, $driver->getMappers()->getMapperFor(StubEmbeddable::class) + ); + + $driver->loadMetadataForClass( + StubMappedSuperClass::class, new ClassMetadataInfo(StubMappedSuperClass::class) + ); + $this->assertInstanceOf( + MappedSuperClassMapper::class, $driver->getMappers()->getMapperFor(StubMappedSuperClass::class) + ); + + $driver->loadMetadataForClass( + FakeEntity::class, new ClassMetadataInfo(FakeEntity::class) + ); + $this->assertInstanceOf( + EntityMapper::class, $driver->getMappers()->getMapperFor(FakeEntity::class) + ); + } } class FakeClassMapping extends EntityMapping