From e5f1c2811ee5e22d500fe9b7a0f7e1f0c58c4f64 Mon Sep 17 00:00:00 2001 From: Sam Taylor Date: Fri, 13 Nov 2020 09:49:02 -0500 Subject: [PATCH 01/21] Added finding similar usernames using "like" or regexp --- .gitignore | 2 ++ src/FindSimilarUsernames.php | 36 ++++++++++++++++++++++++++++--- src/config/username_generator.php | 5 +++++ 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 0d54553..d4d26d6 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ vendor/ composer.lock .idea/ .phpunit.result.cache +vendor +vendor.nosync diff --git a/src/FindSimilarUsernames.php b/src/FindSimilarUsernames.php index c05c3d0..1109dec 100644 --- a/src/FindSimilarUsernames.php +++ b/src/FindSimilarUsernames.php @@ -2,6 +2,8 @@ namespace TaylorNetwork\UsernameGenerator; +use Illuminate\Database\QueryException; + trait FindSimilarUsernames { /** @@ -16,10 +18,38 @@ trait FindSimilarUsernames */ public function findSimilarUsernames($username) { - if (count($data = static::where(config('username_generator.column', 'username'), $username)->get()) === 0) { - return $data; + $preferRegexp = $this->preferRegexp ?? config('username_generator.prefer_regexp', true); + + if(!$preferRegexp) { + return $this->searchUsingLike($username); + } + + try { + return $this->searchUsingRegexp($username); + } catch (QueryException $exception) { + return $this->searchUsingLike($username); } + } + + private function searchUsingLike($username) + { + $exactMatches = static::where($this->getColumn(), $username)->get(); - return static::where(config('username_generator.column', 'username'), 'LIKE', $username.'%')->get(); + if ($exactMatches) { + return static::where($this->getColumn(), 'LIKE', $username.'%')->get(); + } + + return $exactMatches; + } + + private function searchUsingRegexp($username) + { + $column = $this->getColumn(); + return static::whereRaw("$column REGEXP '{$username}([0-9]*)?$'")->get(); + } + + private function getColumn() + { + return $this->usernameColumn ?? config('username_generator.column', 'username'); } } diff --git a/src/config/username_generator.php b/src/config/username_generator.php index e1172d3..cf2b50c 100644 --- a/src/config/username_generator.php +++ b/src/config/username_generator.php @@ -52,6 +52,11 @@ */ 'allowed_characters' => 'a-zA-Z ', + /* + * Prefer using REGEXP + */ + 'prefer_regexp' => true, + /* * Loaded drivers for converting to a username */ From 717f6b40e6436f8db62cf502a820e0151f3cb61d Mon Sep 17 00:00:00 2001 From: Sam Taylor Date: Fri, 13 Nov 2020 09:49:45 -0500 Subject: [PATCH 02/21] Removed old tests and made tests use proper database --- tests/CustomColumn.php | 17 ------- tests/CustomConfigUser.php | 17 ------- tests/Environment/BaseUser.php | 16 +++++++ tests/Environment/CustomColumnUser.php | 17 +++++++ tests/Environment/CustomConfigUser.php | 14 ++++++ tests/Environment/DefaultUser.php | 9 ++++ tests/Environment/TestDatabaseSeeder.php | 24 ++++++++++ tests/Environment/TraitedUser.php | 12 +++++ ...0_12_000000_create_custom_column_table.php | 33 ++++++++++++++ .../2014_10_12_000000_create_users_table.php | 33 ++++++++++++++ tests/GeneratorTest.php | 44 ++++++++++++++----- tests/SomeUser.php | 12 ----- tests/TestModel.php | 27 ------------ tests/TestMultipleUser.php | 32 -------------- tests/TestUser.php | 10 ----- 15 files changed, 190 insertions(+), 127 deletions(-) delete mode 100644 tests/CustomColumn.php delete mode 100644 tests/CustomConfigUser.php create mode 100644 tests/Environment/BaseUser.php create mode 100644 tests/Environment/CustomColumnUser.php create mode 100644 tests/Environment/CustomConfigUser.php create mode 100644 tests/Environment/DefaultUser.php create mode 100644 tests/Environment/TestDatabaseSeeder.php create mode 100644 tests/Environment/TraitedUser.php create mode 100644 tests/Environment/migrations/2014_10_12_000000_create_custom_column_table.php create mode 100644 tests/Environment/migrations/2014_10_12_000000_create_users_table.php delete mode 100644 tests/SomeUser.php delete mode 100644 tests/TestModel.php delete mode 100644 tests/TestMultipleUser.php delete mode 100644 tests/TestUser.php diff --git a/tests/CustomColumn.php b/tests/CustomColumn.php deleted file mode 100644 index 0addcb1..0000000 --- a/tests/CustomColumn.php +++ /dev/null @@ -1,17 +0,0 @@ - 'Custom Column', 'identifier' => null]; - - public function generatorConfig(&$generator) - { - $generator->setConfig(['unique' => true, 'separator' => '*', 'column' => 'identifier']); - } -} diff --git a/tests/CustomConfigUser.php b/tests/CustomConfigUser.php deleted file mode 100644 index e586067..0000000 --- a/tests/CustomConfigUser.php +++ /dev/null @@ -1,17 +0,0 @@ - 'Custom Config', 'username' => null]; - - public function generatorConfig(&$generator) - { - $generator->setConfig(['unique'=> false, 'separator' => '_']); - } -} diff --git a/tests/Environment/BaseUser.php b/tests/Environment/BaseUser.php new file mode 100644 index 0000000..5968185 --- /dev/null +++ b/tests/Environment/BaseUser.php @@ -0,0 +1,16 @@ +setConfig(['unique' => true, 'separator' => '*', 'column' => 'identifier', 'model' => $this]); + } +} \ No newline at end of file diff --git a/tests/Environment/CustomConfigUser.php b/tests/Environment/CustomConfigUser.php new file mode 100644 index 0000000..f5d0ac8 --- /dev/null +++ b/tests/Environment/CustomConfigUser.php @@ -0,0 +1,14 @@ +setConfig('separator', '_'); + $generator->setConfig('unique', false); + } +} \ No newline at end of file diff --git a/tests/Environment/DefaultUser.php b/tests/Environment/DefaultUser.php new file mode 100644 index 0000000..9de9509 --- /dev/null +++ b/tests/Environment/DefaultUser.php @@ -0,0 +1,9 @@ + 'Test User', 'username' => 'testuser']); + BaseUser::create(['name' => 'Test User', 'username' => 'test_user']); + BaseUser::create(['name' => 'Custom Config', 'username' => 'custom_config']); + BaseUser::create(['name' => 'Multi Test', 'username' => 'multitest']); + BaseUser::create(['name' => 'Multi Test', 'username' => 'multitest1']); + + CustomColumnUser::create(['name' => 'Custom Column', 'identifier' => 'custom*column']); + } +} \ No newline at end of file diff --git a/tests/Environment/TraitedUser.php b/tests/Environment/TraitedUser.php new file mode 100644 index 0000000..e62b71f --- /dev/null +++ b/tests/Environment/TraitedUser.php @@ -0,0 +1,12 @@ +increments('id')->index(); + $table->string('name'); + $table->string('identifier')->unique()->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('users'); + } +} diff --git a/tests/Environment/migrations/2014_10_12_000000_create_users_table.php b/tests/Environment/migrations/2014_10_12_000000_create_users_table.php new file mode 100644 index 0000000..df7f3d5 --- /dev/null +++ b/tests/Environment/migrations/2014_10_12_000000_create_users_table.php @@ -0,0 +1,33 @@ +increments('id')->index(); + $table->string('name'); + $table->string('username')->unique()->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('users'); + } +} diff --git a/tests/GeneratorTest.php b/tests/GeneratorTest.php index a66d49f..3c6c4ee 100644 --- a/tests/GeneratorTest.php +++ b/tests/GeneratorTest.php @@ -4,6 +4,11 @@ use Gen; use Orchestra\Testbench\TestCase; +use TaylorNetwork\Tests\Environment\CustomColumnUser; +use TaylorNetwork\Tests\Environment\CustomConfigUser; +use TaylorNetwork\Tests\Environment\DefaultUser; +use TaylorNetwork\Tests\Environment\TestDatabaseSeeder; +use TaylorNetwork\Tests\Environment\TraitedUser; use TaylorNetwork\UsernameGenerator\Facades\UsernameGenerator; use TaylorNetwork\UsernameGenerator\Generator; use TaylorNetwork\UsernameGenerator\ServiceProvider; @@ -22,7 +27,22 @@ protected function getPackageAliases($app) protected function getEnvironmentSetUp($app) { - $app['config']->set('username_generator.model', TestUser::class); + $app['config']->set('username_generator.model', DefaultUser::class); + + // Setup default database to use sqlite :memory: + $app['config']->set('database.default', 'testbench'); + $app['config']->set('database.connections.testbench', [ + 'driver' => 'sqlite', + 'database' => ':memory:', + 'prefix' => '', + ]); + } + + protected function setUp(): void + { + parent::setUp(); + $this->loadMigrationsFrom(implode(DIRECTORY_SEPARATOR, [__DIR__, 'Environment', 'migrations'])); + $this->seed(TestDatabaseSeeder::class); } public function testDefaultConfig() @@ -52,21 +72,21 @@ public function testUppercaseUniqueSeparator() public function testGenerateForModel() { $g = new Generator(); - $this->assertEquals('testuser1', $g->generateFor(new TestUser())); + $this->assertEquals('testuser1', $g->generateFor(new DefaultUser([ 'name' => 'Test User' ]))); } public function testTrait() { - $model = new SomeUser(); + $model = new TraitedUser([ 'name' => 'Test User']); $model->generateUsername(); - $this->assertEquals('someuser1', $model->attributes['username']); + $this->assertEquals('testuser1', $model->getAttribute('username')); } public function testTraitConfig() { - $model = new CustomConfigUser(); + $model = new CustomConfigUser([ 'name' => 'Custom Config']); $model->generateUsername(); - $this->assertEquals('custom_config', $model->attributes['username']); + $this->assertEquals('custom_config', $model->getAttribute('username')); } public function testTrimOtherChars() @@ -77,14 +97,14 @@ public function testTrimOtherChars() public function testUniqueMultiple() { - $model = new TestMultipleUser(); + $model = new TraitedUser(['name' => 'Multi Test' ]); $model->generateUsername(); - $this->assertEquals('testuser2', $model->attributes['username']); + $this->assertEquals('multitest2', $model->getAttribute('username')); } public function testTrimCharsWithSeparator() { - $g = new Generator(['separator' => '-', 'unique' => false]); + $g = new Generator(['separator' => '-']); $this->assertEquals('this-is-a-test-user', $g->generate('1THIS iS 1^^*A *T(E)s$t USER!***((( ')); } @@ -112,7 +132,7 @@ public function testSetDriver() public function testAllowExtraChars() { - $generator = new Generator(['allowed_characters' => 'a-zA-Z0-9_\- ', 'unique' => false]); + $generator = new Generator(['allowed_characters' => 'a-zA-Z0-9_\- ']); $this->assertEquals('use-r_test777', $generator->usingEmail()->generate('use-r_test777@example.com')); } @@ -130,9 +150,9 @@ public function testIgnoreMinLength() public function testCustomColumn() { - $model = new CustomColumn(); + $model = new CustomColumnUser([ 'name' => 'Custom Column' ]); $model->generateUsername(); - $this->assertEquals('custom*column*1', $model->attributes['identifier']); + $this->assertEquals('custom*column*1', $model->getAttribute('identifier')); } public function testRandom() diff --git a/tests/SomeUser.php b/tests/SomeUser.php deleted file mode 100644 index 5b465f4..0000000 --- a/tests/SomeUser.php +++ /dev/null @@ -1,12 +0,0 @@ - 'Some User', 'username' => null]; -} diff --git a/tests/TestModel.php b/tests/TestModel.php deleted file mode 100644 index 9fb0414..0000000 --- a/tests/TestModel.php +++ /dev/null @@ -1,27 +0,0 @@ -attributes]; - } - - public function getAttribute($attribute) - { - return $this->attributes[$attribute]; - } -} diff --git a/tests/TestMultipleUser.php b/tests/TestMultipleUser.php deleted file mode 100644 index cdb3b5f..0000000 --- a/tests/TestMultipleUser.php +++ /dev/null @@ -1,32 +0,0 @@ - 'Test User', 'username' => null]; - - public function get() - { - return [ - [ - 'name' => 'Test User', - 'username' => 'testuser', - ], - - [ - 'name' => 'Test User', - 'username' => 'testuser1', - ], - ]; - } - - public function generatorConfig(&$generator) - { - $generator->setConfig('model', $this); - } -} diff --git a/tests/TestUser.php b/tests/TestUser.php deleted file mode 100644 index 8219c73..0000000 --- a/tests/TestUser.php +++ /dev/null @@ -1,10 +0,0 @@ - 'Test User', 'username' => 'testuser']; - - public $name = 'Test User'; -} From 771450fdf5a0a2c687c26fbf9716829737e4aeb7 Mon Sep 17 00:00:00 2001 From: Sam Taylor Date: Fri, 13 Nov 2020 14:53:23 +0000 Subject: [PATCH 03/21] Apply fixes from StyleCI --- src/FindSimilarUsernames.php | 3 ++- src/config/username_generator.php | 2 +- tests/Environment/BaseUser.php | 3 +-- tests/Environment/CustomColumnUser.php | 4 +--- tests/Environment/CustomConfigUser.php | 4 +--- tests/Environment/DefaultUser.php | 4 +--- tests/Environment/TestDatabaseSeeder.php | 2 +- tests/Environment/TraitedUser.php | 4 +--- tests/GeneratorTest.php | 10 +++++----- 9 files changed, 14 insertions(+), 22 deletions(-) diff --git a/src/FindSimilarUsernames.php b/src/FindSimilarUsernames.php index 1109dec..98b138e 100644 --- a/src/FindSimilarUsernames.php +++ b/src/FindSimilarUsernames.php @@ -20,7 +20,7 @@ public function findSimilarUsernames($username) { $preferRegexp = $this->preferRegexp ?? config('username_generator.prefer_regexp', true); - if(!$preferRegexp) { + if (!$preferRegexp) { return $this->searchUsingLike($username); } @@ -45,6 +45,7 @@ private function searchUsingLike($username) private function searchUsingRegexp($username) { $column = $this->getColumn(); + return static::whereRaw("$column REGEXP '{$username}([0-9]*)?$'")->get(); } diff --git a/src/config/username_generator.php b/src/config/username_generator.php index cf2b50c..085bddc 100644 --- a/src/config/username_generator.php +++ b/src/config/username_generator.php @@ -53,7 +53,7 @@ 'allowed_characters' => 'a-zA-Z ', /* - * Prefer using REGEXP + * Prefer using REGEXP */ 'prefer_regexp' => true, diff --git a/tests/Environment/BaseUser.php b/tests/Environment/BaseUser.php index 5968185..1ad8a3f 100644 --- a/tests/Environment/BaseUser.php +++ b/tests/Environment/BaseUser.php @@ -1,6 +1,5 @@ setConfig(['unique' => true, 'separator' => '*', 'column' => 'identifier', 'model' => $this]); } -} \ No newline at end of file +} diff --git a/tests/Environment/CustomConfigUser.php b/tests/Environment/CustomConfigUser.php index f5d0ac8..983c67f 100644 --- a/tests/Environment/CustomConfigUser.php +++ b/tests/Environment/CustomConfigUser.php @@ -1,9 +1,7 @@ setConfig('separator', '_'); $generator->setConfig('unique', false); } -} \ No newline at end of file +} diff --git a/tests/Environment/DefaultUser.php b/tests/Environment/DefaultUser.php index 9de9509..2d405f8 100644 --- a/tests/Environment/DefaultUser.php +++ b/tests/Environment/DefaultUser.php @@ -1,9 +1,7 @@ 'Custom Column', 'identifier' => 'custom*column']); } -} \ No newline at end of file +} diff --git a/tests/Environment/TraitedUser.php b/tests/Environment/TraitedUser.php index e62b71f..20b83b1 100644 --- a/tests/Environment/TraitedUser.php +++ b/tests/Environment/TraitedUser.php @@ -1,12 +1,10 @@ assertEquals('testuser1', $g->generateFor(new DefaultUser([ 'name' => 'Test User' ]))); + $this->assertEquals('testuser1', $g->generateFor(new DefaultUser(['name' => 'Test User']))); } public function testTrait() { - $model = new TraitedUser([ 'name' => 'Test User']); + $model = new TraitedUser(['name' => 'Test User']); $model->generateUsername(); $this->assertEquals('testuser1', $model->getAttribute('username')); } public function testTraitConfig() { - $model = new CustomConfigUser([ 'name' => 'Custom Config']); + $model = new CustomConfigUser(['name' => 'Custom Config']); $model->generateUsername(); $this->assertEquals('custom_config', $model->getAttribute('username')); } @@ -97,7 +97,7 @@ public function testTrimOtherChars() public function testUniqueMultiple() { - $model = new TraitedUser(['name' => 'Multi Test' ]); + $model = new TraitedUser(['name' => 'Multi Test']); $model->generateUsername(); $this->assertEquals('multitest2', $model->getAttribute('username')); } @@ -150,7 +150,7 @@ public function testIgnoreMinLength() public function testCustomColumn() { - $model = new CustomColumnUser([ 'name' => 'Custom Column' ]); + $model = new CustomColumnUser(['name' => 'Custom Column']); $model->generateUsername(); $this->assertEquals('custom*column*1', $model->getAttribute('identifier')); } From 20a75f68fabc93d796e2d37b94c6e58bb7599eb4 Mon Sep 17 00:00:00 2001 From: Sam Taylor Date: Sat, 14 Nov 2020 09:21:23 -0500 Subject: [PATCH 04/21] Added usernames will be checked if filled out by user - this will make a user entered username conform with generator config as well as make it unique (if turned on) - that feature is also optional and in the config under 'generate_entered_username' --- src/GeneratesUsernames.php | 28 ++++++++++++++++++------ src/config/username_generator.php | 9 ++++++++ tests/Environment/TestDatabaseSeeder.php | 3 ++- tests/GeneratorTest.php | 12 ++++++++-- 4 files changed, 42 insertions(+), 10 deletions(-) diff --git a/src/GeneratesUsernames.php b/src/GeneratesUsernames.php index ee575fa..65c3986 100644 --- a/src/GeneratesUsernames.php +++ b/src/GeneratesUsernames.php @@ -27,11 +27,9 @@ public function generateUsername(): void $column = $generator->getConfig('column', 'username'); if (empty($this->getAttribute($column))) { - try { - $this->attributes[$column] = $generator->generate($this->getField()); - } catch (Exception $e) { - // Failed but don't halt saving the model - } + $this->updateUsername($generator, $column, $this->getField()); + } elseif ($generator->getConfig('generate_entered_username', true)) { + $this->updateUsername($generator, $column, $this->getAttribute($column)); } } @@ -42,7 +40,7 @@ public function generateUsername(): void * * @return string|null */ - public function getField() + public function getField(): ?string { // Support pre-v2 getName method overrides if (method_exists($this, 'getName')) { @@ -67,8 +65,24 @@ public function generatorFieldName(): string * * @param Generator $generator */ - public function generatorConfig(&$generator): void + public function generatorConfig(Generator &$generator): void { // $generator->setConfig('separator', '_'); } + + /** + * Attempt to update the username attribute. + * + * @param Generator $generator + * @param string $column + * @param string|null $field + */ + private function updateUsername(Generator &$generator, string $column, ?string $field = null) + { + try { + $this->attributes[$column] = $generator->generate($field); + } catch (Exception $e) { + // Failed but don't halt saving the model + } + } } diff --git a/src/config/username_generator.php b/src/config/username_generator.php index 085bddc..5797c3c 100644 --- a/src/config/username_generator.php +++ b/src/config/username_generator.php @@ -52,6 +52,15 @@ */ 'allowed_characters' => 'a-zA-Z ', + /* + * Run the generator even if the username was provided by the user? + * Only used with GeneratesUsernames Trait. + * This would be useful to maintain congruency in usernames even + * if someone enters their own. If set to false, when the username + * field is not empty then the generator will not run. + */ + 'generate_entered_username' => true, + /* * Prefer using REGEXP */ diff --git a/tests/Environment/TestDatabaseSeeder.php b/tests/Environment/TestDatabaseSeeder.php index 5ec6665..18260e8 100644 --- a/tests/Environment/TestDatabaseSeeder.php +++ b/tests/Environment/TestDatabaseSeeder.php @@ -19,6 +19,7 @@ public function run() BaseUser::create(['name' => 'Multi Test', 'username' => 'multitest']); BaseUser::create(['name' => 'Multi Test', 'username' => 'multitest1']); - CustomColumnUser::create(['name' => 'Custom Column', 'identifier' => 'custom*column']); + CustomColumnUser::create(['name' => 'Custom Column']); + CustomColumnUser::create(['name' => 'Custom Column']); } } diff --git a/tests/GeneratorTest.php b/tests/GeneratorTest.php index a29efda..2af08ff 100644 --- a/tests/GeneratorTest.php +++ b/tests/GeneratorTest.php @@ -4,6 +4,7 @@ use Gen; use Orchestra\Testbench\TestCase; +use TaylorNetwork\Tests\Environment\BaseUser; use TaylorNetwork\Tests\Environment\CustomColumnUser; use TaylorNetwork\Tests\Environment\CustomConfigUser; use TaylorNetwork\Tests\Environment\DefaultUser; @@ -148,15 +149,22 @@ public function testIgnoreMinLength() $this->assertEquals('t', UsernameGenerator::setConfig('unique', false)->generate('T')); } - public function testCustomColumn() + public function testCustomColumnMultiple() { $model = new CustomColumnUser(['name' => 'Custom Column']); $model->generateUsername(); - $this->assertEquals('custom*column*1', $model->getAttribute('identifier')); + $this->assertEquals('custom*column*2', $model->getAttribute('identifier')); } public function testRandom() { $this->assertIsString(UsernameGenerator::generate()); } + + public function testModelEmptyName() + { + $model = new TraitedUser(); + $model->generateUsername(); + $this->assertIsString($model->getAttribute('username')); + } } From 84f5f543ca85d91d68aac5eb004a10879261c604 Mon Sep 17 00:00:00 2001 From: Sam Taylor Date: Sat, 14 Nov 2020 09:56:12 -0500 Subject: [PATCH 05/21] Update generatorFor to be more accurate and add appropriate tests --- src/GeneratesUsernames.php | 2 +- src/Generator.php | 33 +++++++++---------- src/Support/GeneratorException.php | 11 +++++++ tests/Environment/EmailUser.php | 10 ++++++ tests/Environment/TestDatabaseSeeder.php | 3 ++ ...0_12_000000_create_custom_column_table.php | 2 +- ...4_10_12_000000_create_user_email_table.php | 33 +++++++++++++++++++ tests/GeneratorTest.php | 17 +++++++++- 8 files changed, 91 insertions(+), 20 deletions(-) create mode 100644 src/Support/GeneratorException.php create mode 100644 tests/Environment/EmailUser.php create mode 100644 tests/Environment/migrations/2014_10_12_000000_create_user_email_table.php diff --git a/src/GeneratesUsernames.php b/src/GeneratesUsernames.php index 65c3986..c296309 100644 --- a/src/GeneratesUsernames.php +++ b/src/GeneratesUsernames.php @@ -77,7 +77,7 @@ public function generatorConfig(Generator &$generator): void * @param string $column * @param string|null $field */ - private function updateUsername(Generator &$generator, string $column, ?string $field = null) + private function updateUsername(Generator &$generator, string $column, ?string $field = null): void { try { $this->attributes[$column] = $generator->generate($field); diff --git a/src/Generator.php b/src/Generator.php index 25bd152..135811e 100644 --- a/src/Generator.php +++ b/src/Generator.php @@ -4,6 +4,7 @@ use Illuminate\Support\Arr; use TaylorNetwork\UsernameGenerator\Drivers\BaseDriver; +use TaylorNetwork\UsernameGenerator\Support\GeneratorException; use TaylorNetwork\UsernameGenerator\Support\LoadsConfig; class Generator @@ -31,11 +32,11 @@ public function __construct(array $config = []) /** * Generate a username. * - * @param string $text + * @param string|null $text * * @return string */ - public function generate(string $text = null): string + public function generate(?string $text = null): string { if (!isset($this->driver)) { $this->driver = Arr::first($this->getConfig('drivers')); @@ -50,29 +51,27 @@ public function generate(string $text = null): string * @param object $model * * @return string + * @throws GeneratorException */ public function generateFor($model): string { $drivers = $this->getConfig('drivers'); if (!isset($this->driver)) { - foreach ($drivers as $key => $driver) { - if (!empty($model->$key)) { - $field = $key; - break; - } - } + foreach ($drivers as $driver) { + $driverInstance = new $driver; + $field = $driverInstance->field; - if (!isset($field)) { - return false; + if (!empty($model->$field)) { + return $driverInstance->withConfig($this->config())->generate($model->$field); + } } - - return (new $drivers[$field]())->withConfig($this->config())->generate($model->$field); + throw new GeneratorException('Could not find driver to use for \'generateFor\' method. Set one by using \'setDriver\' method.'); } - $field = array_search($this->driver, $drivers); - - return (new $this->driver())->withConfig($this->config())->generate($model->$field); + $driverInstance = new $this->driver(); + $field = $driverInstance->field; + return $driverInstance->withConfig($this->config())->generate($model->$field); } /** @@ -123,11 +122,11 @@ public static function __callStatic($name, $arguments) * Handle __call and __callStatic. * * @param string $name - * @param mixed $arguments + * @param mixed $arguments * * @return mixed */ - private function caller($name, $arguments) + private function caller(string $name, $arguments) { $drivers = $this->getConfig('drivers'); diff --git a/src/Support/GeneratorException.php b/src/Support/GeneratorException.php new file mode 100644 index 0000000..3a51004 --- /dev/null +++ b/src/Support/GeneratorException.php @@ -0,0 +1,11 @@ + 'Custom Column']); CustomColumnUser::create(['name' => 'Custom Column']); + + EmailUser::create(['email' => 'test_user@example.com', 'username' => 'testuser']); + EmailUser::create(['email' => 'test.user@example.com', 'username' => 'testuser1']); } } diff --git a/tests/Environment/migrations/2014_10_12_000000_create_custom_column_table.php b/tests/Environment/migrations/2014_10_12_000000_create_custom_column_table.php index 697b6b6..a536ae6 100644 --- a/tests/Environment/migrations/2014_10_12_000000_create_custom_column_table.php +++ b/tests/Environment/migrations/2014_10_12_000000_create_custom_column_table.php @@ -28,6 +28,6 @@ public function up() */ public function down() { - Schema::dropIfExists('users'); + Schema::dropIfExists('custom_column'); } } diff --git a/tests/Environment/migrations/2014_10_12_000000_create_user_email_table.php b/tests/Environment/migrations/2014_10_12_000000_create_user_email_table.php new file mode 100644 index 0000000..485db7d --- /dev/null +++ b/tests/Environment/migrations/2014_10_12_000000_create_user_email_table.php @@ -0,0 +1,33 @@ +increments('id')->index(); + $table->string('email'); + $table->string('username')->unique()->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('user_email'); + } +} diff --git a/tests/GeneratorTest.php b/tests/GeneratorTest.php index 2af08ff..a0defd0 100644 --- a/tests/GeneratorTest.php +++ b/tests/GeneratorTest.php @@ -4,10 +4,10 @@ use Gen; use Orchestra\Testbench\TestCase; -use TaylorNetwork\Tests\Environment\BaseUser; use TaylorNetwork\Tests\Environment\CustomColumnUser; use TaylorNetwork\Tests\Environment\CustomConfigUser; use TaylorNetwork\Tests\Environment\DefaultUser; +use TaylorNetwork\Tests\Environment\EmailUser; use TaylorNetwork\Tests\Environment\TestDatabaseSeeder; use TaylorNetwork\Tests\Environment\TraitedUser; use TaylorNetwork\UsernameGenerator\Facades\UsernameGenerator; @@ -167,4 +167,19 @@ public function testModelEmptyName() $model->generateUsername(); $this->assertIsString($model->getAttribute('username')); } + + public function testGenerateForUsingEmail() + { + $g = new Generator([ 'model' => EmailUser::class ]); + $username = $g->generateFor(new EmailUser(['email' => 'testuser@exmaple.com'])); + $this->assertEquals('testuser2', $username); + } + + public function testGenerateForUsingSetDriver() + { + $g = new Generator([ 'model' => EmailUser::class ]); + $g->setDriver('email'); + $username = $g->generateFor(new EmailUser(['email' => 'testuser@exmaple.com'])); + $this->assertEquals('testuser2', $username); + } } From 4fad50ec787c3f241ae6f4978c812ef1556503a1 Mon Sep 17 00:00:00 2001 From: Sam Taylor Date: Sat, 14 Nov 2020 14:57:33 +0000 Subject: [PATCH 06/21] Apply fixes from StyleCI --- src/GeneratesUsernames.php | 4 ++-- src/Generator.php | 9 ++++++--- src/Support/GeneratorException.php | 4 +--- tests/Environment/EmailUser.php | 4 +--- tests/GeneratorTest.php | 4 ++-- 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/GeneratesUsernames.php b/src/GeneratesUsernames.php index c296309..b4db5c3 100644 --- a/src/GeneratesUsernames.php +++ b/src/GeneratesUsernames.php @@ -73,8 +73,8 @@ public function generatorConfig(Generator &$generator): void /** * Attempt to update the username attribute. * - * @param Generator $generator - * @param string $column + * @param Generator $generator + * @param string $column * @param string|null $field */ private function updateUsername(Generator &$generator, string $column, ?string $field = null): void diff --git a/src/Generator.php b/src/Generator.php index 135811e..5c1776f 100644 --- a/src/Generator.php +++ b/src/Generator.php @@ -50,8 +50,9 @@ public function generate(?string $text = null): string * * @param object $model * - * @return string * @throws GeneratorException + * + * @return string */ public function generateFor($model): string { @@ -59,18 +60,20 @@ public function generateFor($model): string if (!isset($this->driver)) { foreach ($drivers as $driver) { - $driverInstance = new $driver; + $driverInstance = new $driver(); $field = $driverInstance->field; if (!empty($model->$field)) { return $driverInstance->withConfig($this->config())->generate($model->$field); } } + throw new GeneratorException('Could not find driver to use for \'generateFor\' method. Set one by using \'setDriver\' method.'); } $driverInstance = new $this->driver(); $field = $driverInstance->field; + return $driverInstance->withConfig($this->config())->generate($model->$field); } @@ -122,7 +125,7 @@ public static function __callStatic($name, $arguments) * Handle __call and __callStatic. * * @param string $name - * @param mixed $arguments + * @param mixed $arguments * * @return mixed */ diff --git a/src/Support/GeneratorException.php b/src/Support/GeneratorException.php index 3a51004..80ff0a6 100644 --- a/src/Support/GeneratorException.php +++ b/src/Support/GeneratorException.php @@ -1,11 +1,9 @@ EmailUser::class ]); + $g = new Generator(['model' => EmailUser::class]); $username = $g->generateFor(new EmailUser(['email' => 'testuser@exmaple.com'])); $this->assertEquals('testuser2', $username); } public function testGenerateForUsingSetDriver() { - $g = new Generator([ 'model' => EmailUser::class ]); + $g = new Generator(['model' => EmailUser::class]); $g->setDriver('email'); $username = $g->generateFor(new EmailUser(['email' => 'testuser@exmaple.com'])); $this->assertEquals('testuser2', $username); From f1f337d7540588cf59083ad4792d4101cd10fabc Mon Sep 17 00:00:00 2001 From: Sam Taylor Date: Sat, 14 Nov 2020 22:11:34 -0500 Subject: [PATCH 07/21] Create LICENSE --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..dc3efd8 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 TaylorNetwork + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 7c45b271ce302f0ebea99d9ad6ada0f080e4fc48 Mon Sep 17 00:00:00 2001 From: Sam Taylor Date: Thu, 19 Nov 2020 19:28:02 -0500 Subject: [PATCH 08/21] Added field_map config option --- src/Generator.php | 57 +++++++++++++++++-- src/config/username_generator.php | 16 ++++++ tests/Environment/CustomFieldUser.php | 10 ++++ tests/Environment/TestDatabaseSeeder.php | 2 + ...10_12_000000_create_custom_users_table.php | 33 +++++++++++ tests/GeneratorTest.php | 27 +++++++++ 6 files changed, 141 insertions(+), 4 deletions(-) create mode 100644 tests/Environment/CustomFieldUser.php create mode 100644 tests/Environment/migrations/2014_10_12_000000_create_custom_users_table.php diff --git a/src/Generator.php b/src/Generator.php index 5c1776f..03932b6 100644 --- a/src/Generator.php +++ b/src/Generator.php @@ -50,9 +50,9 @@ public function generate(?string $text = null): string * * @param object $model * - * @throws GeneratorException - * * @return string + * @throws GeneratorException|Support\UsernameTooShortException + * */ public function generateFor($model): string { @@ -64,8 +64,13 @@ public function generateFor($model): string $field = $driverInstance->field; if (!empty($model->$field)) { - return $driverInstance->withConfig($this->config())->generate($model->$field); + return $this->forwardCallToDriver($driverInstance, $model->$field); + } + + if($mappedField = $this->getMappedField($field, $model)) { + return $this->forwardCallToDriver($driverInstance, $model->$mappedField); } + } throw new GeneratorException('Could not find driver to use for \'generateFor\' method. Set one by using \'setDriver\' method.'); @@ -74,7 +79,51 @@ public function generateFor($model): string $driverInstance = new $this->driver(); $field = $driverInstance->field; - return $driverInstance->withConfig($this->config())->generate($model->$field); + return $this->forwardCallToDriver($driverInstance, $model->$field); + } + + /** + * Get the usable field on the model from the field map. + * + * @param string $field + * @param object $model + * @return string|null + */ + protected function getMappedField(string $field, $model): ?string + { + $map = $this->getConfig('field_map'); + + if (array_key_exists($field, $map)) { + if (is_array($map[$field])) { + foreach ($map[$field] as $mappedField) { + if (!empty($model->$mappedField)) { + return $mappedField; + } + } + } else { + $mappedField = $map[$field]; + return empty($model->$mappedField) ?: $mappedField; + } + } + + return null; + } + + /** + * Forward the generate call to the selected driver. + * + * @param string|BaseDriver $driver + * @param string|null $text + * @return string + * @throws Support\UsernameTooShortException + */ + protected function forwardCallToDriver($driver, ?string $text): string + { + if (gettype($driver) === 'string') { + $driver = new $driver(); + } + + return $driver->withConfig($this->config())->generate($text); } /** diff --git a/src/config/username_generator.php b/src/config/username_generator.php index 5797c3c..8841a87 100644 --- a/src/config/username_generator.php +++ b/src/config/username_generator.php @@ -66,6 +66,22 @@ */ 'prefer_regexp' => true, + /* + * Field Map + * + * This is really only used when using generateFor(). + * + * If the default "name" field for your model is not "name" you can create a + * field map here. When looking for the "name" field, if not found, will check + * the "fullName" field. You can have the same effect by adding a "name" attribute + * to the model in question (ie. getNameAttribute) + * + * 'field_map' => [ + * 'name' => 'fullName', + * ], + */ + 'field_map' => [], + /* * Loaded drivers for converting to a username */ diff --git a/tests/Environment/CustomFieldUser.php b/tests/Environment/CustomFieldUser.php new file mode 100644 index 0000000..2ea2f3b --- /dev/null +++ b/tests/Environment/CustomFieldUser.php @@ -0,0 +1,10 @@ + 'test_user@example.com', 'username' => 'testuser']); EmailUser::create(['email' => 'test.user@example.com', 'username' => 'testuser1']); + + CustomFieldUser::create(['fullName' => 'Test User', 'username' => 'testuser']); } } diff --git a/tests/Environment/migrations/2014_10_12_000000_create_custom_users_table.php b/tests/Environment/migrations/2014_10_12_000000_create_custom_users_table.php new file mode 100644 index 0000000..262be9c --- /dev/null +++ b/tests/Environment/migrations/2014_10_12_000000_create_custom_users_table.php @@ -0,0 +1,33 @@ +increments('id')->index(); + $table->string('fullName'); + $table->string('username')->unique()->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('custom_users'); + } +} diff --git a/tests/GeneratorTest.php b/tests/GeneratorTest.php index 1e26763..3b4d202 100644 --- a/tests/GeneratorTest.php +++ b/tests/GeneratorTest.php @@ -6,6 +6,7 @@ use Orchestra\Testbench\TestCase; use TaylorNetwork\Tests\Environment\CustomColumnUser; use TaylorNetwork\Tests\Environment\CustomConfigUser; +use TaylorNetwork\Tests\Environment\CustomFieldUser; use TaylorNetwork\Tests\Environment\DefaultUser; use TaylorNetwork\Tests\Environment\EmailUser; use TaylorNetwork\Tests\Environment\TestDatabaseSeeder; @@ -182,4 +183,30 @@ public function testGenerateForUsingSetDriver() $username = $g->generateFor(new EmailUser(['email' => 'testuser@exmaple.com'])); $this->assertEquals('testuser2', $username); } + + public function testGenerateForWithFieldMapString() + { + $g = new Generator([ + 'model' => CustomFieldUser::class, + 'field_map' => [ + 'name' => 'fullName' + ] + ]); + + $username = $g->generateFor(new CustomFieldUser(['fullName' => 'Test User'])); + $this->assertEquals('testuser1', $username); + } + + public function testGenerateForWithFieldMapArray() + { + $g = new Generator([ + 'model' => CustomFieldUser::class, + 'field_map' => [ + 'name' => ['fullName'] + ] + ]); + + $username = $g->generateFor(new CustomFieldUser(['fullName' => 'Test User'])); + $this->assertEquals('testuser1', $username); + } } From cf80c598817f61cf61937afdefc7419feacfc94a Mon Sep 17 00:00:00 2001 From: Sam Taylor Date: Fri, 20 Nov 2020 00:28:51 +0000 Subject: [PATCH 09/21] Apply fixes from StyleCI --- src/Generator.php | 13 ++++++++----- tests/Environment/CustomFieldUser.php | 4 +--- tests/GeneratorTest.php | 12 ++++++------ 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/Generator.php b/src/Generator.php index 03932b6..e36ed34 100644 --- a/src/Generator.php +++ b/src/Generator.php @@ -50,9 +50,9 @@ public function generate(?string $text = null): string * * @param object $model * - * @return string * @throws GeneratorException|Support\UsernameTooShortException * + * @return string */ public function generateFor($model): string { @@ -67,10 +67,9 @@ public function generateFor($model): string return $this->forwardCallToDriver($driverInstance, $model->$field); } - if($mappedField = $this->getMappedField($field, $model)) { + if ($mappedField = $this->getMappedField($field, $model)) { return $this->forwardCallToDriver($driverInstance, $model->$mappedField); } - } throw new GeneratorException('Could not find driver to use for \'generateFor\' method. Set one by using \'setDriver\' method.'); @@ -87,6 +86,7 @@ public function generateFor($model): string * * @param string $field * @param object $model + * * @return string|null */ protected function getMappedField(string $field, $model): ?string @@ -102,6 +102,7 @@ protected function getMappedField(string $field, $model): ?string } } else { $mappedField = $map[$field]; + return empty($model->$mappedField) ?: $mappedField; } } @@ -113,9 +114,11 @@ protected function getMappedField(string $field, $model): ?string * Forward the generate call to the selected driver. * * @param string|BaseDriver $driver - * @param string|null $text - * @return string + * @param string|null $text + * * @throws Support\UsernameTooShortException + * + * @return string */ protected function forwardCallToDriver($driver, ?string $text): string { diff --git a/tests/Environment/CustomFieldUser.php b/tests/Environment/CustomFieldUser.php index 2ea2f3b..7c9ce83 100644 --- a/tests/Environment/CustomFieldUser.php +++ b/tests/Environment/CustomFieldUser.php @@ -1,10 +1,8 @@ CustomFieldUser::class, + 'model' => CustomFieldUser::class, 'field_map' => [ - 'name' => 'fullName' - ] + 'name' => 'fullName', + ], ]); $username = $g->generateFor(new CustomFieldUser(['fullName' => 'Test User'])); @@ -200,10 +200,10 @@ public function testGenerateForWithFieldMapString() public function testGenerateForWithFieldMapArray() { $g = new Generator([ - 'model' => CustomFieldUser::class, + 'model' => CustomFieldUser::class, 'field_map' => [ - 'name' => ['fullName'] - ] + 'name' => ['fullName'], + ], ]); $username = $g->generateFor(new CustomFieldUser(['fullName' => 'Test User'])); From 58bd21a0c248ef2aece2d92951bc84459ab2be4f Mon Sep 17 00:00:00 2001 From: Sam Taylor Date: Thu, 19 Nov 2020 19:34:52 -0500 Subject: [PATCH 10/21] Added additional test --- tests/GeneratorTest.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/GeneratorTest.php b/tests/GeneratorTest.php index 59b664c..6ea69f4 100644 --- a/tests/GeneratorTest.php +++ b/tests/GeneratorTest.php @@ -209,4 +209,18 @@ public function testGenerateForWithFieldMapArray() $username = $g->generateFor(new CustomFieldUser(['fullName' => 'Test User'])); $this->assertEquals('testuser1', $username); } + + public function testFieldMapExistsButNotUsed() + { + $g = new Generator([ + 'model' => DefaultUser::class, + 'field_map' => [ + 'name' => 'fullName' + ] + ]); + + $username = $g->generateFor(new DefaultUser(['name' => 'Test User'])); + $this->assertEquals('testuser1', $username); + } } + From 614525afa1a487fb226793877182beccb1679532 Mon Sep 17 00:00:00 2001 From: Sam Taylor Date: Thu, 19 Nov 2020 19:36:23 -0500 Subject: [PATCH 11/21] StyleCI --- tests/GeneratorTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/GeneratorTest.php b/tests/GeneratorTest.php index 6ea69f4..5776181 100644 --- a/tests/GeneratorTest.php +++ b/tests/GeneratorTest.php @@ -213,10 +213,10 @@ public function testGenerateForWithFieldMapArray() public function testFieldMapExistsButNotUsed() { $g = new Generator([ - 'model' => DefaultUser::class, + 'model' => DefaultUser::class, 'field_map' => [ - 'name' => 'fullName' - ] + 'name' => 'fullName', + ], ]); $username = $g->generateFor(new DefaultUser(['name' => 'Test User'])); From 74b450ef9d2c7416b7a59074dc066656fd0557c3 Mon Sep 17 00:00:00 2001 From: Sam Taylor Date: Wed, 2 Dec 2020 12:02:12 -0500 Subject: [PATCH 12/21] Added max_length option - Also updated the unique check to see if a username is unique before looking for similar, this fixes the occasional number being added when the original was actually unique but it was similar to others. --- src/Drivers/BaseDriver.php | 49 +++++++++++++++++-- src/FindSimilarUsernames.php | 32 ++++++++++++ src/Generator.php | 16 +++--- .../{ => Exceptions}/GeneratorException.php | 2 +- .../Exceptions/UsernameTooLongException.php | 11 +++++ .../UsernameTooShortException.php | 2 +- src/config/username_generator.php | 12 +++++ tests/Environment/TestDatabaseSeeder.php | 2 + tests/GeneratorTest.php | 35 ++++++++++++- 9 files changed, 148 insertions(+), 13 deletions(-) rename src/Support/{ => Exceptions}/GeneratorException.php (53%) create mode 100644 src/Support/Exceptions/UsernameTooLongException.php rename src/Support/{ => Exceptions}/UsernameTooShortException.php (55%) diff --git a/src/Drivers/BaseDriver.php b/src/Drivers/BaseDriver.php index 7a3102f..925057a 100644 --- a/src/Drivers/BaseDriver.php +++ b/src/Drivers/BaseDriver.php @@ -3,8 +3,10 @@ namespace TaylorNetwork\UsernameGenerator\Drivers; use Illuminate\Support\Str; +use TaylorNetwork\UsernameGenerator\Support\Exceptions\GeneratorException; +use TaylorNetwork\UsernameGenerator\Support\Exceptions\UsernameTooLongException; +use TaylorNetwork\UsernameGenerator\Support\Exceptions\UsernameTooShortException; use TaylorNetwork\UsernameGenerator\Support\LoadsConfig; -use TaylorNetwork\UsernameGenerator\Support\UsernameTooShortException; abstract class BaseDriver { @@ -58,11 +60,10 @@ public function getWord($type = 'noun'): string /** * Generate the username. * - * @param string $text - * - * @throws UsernameTooShortException + * @param string|null $text * * @return string + * @throws UsernameTooShortException|UsernameTooLongException|GeneratorException */ public function generate(string $text = null): string { @@ -82,6 +83,12 @@ public function generate(string $text = null): string } } + if ($this->getConfig('max_length', 0) > 0 && $this->getConfig('max_length',0) > $this->getConfig('min_length')) { + if (strlen($text) > $this->getConfig('max_length', 0)) { + $text = $this->tooLongAction($text); + } + } + return $text; } @@ -107,6 +114,36 @@ public function tooShortAction(string $text): string return $text; } + /** + * Action when username is too long. + * + * @param string $text + * @return string + * @throws UsernameTooLongException|GeneratorException + */ + public function tooLongAction(string $text): string + { + if ($this->getConfig('throw_exception_on_too_long')) { + throw new UsernameTooLongException('Generated username exceeds maximum length of '.$this->getConfig('max_length')); + } + + $lengthValue = $this->getConfig('max_length') + 1; + + while (strlen($text) > $this->getConfig('max_length')) { + $lengthValue--; + + if ($lengthValue === 0) { + throw new GeneratorException('Could not reduce the username to a valid length.'); + } + + $text = substr($text, 0, $lengthValue); + $text = $this->makeUnique($text); + } + + return $text; + } + + /** * Convert the case of the username. * @@ -171,6 +208,10 @@ public function addSeparator(string $text): string public function makeUnique(string $text): string { if ($this->getConfig('unique') && $this->model() && method_exists($this->model(), 'findSimilarUsernames')) { + if (method_exists($this->model(), 'isUsernameUnique') && $this->model()->isUsernameUnique($text)) { + return $text; + } + if (($similar = count($this->model()->findSimilarUsernames($text))) > 0) { return $text.$this->getConfig('separator').$similar; } diff --git a/src/FindSimilarUsernames.php b/src/FindSimilarUsernames.php index 98b138e..dae4636 100644 --- a/src/FindSimilarUsernames.php +++ b/src/FindSimilarUsernames.php @@ -2,6 +2,8 @@ namespace TaylorNetwork\UsernameGenerator; +use Illuminate\Config\Repository; +use Illuminate\Contracts\Foundation\Application; use Illuminate\Database\QueryException; trait FindSimilarUsernames @@ -31,6 +33,23 @@ public function findSimilarUsernames($username) } } + /** + * Check if the username is unique as is. + * + * @param string $username + * @return bool + */ + public function isUsernameUnique(string $username): bool + { + return static::where($this->getColumn(), $username)->get()->count() === 0; + } + + /** + * Search for similar usernames using LIKE. + * + * @param $username + * @return mixed + */ private function searchUsingLike($username) { $exactMatches = static::where($this->getColumn(), $username)->get(); @@ -42,6 +61,14 @@ private function searchUsingLike($username) return $exactMatches; } + /** + * Search for similar usernames using REGEXP. + * + * This will fail on some databases, so like should be used as a backup. + * + * @param $username + * @return mixed + */ private function searchUsingRegexp($username) { $column = $this->getColumn(); @@ -49,6 +76,11 @@ private function searchUsingRegexp($username) return static::whereRaw("$column REGEXP '{$username}([0-9]*)?$'")->get(); } + /** + * Get the username column. + * + * @return Repository|Application|mixed + */ private function getColumn() { return $this->usernameColumn ?? config('username_generator.column', 'username'); diff --git a/src/Generator.php b/src/Generator.php index e36ed34..40a7b3c 100644 --- a/src/Generator.php +++ b/src/Generator.php @@ -4,7 +4,9 @@ use Illuminate\Support\Arr; use TaylorNetwork\UsernameGenerator\Drivers\BaseDriver; -use TaylorNetwork\UsernameGenerator\Support\GeneratorException; +use TaylorNetwork\UsernameGenerator\Support\Exceptions\GeneratorException; +use TaylorNetwork\UsernameGenerator\Support\Exceptions\UsernameTooLongException; +use TaylorNetwork\UsernameGenerator\Support\Exceptions\UsernameTooShortException; use TaylorNetwork\UsernameGenerator\Support\LoadsConfig; class Generator @@ -50,9 +52,10 @@ public function generate(?string $text = null): string * * @param object $model * - * @throws GeneratorException|Support\UsernameTooShortException - * * @return string + * @throws GeneratorException + * @throws UsernameTooLongException + * @throws UsernameTooShortException */ public function generateFor($model): string { @@ -114,11 +117,12 @@ protected function getMappedField(string $field, $model): ?string * Forward the generate call to the selected driver. * * @param string|BaseDriver $driver - * @param string|null $text - * - * @throws Support\UsernameTooShortException + * @param string|null $text * * @return string + * @throws GeneratorException + * @throws UsernameTooLongException + * @throws UsernameTooShortException */ protected function forwardCallToDriver($driver, ?string $text): string { diff --git a/src/Support/GeneratorException.php b/src/Support/Exceptions/GeneratorException.php similarity index 53% rename from src/Support/GeneratorException.php rename to src/Support/Exceptions/GeneratorException.php index 80ff0a6..8cbeea7 100644 --- a/src/Support/GeneratorException.php +++ b/src/Support/Exceptions/GeneratorException.php @@ -1,6 +1,6 @@ false, + /* + * The maximum length of the username. + * + * Set to 0 to not enforce + */ + 'max_length' => 0, + + /* + * Want to throw a UsernameTooLong exception when too long? + */ + 'throw_exception_on_too_long' => false, + /* * Convert the case of the generated username * diff --git a/tests/Environment/TestDatabaseSeeder.php b/tests/Environment/TestDatabaseSeeder.php index f63fc92..7df9d65 100644 --- a/tests/Environment/TestDatabaseSeeder.php +++ b/tests/Environment/TestDatabaseSeeder.php @@ -19,6 +19,8 @@ public function run() BaseUser::create(['name' => 'Multi Test', 'username' => 'multitest']); BaseUser::create(['name' => 'Multi Test', 'username' => 'multitest1']); + BaseUser::create(['name' => 'T', 'username' => 't']); + CustomColumnUser::create(['name' => 'Custom Column']); CustomColumnUser::create(['name' => 'Custom Column']); diff --git a/tests/GeneratorTest.php b/tests/GeneratorTest.php index 5776181..4895986 100644 --- a/tests/GeneratorTest.php +++ b/tests/GeneratorTest.php @@ -14,6 +14,8 @@ use TaylorNetwork\UsernameGenerator\Facades\UsernameGenerator; use TaylorNetwork\UsernameGenerator\Generator; use TaylorNetwork\UsernameGenerator\ServiceProvider; +use TaylorNetwork\UsernameGenerator\Support\Exceptions\GeneratorException; +use TaylorNetwork\UsernameGenerator\Support\Exceptions\UsernameTooLongException; class GeneratorTest extends TestCase { @@ -68,7 +70,7 @@ public function testMixedCaseNotUnique() public function testUppercaseUniqueSeparator() { $g = new Generator(['case' => 'upper', 'separator' => '_']); - $this->assertEquals('TEST_USER_1', $g->generate('Test User')); + $this->assertEquals('TEST_USER', $g->generate('Test User')); } public function testGenerateForModel() @@ -222,5 +224,36 @@ public function testFieldMapExistsButNotUsed() $username = $g->generateFor(new DefaultUser(['name' => 'Test User'])); $this->assertEquals('testuser1', $username); } + + public function testUsernameTooLong() + { + $g = new Generator([ + 'max_length' => 8 + ]); + + $this->assertEquals('testuse', $g->generate('Test User')); + } + + public function testUsernameTooLongException() + { + $g = new Generator([ + 'max_length' => 6, + 'throw_exception_on_too_long' => true, + ]); + + $this->expectException(UsernameTooLongException::class); + $g->generate('Test User'); + } + + public function testUsernameFailure() + { + $g = new Generator([ + 'max_length' => 1, + ]); + + $this->expectException(GeneratorException::class); + $g->generate('Test User'); + } + } From da1c3e5f04b2c1dc26fcac3a795f24947efa822c Mon Sep 17 00:00:00 2001 From: Sam Taylor Date: Wed, 2 Dec 2020 12:13:43 -0500 Subject: [PATCH 13/21] Updated readme --- README.md | 160 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 141 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 8166139..04503dc 100644 --- a/README.md +++ b/README.md @@ -22,12 +22,22 @@ Easily generate unique usernames for a Laravel User Model - [Upper Case](#upper-case) - [Mixed Case](#mixed-case) - [Minimum Length](#minimum-length) + - [Maximum Length](#maximum-length) 7. [Drivers](#drivers) - [Extending](#extending) 8. [License](#license) ## Changes +**v2.5** + +- Added maximum length check. +- Added ability for pre-filled usernames to go through generate process to allow for consistent username styles. +- Added checking for similar usernames using REGEXP or LIKE (LIKE is a fallback if REGEXP fails). +- Added a check if a username is unique as is before checking for similar ones. +- Updated `composer.json` to support PHP 8.0 as well as 7.3 +- Updated readme for better Laravel 8+ quickstart + **v2.4** - This is a minor change but if you're using older versions of Laravel you may need to update your config file. @@ -69,40 +79,102 @@ Via Composer $ composer require taylornetwork/laravel-username-generator ``` -## Set Up +### Publish Config -Add the `FindSimilarUsernames` trait on your user model (or whichever model you want to use). +This will add the config to `config/username_generator.php` -```php -// app/User.php +```bash +$ php artisan vendor:publish --provider="TaylorNetwork\UsernameGenerator\ServiceProvider" +``` + +## Quickstart + +This section will help you get up and running fast. + +The following steps will be the same for all Laravel versions and assumes you're adding the package to a new installation. + +**User Model** -namespace App; +In `App\Models\User` (or `App\User` for Laravel 7) add the `FindSimilarUsernames` and `GeneratesUsernames` traits. +Add `'username'` to the fillable property. -use Illuminate\Notifications\Notifiable; -use Illuminate\Foundation\Auth\User as Authenticatable; +```php + +// ... use TaylorNetwork\UsernameGenerator\FindSimilarUsernames; +use TaylorNetwork\UsernameGenerator\GeneratesUsernames; class User extends Authenticatable { - use Notifiable, FindSimilarUsernames; + // ... + use FindSimilarUsernames; + use GeneratesUsernames; + + protected $fillable = [ + // ... + 'username', + ]; + + // ... - // -- +} +``` -} +**Database Migration** + +In your `database/2014_10_12_000000_create_users_table` add a username column. + +```php +class CreateUsersTable extends Migration +{ + public function up() + { + Schema::create('users', function (Blueprint $table) { + // ... + $table->string('username')->unique(); + // ... + }); + } +} ``` -### Laravel 7 and below -If you're using Laravel 7 or below you'll need to publish the config using +### Laravel 8+ + +**Note: if you are not using Laravel Jetstream for your project, simply continue with the Laravel 7 guide below.** + +Publish the Laravel Fortify config if you haven't already ```bash -$ php artisan vendor:publish --provider="TaylorNetwork\UsernameGenerator\ServiceProvider" +$ php artisan vendor:publish --tag=fortify-config +``` + +In the `config/fortify.php` change the `'username' => 'email'` to `'username' => 'username'` + +```php +// ... + +'username' => 'username', + +'email' => 'email', + +// ... +``` + +Update the login view in `resources/views/auth/login.blade.php` and replace Email with Username. + +```html + + ``` -And update your `config/username_generator.php` file to match your User model namespace (`App\User`). -### Use username to login +### Laravel 7 and below + +In `config/username_generator.php` update the User model namespace to match your project. + +**Using username to login** To use the username to login instead of the email you need to add the following to your `LoginController` @@ -113,11 +185,27 @@ public function username() } ``` -See Username Customization in [Laravel Authentication Docs](https://laravel.com/docs/5.8/authentication#included-authenticating) + +## Set Up + +Add the `FindSimilarUsernames` trait on your user model (or whichever model you want to use). + +```php +use TaylorNetwork\UsernameGenerator\FindSimilarUsernames; + +class User extends Authenticatable +{ + use FindSimilarUsernames; +} +``` + +**Note: this is required in all cases if you want the username to be unique** ## Config +**This is in the process of being updated on the wiki** + By default the `Generator` class has the following configuration: | Config | Value | Type | @@ -126,7 +214,7 @@ By default the `Generator` class has the following configuration: | Separator | `''` | string (should be single character) | | Case | `'lower'` | string (one of lower, upper, or mixed) | | Username DB Column | `'username'` | string | -| Class | `'\App\User'` | string | +| Class | `'\App\Models\User'` | string | The config is stored in `config/username_generator.php` @@ -137,8 +225,6 @@ You can override config on a new instance by `new Generator([ 'unique' => false #### generate($name) Create a new instance and call `generate($name)` -*Note: This has replaced, the old `makeUsername` method which ~~is deprecated but still currently has support~~ no longer has support (as of v2.0)* - ```php use TaylorNetwork\UsernameGenerator\Generator; @@ -365,6 +451,42 @@ UsernameGenerator::generate('test'); Would throw a `UsernameTooShortException` +### Maximum Length + +If you want to enforce a maximum length for usernames generated change the `max_length` option in `config/username_generator.php` + +```php +'max_length' => 6, +``` + +By default if the generator generates a username more than the minimum length it will cut it to the max length value and then try to make it unique again. +If that becomes too long it will remove one character at a time until a unique username with the correct length has been generated. + +For example + +```php + +UsernameGenerator::generate('test user'); + +'testus' + +``` + +**Alternatively you can throw an exception when the maximum length has been exceeded** + +In `config/username_generator.php` set + +```php +'throw_exception_on_too_long' => true, +``` + +```php +UsernameGenerator::generate('test user'); +``` + +Would throw a `UsernameTooLongException` + + ## Drivers 2 drivers are included, `NameDriver` (default) and `EmailDriver` From a04833656c5c2c6ae6db4e8299a0f684539a8882 Mon Sep 17 00:00:00 2001 From: Sam Taylor Date: Wed, 2 Dec 2020 17:14:33 +0000 Subject: [PATCH 14/21] Apply fixes from StyleCI --- src/Drivers/BaseDriver.php | 10 ++++++---- src/FindSimilarUsernames.php | 3 +++ src/Generator.php | 8 +++++--- src/Support/Exceptions/UsernameTooLongException.php | 4 +--- tests/GeneratorTest.php | 6 ++---- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/Drivers/BaseDriver.php b/src/Drivers/BaseDriver.php index 925057a..e9dacab 100644 --- a/src/Drivers/BaseDriver.php +++ b/src/Drivers/BaseDriver.php @@ -62,8 +62,9 @@ public function getWord($type = 'noun'): string * * @param string|null $text * - * @return string * @throws UsernameTooShortException|UsernameTooLongException|GeneratorException + * + * @return string */ public function generate(string $text = null): string { @@ -83,7 +84,7 @@ public function generate(string $text = null): string } } - if ($this->getConfig('max_length', 0) > 0 && $this->getConfig('max_length',0) > $this->getConfig('min_length')) { + if ($this->getConfig('max_length', 0) > 0 && $this->getConfig('max_length', 0) > $this->getConfig('min_length')) { if (strlen($text) > $this->getConfig('max_length', 0)) { $text = $this->tooLongAction($text); } @@ -118,8 +119,10 @@ public function tooShortAction(string $text): string * Action when username is too long. * * @param string $text - * @return string + * * @throws UsernameTooLongException|GeneratorException + * + * @return string */ public function tooLongAction(string $text): string { @@ -143,7 +146,6 @@ public function tooLongAction(string $text): string return $text; } - /** * Convert the case of the username. * diff --git a/src/FindSimilarUsernames.php b/src/FindSimilarUsernames.php index dae4636..861ace4 100644 --- a/src/FindSimilarUsernames.php +++ b/src/FindSimilarUsernames.php @@ -37,6 +37,7 @@ public function findSimilarUsernames($username) * Check if the username is unique as is. * * @param string $username + * * @return bool */ public function isUsernameUnique(string $username): bool @@ -48,6 +49,7 @@ public function isUsernameUnique(string $username): bool * Search for similar usernames using LIKE. * * @param $username + * * @return mixed */ private function searchUsingLike($username) @@ -67,6 +69,7 @@ private function searchUsingLike($username) * This will fail on some databases, so like should be used as a backup. * * @param $username + * * @return mixed */ private function searchUsingRegexp($username) diff --git a/src/Generator.php b/src/Generator.php index 40a7b3c..b15ccb4 100644 --- a/src/Generator.php +++ b/src/Generator.php @@ -52,10 +52,11 @@ public function generate(?string $text = null): string * * @param object $model * - * @return string * @throws GeneratorException * @throws UsernameTooLongException * @throws UsernameTooShortException + * + * @return string */ public function generateFor($model): string { @@ -117,12 +118,13 @@ protected function getMappedField(string $field, $model): ?string * Forward the generate call to the selected driver. * * @param string|BaseDriver $driver - * @param string|null $text + * @param string|null $text * - * @return string * @throws GeneratorException * @throws UsernameTooLongException * @throws UsernameTooShortException + * + * @return string */ protected function forwardCallToDriver($driver, ?string $text): string { diff --git a/src/Support/Exceptions/UsernameTooLongException.php b/src/Support/Exceptions/UsernameTooLongException.php index e2b609e..b3be3b4 100644 --- a/src/Support/Exceptions/UsernameTooLongException.php +++ b/src/Support/Exceptions/UsernameTooLongException.php @@ -1,11 +1,9 @@ 8 + 'max_length' => 8, ]); $this->assertEquals('testuse', $g->generate('Test User')); @@ -237,7 +237,7 @@ public function testUsernameTooLong() public function testUsernameTooLongException() { $g = new Generator([ - 'max_length' => 6, + 'max_length' => 6, 'throw_exception_on_too_long' => true, ]); @@ -254,6 +254,4 @@ public function testUsernameFailure() $this->expectException(GeneratorException::class); $g->generate('Test User'); } - } - From 00197d71dc8c8d88ca090c59219da4ddac6a6d63 Mon Sep 17 00:00:00 2001 From: Sam Taylor Date: Wed, 2 Dec 2020 12:32:16 -0500 Subject: [PATCH 15/21] Bump to PHP 7.2+ Added object type hints etc. --- composer.json | 2 +- src/Drivers/BaseDriver.php | 4 ++-- src/Facades/UsernameGenerator.php | 2 +- src/FindSimilarUsernames.php | 16 ++++++++-------- src/Generator.php | 12 ++++++------ src/Support/LoadsConfig.php | 12 ++++++------ 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/composer.json b/composer.json index 4408cad..a2b3272 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "taylornetwork/laravel-username-generator", "require": { "illuminate/support": ">=5.5", - "php": ">=7.1" + "php": "^7.2|^7.3|^7.4|^8.0" }, "require-dev": { "orchestra/testbench": "^3.5", diff --git a/src/Drivers/BaseDriver.php b/src/Drivers/BaseDriver.php index e9dacab..bd59d9a 100644 --- a/src/Drivers/BaseDriver.php +++ b/src/Drivers/BaseDriver.php @@ -49,7 +49,7 @@ public function __construct() $this->loadConfig(); } - public function getWord($type = 'noun'): string + public function getWord(string $type = 'noun'): string { $type = Str::plural(strtolower($type)); $max = count($this->getConfig('dictionary')[$type]) - 1; @@ -66,7 +66,7 @@ public function getWord($type = 'noun'): string * * @return string */ - public function generate(string $text = null): string + public function generate(?string $text = null): string { if ($text === null) { $text = $this->getWord('adjective').' '.$this->getWord('noun'); diff --git a/src/Facades/UsernameGenerator.php b/src/Facades/UsernameGenerator.php index df3f63c..28d36a6 100644 --- a/src/Facades/UsernameGenerator.php +++ b/src/Facades/UsernameGenerator.php @@ -9,7 +9,7 @@ class UsernameGenerator extends Facade /** * {@inheritdoc} */ - protected static function getFacadeAccessor() + protected static function getFacadeAccessor(): string { return 'UsernameGenerator'; } diff --git a/src/FindSimilarUsernames.php b/src/FindSimilarUsernames.php index 861ace4..60ecf19 100644 --- a/src/FindSimilarUsernames.php +++ b/src/FindSimilarUsernames.php @@ -14,11 +14,11 @@ trait FindSimilarUsernames * This assumes you are using Eloquent with Laravel, if not, override this * function in your class. * - * @param $username + * @param string $username * * @return mixed */ - public function findSimilarUsernames($username) + public function findSimilarUsernames(string $username) { $preferRegexp = $this->preferRegexp ?? config('username_generator.prefer_regexp', true); @@ -48,11 +48,11 @@ public function isUsernameUnique(string $username): bool /** * Search for similar usernames using LIKE. * - * @param $username + * @param string $username * * @return mixed */ - private function searchUsingLike($username) + private function searchUsingLike(string $username) { $exactMatches = static::where($this->getColumn(), $username)->get(); @@ -68,11 +68,11 @@ private function searchUsingLike($username) * * This will fail on some databases, so like should be used as a backup. * - * @param $username + * @param string $username * * @return mixed */ - private function searchUsingRegexp($username) + private function searchUsingRegexp(string $username) { $column = $this->getColumn(); @@ -82,9 +82,9 @@ private function searchUsingRegexp($username) /** * Get the username column. * - * @return Repository|Application|mixed + * @return string */ - private function getColumn() + private function getColumn(): string { return $this->usernameColumn ?? config('username_generator.column', 'username'); } diff --git a/src/Generator.php b/src/Generator.php index b15ccb4..a7b6f2c 100644 --- a/src/Generator.php +++ b/src/Generator.php @@ -58,7 +58,7 @@ public function generate(?string $text = null): string * * @return string */ - public function generateFor($model): string + public function generateFor(object $model): string { $drivers = $this->getConfig('drivers'); @@ -93,7 +93,7 @@ public function generateFor($model): string * * @return string|null */ - protected function getMappedField(string $field, $model): ?string + protected function getMappedField(string $field, object $model): ?string { $map = $this->getConfig('field_map'); @@ -157,11 +157,11 @@ public function setDriver(string $driverKey): self * __call. * * @param string $name - * @param mixed $arguments + * @param mixed $arguments * * @return mixed */ - public function __call($name, $arguments) + public function __call(string $name, $arguments) { return $this->caller($name, $arguments); } @@ -170,11 +170,11 @@ public function __call($name, $arguments) * __callStatic. * * @param string $name - * @param mixed $arguments + * @param mixed $arguments * * @return mixed */ - public static function __callStatic($name, $arguments) + public static function __callStatic(string $name, $arguments) { return (new static())->caller($name, $arguments); } diff --git a/src/Support/LoadsConfig.php b/src/Support/LoadsConfig.php index efb75f8..c06de2f 100644 --- a/src/Support/LoadsConfig.php +++ b/src/Support/LoadsConfig.php @@ -23,16 +23,16 @@ trait LoadsConfig /** * Access an instance of the unique to model. * - * @return bool + * @return object|null */ - public function model() + public function model(): ?object { try { $model = $this->getConfig('model'); return new $model(); } catch (Exception $exception) { - return false; + return null; } } @@ -91,7 +91,7 @@ public function setConfig($key, $value = null): self /** * Load config from Laravel config file. */ - public function loadConfig() + public function loadConfig(): void { try { $this->config = config('username_generator'); @@ -129,7 +129,7 @@ public static function laravelConfig(string $key, $default = null) * * @return array */ - public function config() + public function config(): array { if (!$this->configLoaded) { $this->loadConfig(); @@ -156,7 +156,7 @@ public function withConfig(array $config): self /** * Adds the the default dictionary words to the config if not set. */ - private function checkForDictionary() + private function checkForDictionary(): void { if ($this->configLoaded) { $dictionary = include __DIR__.'/../config/dictionary.php'; From dca00df324b0c5c5e4ebfc4c4d9d961ea56f3068 Mon Sep 17 00:00:00 2001 From: Sam Taylor Date: Wed, 2 Dec 2020 17:33:08 +0000 Subject: [PATCH 16/21] Apply fixes from StyleCI --- src/FindSimilarUsernames.php | 2 -- src/Generator.php | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/FindSimilarUsernames.php b/src/FindSimilarUsernames.php index 60ecf19..96c452f 100644 --- a/src/FindSimilarUsernames.php +++ b/src/FindSimilarUsernames.php @@ -2,8 +2,6 @@ namespace TaylorNetwork\UsernameGenerator; -use Illuminate\Config\Repository; -use Illuminate\Contracts\Foundation\Application; use Illuminate\Database\QueryException; trait FindSimilarUsernames diff --git a/src/Generator.php b/src/Generator.php index a7b6f2c..a161a9a 100644 --- a/src/Generator.php +++ b/src/Generator.php @@ -157,7 +157,7 @@ public function setDriver(string $driverKey): self * __call. * * @param string $name - * @param mixed $arguments + * @param mixed $arguments * * @return mixed */ @@ -170,7 +170,7 @@ public function __call(string $name, $arguments) * __callStatic. * * @param string $name - * @param mixed $arguments + * @param mixed $arguments * * @return mixed */ From e45c932aadda112896daaac67df15829b75b99c3 Mon Sep 17 00:00:00 2001 From: Sam Taylor Date: Wed, 2 Dec 2020 12:34:14 -0500 Subject: [PATCH 17/21] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 04503dc..634c5f6 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ Easily generate unique usernames for a Laravel User Model - Added ability for pre-filled usernames to go through generate process to allow for consistent username styles. - Added checking for similar usernames using REGEXP or LIKE (LIKE is a fallback if REGEXP fails). - Added a check if a username is unique as is before checking for similar ones. -- Updated `composer.json` to support PHP 8.0 as well as 7.3 +- Updated `composer.json` to support PHP 7.2 and above - Updated readme for better Laravel 8+ quickstart **v2.4** From 0f22d323af26e2ee1d833f74fd9180fc89277b81 Mon Sep 17 00:00:00 2001 From: Sam Taylor Date: Wed, 2 Dec 2020 12:56:58 -0500 Subject: [PATCH 18/21] Pulled check for min and max length out of generate method. - Allowing hooks for checkMinLength and checkMaxLength to be created in a driver. --- src/Drivers/BaseDriver.php | 41 +++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/src/Drivers/BaseDriver.php b/src/Drivers/BaseDriver.php index bd59d9a..ba401e3 100644 --- a/src/Drivers/BaseDriver.php +++ b/src/Drivers/BaseDriver.php @@ -39,6 +39,8 @@ abstract class BaseDriver 'collapseWhitespace', 'addSeparator', 'makeUnique', + 'checkMinLength', + 'checkMaxLength', ]; /** @@ -62,8 +64,6 @@ public function getWord(string $type = 'noun'): string * * @param string|null $text * - * @throws UsernameTooShortException|UsernameTooLongException|GeneratorException - * * @return string */ public function generate(?string $text = null): string @@ -78,12 +78,19 @@ public function generate(?string $text = null): string $text = $this->checkForHook($text, $method); } - if ($this->getConfig('min_length', 0) > 0) { - if (strlen($text) < $this->getConfig('min_length')) { - $text = $this->tooShortAction($text); - } - } + return $text; + } + /** + * Check maximum length. + * + * @param string $text + * @return string + * @throws GeneratorException + * @throws UsernameTooLongException + */ + public function checkMaxLength(string $text): string + { if ($this->getConfig('max_length', 0) > 0 && $this->getConfig('max_length', 0) > $this->getConfig('min_length')) { if (strlen($text) > $this->getConfig('max_length', 0)) { $text = $this->tooLongAction($text); @@ -93,6 +100,24 @@ public function generate(?string $text = null): string return $text; } + /** + * Check minimum length. + * + * @param string $text + * @return string + * @throws UsernameTooShortException + */ + public function checkMinLength(string $text): string + { + if ($this->getConfig('min_length', 0) > 0) { + if (strlen($text) < $this->getConfig('min_length')) { + $text = $this->tooShortAction($text); + } + } + + return $text; + } + /** * Action on username too short. * @@ -112,6 +137,8 @@ public function tooShortAction(string $text): string $text .= rand(0, 9); } + $text = $this->makeUnique($text); + return $text; } From a6fae2722e6999e7e6666d7850fa2c3e5cc38b34 Mon Sep 17 00:00:00 2001 From: Sam Taylor Date: Wed, 2 Dec 2020 17:57:53 +0000 Subject: [PATCH 19/21] Apply fixes from StyleCI --- src/Drivers/BaseDriver.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Drivers/BaseDriver.php b/src/Drivers/BaseDriver.php index ba401e3..30e2eed 100644 --- a/src/Drivers/BaseDriver.php +++ b/src/Drivers/BaseDriver.php @@ -85,9 +85,11 @@ public function generate(?string $text = null): string * Check maximum length. * * @param string $text - * @return string + * * @throws GeneratorException * @throws UsernameTooLongException + * + * @return string */ public function checkMaxLength(string $text): string { @@ -104,8 +106,10 @@ public function checkMaxLength(string $text): string * Check minimum length. * * @param string $text - * @return string + * * @throws UsernameTooShortException + * + * @return string */ public function checkMinLength(string $text): string { From 25132bbc5b3e938a9ffc5c2b290b6e0e534fc5c6 Mon Sep 17 00:00:00 2001 From: Sam Taylor Date: Wed, 2 Dec 2020 13:09:25 -0500 Subject: [PATCH 20/21] Fix potential bug if field_map isn't found --- src/Generator.php | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/Generator.php b/src/Generator.php index a161a9a..9b937f8 100644 --- a/src/Generator.php +++ b/src/Generator.php @@ -53,8 +53,6 @@ public function generate(?string $text = null): string * @param object $model * * @throws GeneratorException - * @throws UsernameTooLongException - * @throws UsernameTooShortException * * @return string */ @@ -95,7 +93,7 @@ public function generateFor(object $model): string */ protected function getMappedField(string $field, object $model): ?string { - $map = $this->getConfig('field_map'); + $map = $this->getConfig('field_map', []); if (array_key_exists($field, $map)) { if (is_array($map[$field])) { @@ -120,10 +118,6 @@ protected function getMappedField(string $field, object $model): ?string * @param string|BaseDriver $driver * @param string|null $text * - * @throws GeneratorException - * @throws UsernameTooLongException - * @throws UsernameTooShortException - * * @return string */ protected function forwardCallToDriver($driver, ?string $text): string From d5ce05a54d23a365742ab495ac2ed08da8f46c7c Mon Sep 17 00:00:00 2001 From: Sam Taylor Date: Wed, 2 Dec 2020 18:10:17 +0000 Subject: [PATCH 21/21] Apply fixes from StyleCI --- src/Generator.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Generator.php b/src/Generator.php index 9b937f8..619f0a4 100644 --- a/src/Generator.php +++ b/src/Generator.php @@ -5,8 +5,6 @@ use Illuminate\Support\Arr; use TaylorNetwork\UsernameGenerator\Drivers\BaseDriver; use TaylorNetwork\UsernameGenerator\Support\Exceptions\GeneratorException; -use TaylorNetwork\UsernameGenerator\Support\Exceptions\UsernameTooLongException; -use TaylorNetwork\UsernameGenerator\Support\Exceptions\UsernameTooShortException; use TaylorNetwork\UsernameGenerator\Support\LoadsConfig; class Generator