From 9fc3c474553653ca1086f76724753a99b17bcbb7 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Fri, 10 Jan 2025 11:24:43 -0500 Subject: [PATCH 01/11] override Database Factory for Winter Storm --- src/Database/Factories/Factory.php | 28 +++++++++++++++++++++++++ src/Database/Factories/HasFactory.php | 30 +++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 src/Database/Factories/Factory.php create mode 100644 src/Database/Factories/HasFactory.php diff --git a/src/Database/Factories/Factory.php b/src/Database/Factories/Factory.php new file mode 100644 index 000000000..52eaf79a7 --- /dev/null +++ b/src/Database/Factories/Factory.php @@ -0,0 +1,28 @@ + $modelName + * @return class-string<\Illuminate\Database\Eloquent\Factories\Factory> + */ + public static function resolveFactoryName(string $modelName) + { + $pluginNamespace = Str::before($modelName, 'Models'); + $modelClassName = Str::after($modelName, 'Models\\'); + + return $pluginNamespace.static::$namespace.$modelClassName.'Factory'; + } +} diff --git a/src/Database/Factories/HasFactory.php b/src/Database/Factories/HasFactory.php new file mode 100644 index 000000000..bf1079080 --- /dev/null +++ b/src/Database/Factories/HasFactory.php @@ -0,0 +1,30 @@ +count(is_numeric($count) ? $count : null) + ->state(is_callable($count) || is_array($count) ? $count : $state); + } + + /** + * Create a new factory instance for the model. + * + * @return \Winter\Storm\Database\Factories\Factory + */ + protected static function newFactory() + { + // + } +} From 8ca4afc127d43069f96b257ed2e0ab8cbd1f1430 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Fri, 10 Jan 2025 15:54:16 -0500 Subject: [PATCH 02/11] improve resolveFactoryName; add unit test --- src/Database/Factories/Factory.php | 15 ++++++++++++--- tests/Database/Factories/FactoryTest.php | 15 +++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 tests/Database/Factories/FactoryTest.php diff --git a/src/Database/Factories/Factory.php b/src/Database/Factories/Factory.php index 52eaf79a7..704bb4283 100644 --- a/src/Database/Factories/Factory.php +++ b/src/Database/Factories/Factory.php @@ -20,9 +20,18 @@ abstract class Factory extends BaseFactory */ public static function resolveFactoryName(string $modelName) { - $pluginNamespace = Str::before($modelName, 'Models'); - $modelClassName = Str::after($modelName, 'Models\\'); + if (Str::contains($modelName, '\\Models\\')) { + $pluginNamespace = trim(Str::before($modelName, 'Models'), '\\'); + $modelClassName = trim(Str::after($modelName, 'Models'), '\\'); + } else { + $pluginNamespace = ''; + $modelClassName = $modelName; + } - return $pluginNamespace.static::$namespace.$modelClassName.'Factory'; + return trim(implode('\\', [ + $pluginNamespace, + trim(static::$namespace, '\\'), + $modelClassName.'Factory' + ]), '\\'); } } diff --git a/tests/Database/Factories/FactoryTest.php b/tests/Database/Factories/FactoryTest.php new file mode 100644 index 000000000..bc3663dff --- /dev/null +++ b/tests/Database/Factories/FactoryTest.php @@ -0,0 +1,15 @@ +assertEquals($factoryClass, 'Plugin\Author\Database\Factories\TestModelFactory'); + + $factoryClass = Factory::resolveFactoryName('TestModel'); + $this->assertEquals($factoryClass, 'Database\Factories\TestModelFactory'); + } +} From 53a7dc3bee1de09787f5df6173c1fae95f031b14 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Fri, 10 Jan 2025 15:58:11 -0500 Subject: [PATCH 03/11] add one more test case --- src/Database/Factories/Factory.php | 2 +- tests/Database/Factories/FactoryTest.php | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Database/Factories/Factory.php b/src/Database/Factories/Factory.php index 704bb4283..a041f69b8 100644 --- a/src/Database/Factories/Factory.php +++ b/src/Database/Factories/Factory.php @@ -20,7 +20,7 @@ abstract class Factory extends BaseFactory */ public static function resolveFactoryName(string $modelName) { - if (Str::contains($modelName, '\\Models\\')) { + if (Str::contains($modelName, 'Models\\')) { $pluginNamespace = trim(Str::before($modelName, 'Models'), '\\'); $modelClassName = trim(Str::after($modelName, 'Models'), '\\'); } else { diff --git a/tests/Database/Factories/FactoryTest.php b/tests/Database/Factories/FactoryTest.php index bc3663dff..78eb20871 100644 --- a/tests/Database/Factories/FactoryTest.php +++ b/tests/Database/Factories/FactoryTest.php @@ -9,6 +9,9 @@ public function testResolveFactoryName() $factoryClass = Factory::resolveFactoryName('Plugin\Author\Models\TestModel'); $this->assertEquals($factoryClass, 'Plugin\Author\Database\Factories\TestModelFactory'); + $factoryClass = Factory::resolveFactoryName('Models\TestModel'); + $this->assertEquals($factoryClass, 'Database\Factories\TestModelFactory'); + $factoryClass = Factory::resolveFactoryName('TestModel'); $this->assertEquals($factoryClass, 'Database\Factories\TestModelFactory'); } From 61255f3fc928bc0d53d1c06de076481bac82ad4e Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Sun, 12 Jan 2025 09:55:05 -0500 Subject: [PATCH 04/11] use winter storm model and factory --- src/Database/Factories/Factory.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Database/Factories/Factory.php b/src/Database/Factories/Factory.php index a041f69b8..9508f924f 100644 --- a/src/Database/Factories/Factory.php +++ b/src/Database/Factories/Factory.php @@ -6,7 +6,7 @@ use Illuminate\Support\Str; /** - * @template TModel of \Illuminate\Database\Eloquent\Model + * @template TModel of \Winter\Storm\Database\Model * * @method $this trashed() */ @@ -15,8 +15,8 @@ abstract class Factory extends BaseFactory /** * Get the factory name for the given model name. * - * @param class-string<\Illuminate\Database\Eloquent\Model> $modelName - * @return class-string<\Illuminate\Database\Eloquent\Factories\Factory> + * @param class-string<\Winter\Storm\Database\Model> $modelName + * @return class-string<\Winter\Storm\Database\Factories\Factory> */ public static function resolveFactoryName(string $modelName) { From e8711386e4f8a3af9273bf8e4d76a9147b3472f2 Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Fri, 31 Jan 2025 23:53:35 -0600 Subject: [PATCH 05/11] Add test case for modules --- tests/Database/Factories/FactoryTest.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/Database/Factories/FactoryTest.php b/tests/Database/Factories/FactoryTest.php index 78eb20871..4c6b23f78 100644 --- a/tests/Database/Factories/FactoryTest.php +++ b/tests/Database/Factories/FactoryTest.php @@ -6,6 +6,9 @@ class FactoryTest extends TestCase { public function testResolveFactoryName() { + $factoryClass = Factory::resolveFactoryName('Module\Models\TestModel'); + $this->assertEquals($factoryClass, 'Module\Database\Factories\TestModelFactory'); + $factoryClass = Factory::resolveFactoryName('Plugin\Author\Models\TestModel'); $this->assertEquals($factoryClass, 'Plugin\Author\Database\Factories\TestModelFactory'); From ee5d4070c03a6b7bb0a3761d4b6b53143443cf8d Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Sat, 1 Feb 2025 00:02:13 -0600 Subject: [PATCH 06/11] Apply suggestions from code review --- src/Database/Factories/HasFactory.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Database/Factories/HasFactory.php b/src/Database/Factories/HasFactory.php index bf1079080..153793231 100644 --- a/src/Database/Factories/HasFactory.php +++ b/src/Database/Factories/HasFactory.php @@ -2,14 +2,12 @@ namespace Winter\Storm\Database\Factories; -use Illuminate\Database\Eloquent\Factories\Factory as BaseFactory; - trait HasFactory { /** * Get a new factory instance for the model. */ - public static function factory(callable|array|int|null $count = null, callable|array $state = []): BaseFactory + public static function factory(callable|array|int|null $count = null, callable|array $state = []): Factory { $factory = static::newFactory() ?: Factory::factoryForModel(get_called_class()); From b685a09970259cc9510b45637384da55a5c8eb35 Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Sat, 1 Feb 2025 00:18:41 -0600 Subject: [PATCH 07/11] Update Factory.php --- src/Database/Factories/Factory.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Database/Factories/Factory.php b/src/Database/Factories/Factory.php index 9508f924f..510047504 100644 --- a/src/Database/Factories/Factory.php +++ b/src/Database/Factories/Factory.php @@ -21,15 +21,15 @@ abstract class Factory extends BaseFactory public static function resolveFactoryName(string $modelName) { if (Str::contains($modelName, 'Models\\')) { - $pluginNamespace = trim(Str::before($modelName, 'Models'), '\\'); + $baseNamespace = trim(Str::before($modelName, 'Models'), '\\'); $modelClassName = trim(Str::after($modelName, 'Models'), '\\'); } else { - $pluginNamespace = ''; + $baseNamespace = ''; $modelClassName = $modelName; } return trim(implode('\\', [ - $pluginNamespace, + $baseNamespace, trim(static::$namespace, '\\'), $modelClassName.'Factory' ]), '\\'); From e4f6458be799eb0489dc5514ddb65889d0764198 Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Sat, 1 Feb 2025 00:27:20 -0600 Subject: [PATCH 08/11] Update Factory.php --- src/Database/Factories/Factory.php | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/Database/Factories/Factory.php b/src/Database/Factories/Factory.php index 510047504..c192117c3 100644 --- a/src/Database/Factories/Factory.php +++ b/src/Database/Factories/Factory.php @@ -34,4 +34,27 @@ public static function resolveFactoryName(string $modelName) $modelClassName.'Factory' ]), '\\'); } + + /** + * Get the name of the model that is generated by the factory. + * + * @return class-string<\Winter\Storm\Database\Model|TModel> + */ + public function modelName() + { + $resolver = static::$modelNameResolver ?? function (self $factory) { + $baseNamespace = join("\\", array_slice( + explode("\\", Str::replaceFirst(static::$namespace, '', get_class($factory))), + 0, + -1 + )); + $factoryBasename = Str::replaceLast('Factory', '', class_basename($factory)); + + $guessedClass = $baseNamespace . '\\Models\\' . $factoryBasename; + + return class_exists($guessedClass) ? $guessedClass : parent::modelName(); + }; + + return $this->model ?? $resolver($this); + } } From 14c27b1493345b443cf2a88511ddb962d936a046 Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Sat, 1 Feb 2025 00:35:26 -0600 Subject: [PATCH 09/11] Appease the stan --- src/Database/Factories/Factory.php | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Database/Factories/Factory.php b/src/Database/Factories/Factory.php index c192117c3..46f15c93a 100644 --- a/src/Database/Factories/Factory.php +++ b/src/Database/Factories/Factory.php @@ -12,6 +12,20 @@ */ abstract class Factory extends BaseFactory { + /** + * The default model name resolver. + * + * @var callable + */ + protected static $modelNameResolver = null; + + /** + * The name of the factory's corresponding model. + * + * @var class-string<\Illuminate\Database\Eloquent\Model|TModel> + */ + protected $model = null; + /** * Get the factory name for the given model name. * @@ -38,7 +52,7 @@ public static function resolveFactoryName(string $modelName) /** * Get the name of the model that is generated by the factory. * - * @return class-string<\Winter\Storm\Database\Model|TModel> + * @return class-string<\Illuminate\Database\Eloquent\Model|TModel> */ public function modelName() { From 94982e20ac6570e7069d3c5c9c85dea8c440ef29 Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Sat, 1 Feb 2025 00:38:31 -0600 Subject: [PATCH 10/11] Appease the stan pt 2 --- src/Database/Factories/Factory.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Database/Factories/Factory.php b/src/Database/Factories/Factory.php index 46f15c93a..4fc95f481 100644 --- a/src/Database/Factories/Factory.php +++ b/src/Database/Factories/Factory.php @@ -15,14 +15,14 @@ abstract class Factory extends BaseFactory /** * The default model name resolver. * - * @var callable + * @var callable|null */ protected static $modelNameResolver = null; /** * The name of the factory's corresponding model. * - * @var class-string<\Illuminate\Database\Eloquent\Model|TModel> + * @var class-string<\Illuminate\Database\Eloquent\Model|TModel>|null */ protected $model = null; From dc4d60f6b4cfd4971ee20dda9d15c22099271b85 Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Sat, 1 Feb 2025 00:42:24 -0600 Subject: [PATCH 11/11] I've had ENOUGH --- src/Database/Factories/Factory.php | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/src/Database/Factories/Factory.php b/src/Database/Factories/Factory.php index 4fc95f481..a984abf63 100644 --- a/src/Database/Factories/Factory.php +++ b/src/Database/Factories/Factory.php @@ -12,20 +12,6 @@ */ abstract class Factory extends BaseFactory { - /** - * The default model name resolver. - * - * @var callable|null - */ - protected static $modelNameResolver = null; - - /** - * The name of the factory's corresponding model. - * - * @var class-string<\Illuminate\Database\Eloquent\Model|TModel>|null - */ - protected $model = null; - /** * Get the factory name for the given model name. * @@ -56,6 +42,7 @@ public static function resolveFactoryName(string $modelName) */ public function modelName() { + // @phpstan-ignore-next-line $resolver = static::$modelNameResolver ?? function (self $factory) { $baseNamespace = join("\\", array_slice( explode("\\", Str::replaceFirst(static::$namespace, '', get_class($factory))), @@ -69,6 +56,7 @@ public function modelName() return class_exists($guessedClass) ? $guessedClass : parent::modelName(); }; + // @phpstan-ignore-next-line return $this->model ?? $resolver($this); } }