From dd597362ebaebe645a59182d2a6eee3a9445075c Mon Sep 17 00:00:00 2001 From: Guido Contreras Woda Date: Tue, 4 Jul 2017 18:40:27 -0300 Subject: [PATCH 1/3] Adds a `mappingsFrom` function This function can convert an array of paths into an array of Mapping objects by reflecting on declared classes, just as the AnnotationDriver does. --- composer.json | 1 + src/FluentDriver.php | 55 ++++++++++++++++++---------- src/helpers.php | 73 ++++++++++++++++++++++++++++++++++++++ tests/FluentDriverTest.php | 48 +++++++++++++++++++++++++ 4 files changed, 158 insertions(+), 19 deletions(-) create mode 100644 src/helpers.php diff --git a/composer.json b/composer.json index bccf08b..718070e 100644 --- a/composer.json +++ b/composer.json @@ -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..e8ab70e 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,31 @@ 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 +134,26 @@ 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 + * @return Mapping + * @throws InvalidArgumentException + */ + 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..ffa158d --- /dev/null +++ b/src/helpers.php @@ -0,0 +1,73 @@ +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 From fc3d47008924cb6a6b172718604e7030929aaf61 Mon Sep 17 00:00:00 2001 From: Patrick Brouwers Date: Tue, 4 Jul 2017 21:40:40 +0000 Subject: [PATCH 2/3] Apply fixes from StyleCI [ci skip] [skip ci] --- src/FluentDriver.php | 8 ++++++-- src/helpers.php | 10 ++++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/FluentDriver.php b/src/FluentDriver.php index e8ab70e..72abe00 100644 --- a/src/FluentDriver.php +++ b/src/FluentDriver.php @@ -81,6 +81,7 @@ public function isTransient($className) * Adds an array of mapping classes / objects to the driver. * * @param string[]|Mapping[] $mappings + * * @throws MappingException * @throws InvalidArgumentException */ @@ -96,6 +97,7 @@ public function addMappings(array $mappings = []) * * @throws MappingException * @throws InvalidArgumentException + * * @return void */ public function addMapping($mapping) @@ -138,9 +140,11 @@ protected function getFluent(ClassMetadata $metadata) /** * Create a mapping object from a mapping class, assuming an empty constructor. * - * @param string $class - * @return Mapping + * @param string $class + * * @throws InvalidArgumentException + * + * @return Mapping */ protected function createMapping($class) { diff --git a/src/helpers.php b/src/helpers.php index ffa158d..e8c89a5 100644 --- a/src/helpers.php +++ b/src/helpers.php @@ -13,13 +13,15 @@ /** * Returns an array of Mapping objects found on the given paths. * - * @param string[] $paths - * @param string $fileExtension - * @return Mapping[] + * @param string[] $paths + * @param string $fileExtension * * @throws MappingException + * + * @return Mapping[] */ -function mappingsFrom(array $paths, $fileExtension = '.php') { +function mappingsFrom(array $paths, $fileExtension = '.php') +{ $includedFiles = []; foreach ($paths as $path) { From ae5005c9d3a8d7f8e7071cf74275d40af09bca6d Mon Sep 17 00:00:00 2001 From: Guido Contreras Woda Date: Tue, 4 Jul 2017 18:50:47 -0300 Subject: [PATCH 3/3] Proposed namespaced function requires php 5.6+ --- .travis.yml | 1 - composer.json | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) 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 718070e..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" },