From 68602778d950d0a51d66f9559d1f491e960a19f1 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Dadashi Date: Mon, 31 Oct 2022 08:33:06 +0330 Subject: [PATCH 01/16] feat: add new CLI command for make custom `UserModel` --- .../Generators/UserModelGenerator.php | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 src/Commands/Generators/UserModelGenerator.php diff --git a/src/Commands/Generators/UserModelGenerator.php b/src/Commands/Generators/UserModelGenerator.php new file mode 100644 index 000000000..b41f3c444 --- /dev/null +++ b/src/Commands/Generators/UserModelGenerator.php @@ -0,0 +1,85 @@ + [options]'; + + /** + * The Command's Arguments + * + * @var array + */ + protected $arguments = [ + 'name' => 'The model class name.', + ]; + + /** + * The Command's Options + * + * @var array + */ + protected $options = [ + '--namespace' => 'Set root namespace. Default: "APP_NAMESPACE".', + '--suffix' => 'Append the component title to the class name (e.g. User => UserModel).', + '--force' => 'Force overwrite existing file.', + ]; + + /** + * Actually execute a command. + */ + public function run(array $params): void + { + $this->component = 'Model'; + $this->directory = 'Models'; + $this->template = 'usermodel.tpl.php'; + + $this->classNameLang = 'CLI.generator.className.model'; + $this->execute($params); + } + + /** + * Prepare options and do the necessary replacements. + */ + protected function prepare(string $class): string + { + return $this->parseTemplate($class); + } +} From 288f8cb028738d9b944a5c43cda5e2842340fe47 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Dadashi Date: Mon, 31 Oct 2022 08:35:03 +0330 Subject: [PATCH 02/16] feat: add tpl for make custom `UserModel` --- .../Generators/Views/usermodel.tpl.php | 20 +++++++++++++++++++ src/Config/Registrar.php | 9 +++++++++ 2 files changed, 29 insertions(+) create mode 100644 src/Commands/Generators/Views/usermodel.tpl.php diff --git a/src/Commands/Generators/Views/usermodel.tpl.php b/src/Commands/Generators/Views/usermodel.tpl.php new file mode 100644 index 000000000..60336781f --- /dev/null +++ b/src/Commands/Generators/Views/usermodel.tpl.php @@ -0,0 +1,20 @@ +<@php + +declare(strict_types=1); + +namespace {namespace}; + +use CodeIgniter\Shield\Models\UserModel; + +class {class} extends UserModel +{ + protected function initialize(): void + { + // Merge properties with parent + $this->allowedFields = array_merge($this->allowedFields, [ + // Add here your custom fields + // 'first_name', + ]); + } +} + diff --git a/src/Config/Registrar.php b/src/Config/Registrar.php index f212e7962..31e73822f 100644 --- a/src/Config/Registrar.php +++ b/src/Config/Registrar.php @@ -45,4 +45,13 @@ public static function Toolbar(): array ], ]; } + + public static function Generators(): array + { + return [ + 'views' => [ + 'shield:make' => 'CodeIgniter\Shield\Commands\Generators\Views\usermodel.tpl.php', + ], + ]; + } } From 65241d728225d85159a706bfcfd2ff2e7e4d852b Mon Sep 17 00:00:00 2001 From: Pooya Parsa Dadashi Date: Wed, 2 Nov 2022 07:34:50 +0330 Subject: [PATCH 03/16] fix: rename command name to `shield:model` --- src/Commands/Generators/UserModelGenerator.php | 4 ++-- src/Config/Registrar.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Commands/Generators/UserModelGenerator.php b/src/Commands/Generators/UserModelGenerator.php index b41f3c444..613fd4a79 100644 --- a/src/Commands/Generators/UserModelGenerator.php +++ b/src/Commands/Generators/UserModelGenerator.php @@ -26,7 +26,7 @@ class UserModelGenerator extends BaseCommand * * @var string */ - protected $name = 'shield:make'; + protected $name = 'shield:model'; /** * The Command's Description @@ -40,7 +40,7 @@ class UserModelGenerator extends BaseCommand * * @var string */ - protected $usage = 'shield:make [options]'; + protected $usage = 'shield:model [options]'; /** * The Command's Arguments diff --git a/src/Config/Registrar.php b/src/Config/Registrar.php index 31e73822f..0186a2fec 100644 --- a/src/Config/Registrar.php +++ b/src/Config/Registrar.php @@ -50,7 +50,7 @@ public static function Generators(): array { return [ 'views' => [ - 'shield:make' => 'CodeIgniter\Shield\Commands\Generators\Views\usermodel.tpl.php', + 'shield:model' => 'CodeIgniter\Shield\Commands\Generators\Views\usermodel.tpl.php', ], ]; } From 92ba9d49250566bbfc911d6bbb50d44a95620073 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Dadashi Date: Wed, 2 Nov 2022 07:35:43 +0330 Subject: [PATCH 04/16] tests: add phpunit test --- tests/Commands/UserModelGeneratorTest.php | 102 ++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 tests/Commands/UserModelGeneratorTest.php diff --git a/tests/Commands/UserModelGeneratorTest.php b/tests/Commands/UserModelGeneratorTest.php new file mode 100644 index 000000000..02cc5686b --- /dev/null +++ b/tests/Commands/UserModelGeneratorTest.php @@ -0,0 +1,102 @@ +streamFilter = stream_filter_append(STDOUT, 'CITestStreamFilter'); + $this->streamFilter = stream_filter_append(STDERR, 'CITestStreamFilter'); + parent::setUp(); + } + + protected function tearDown(): void + { + parent::tearDown(); + + stream_filter_remove($this->streamFilter); + $result = str_replace(["\033[0;32m", "\033[0m", "\n"], '', CITestStreamFilter::$buffer); + + $filepath = str_replace('APPPATH' . DIRECTORY_SEPARATOR, APPPATH, trim(substr($result, 14))); + if (is_file($filepath)) { + unlink($filepath); + } + } + + protected function getFileContents(string $filepath): string + { + if (! file_exists($filepath)) { + return ''; + } + + return file_get_contents($filepath) ?: ''; + } + + public function testGenerateUserModel(): void + { + command('shield:model MyUserModel'); + $filepath = APPPATH . 'Models/MyUserModel.php'; + + $this->assertStringContainsString('File created: ', CITestStreamFilter::$buffer); + $this->assertFileExists($filepath); + + $this->assertStringContainsString('namespace App\Models;', $this->getFileContents($filepath)); + $this->assertStringContainsString('class MyUserModel extends UserModel', $this->getFileContents($filepath)); + $this->assertStringContainsString('use CodeIgniter\Shield\Models\UserModel;', $this->getFileContents($filepath)); + $this->assertStringContainsString('protected function initialize(): void', $this->getFileContents($filepath)); + } + + public function testGenerateUserModelCustomNamespace(): void + { + command('shield:model MyUserModel --namespace CodeIgniter\\\\Shield'); + $filepath = HOMEPATH . 'src/Models/MyUserModel.php'; + + $this->assertStringContainsString('File created: ', CITestStreamFilter::$buffer); + $this->assertFileExists($filepath); + + $this->assertStringContainsString('namespace CodeIgniter\Shield\Models;', $this->getFileContents($filepath)); + $this->assertStringContainsString('class MyUserModel extends UserModel', $this->getFileContents($filepath)); + $this->assertStringContainsString('use CodeIgniter\Shield\Models\UserModel;', $this->getFileContents($filepath)); + $this->assertStringContainsString('protected function initialize(): void', $this->getFileContents($filepath)); + + if (is_file($filepath)) { + unlink($filepath); + } + } + + public function testGenerateUserModelWithForce(): void + { + command('shield:model MyUserModel'); + + command('shield:model MyUserModel --force'); + $this->assertStringContainsString('File overwritten: ', CITestStreamFilter::$buffer); + + $filepath = APPPATH . 'Models/MyUserModel.php'; + if (is_file($filepath)) { + unlink($filepath); + } + } + + public function testGenerateUserModelWithSuffix(): void + { + command('shield:model MyUser --suffix'); + $filepath = APPPATH . 'Models/MyUserModel.php'; + + $this->assertStringContainsString('File created: ', CITestStreamFilter::$buffer); + $this->assertFileExists($filepath); + + $this->assertStringContainsString('class MyUserModel extends UserModel', $this->getFileContents($filepath)); + } +} From 469f8b965c9a1f3f8048f360e6548cdfcc4cfd9f Mon Sep 17 00:00:00 2001 From: Pooya Parsa Dadashi Date: Wed, 2 Nov 2022 11:08:32 +0330 Subject: [PATCH 05/16] docs: add description for command `shield:model` --- docs/concepts.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/concepts.md b/docs/concepts.md index c8cafce74..a3054d85e 100644 --- a/docs/concepts.md +++ b/docs/concepts.md @@ -26,10 +26,16 @@ on the standard Config class if nothing is found in the database. You can use your own models to handle user persistence. Shield calls this the "User Provider" class. A default model is provided for you at `CodeIgniter\Shield\Models\UserModel`. You can change this in the `Config\Auth->userProvider` setting. -The only requirement is that your new class MUST extend the provided `UserModel`. +The only requirement is that your new class MUST extend the provided `UserModel`. Shield has a CLI command to quickly create a custom `UserModel`, for example if you run the following command in terminal: + +```console +php spark shield:model MyUserModel +``` + +You should set the `Config\Auth->userProvider` as below: ```php -public $userProvider = 'CodeIgniter\Shield\Models\UserModel'; +public $userProvider = 'App\Models\MyUserModel'; ``` From 223fad50c7d0cce5c6c728a789d4603edaddc8cf Mon Sep 17 00:00:00 2001 From: Pooya Parsa Dadashi Date: Wed, 2 Nov 2022 11:42:06 +0330 Subject: [PATCH 06/16] docs: correct description Co-authored-by: John Paul E. Balandan, CPA --- docs/concepts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts.md b/docs/concepts.md index a3054d85e..dc2d61508 100644 --- a/docs/concepts.md +++ b/docs/concepts.md @@ -26,7 +26,7 @@ on the standard Config class if nothing is found in the database. You can use your own models to handle user persistence. Shield calls this the "User Provider" class. A default model is provided for you at `CodeIgniter\Shield\Models\UserModel`. You can change this in the `Config\Auth->userProvider` setting. -The only requirement is that your new class MUST extend the provided `UserModel`. Shield has a CLI command to quickly create a custom `UserModel`, for example if you run the following command in terminal: +The only requirement is that your new class MUST extend the provided `UserModel`. Shield has a CLI command to quickly create a custom `MyUserModel` by running the following command in terminal: ```console php spark shield:model MyUserModel From 8c35a48e0f591c73197e81a633bad7eafcff91c4 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Dadashi Date: Wed, 2 Nov 2022 11:44:47 +0330 Subject: [PATCH 07/16] docs: use `::$` instead of `->`. Co-authored-by: John Paul E. Balandan, CPA --- docs/concepts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts.md b/docs/concepts.md index dc2d61508..3ae2f27dd 100644 --- a/docs/concepts.md +++ b/docs/concepts.md @@ -32,7 +32,7 @@ The only requirement is that your new class MUST extend the provided `UserModel` php spark shield:model MyUserModel ``` -You should set the `Config\Auth->userProvider` as below: +You should set `Config\Auth::$userProvider` as follows: ```php public $userProvider = 'App\Models\MyUserModel'; From c142856f61b508a5b654103cee6f7b172ed5d480 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Dadashi Date: Wed, 2 Nov 2022 11:46:04 +0330 Subject: [PATCH 08/16] feat: use array unpacking Co-authored-by: John Paul E. Balandan, CPA --- src/Commands/Generators/Views/usermodel.tpl.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Commands/Generators/Views/usermodel.tpl.php b/src/Commands/Generators/Views/usermodel.tpl.php index 60336781f..4189d3884 100644 --- a/src/Commands/Generators/Views/usermodel.tpl.php +++ b/src/Commands/Generators/Views/usermodel.tpl.php @@ -11,10 +11,11 @@ class {class} extends UserModel protected function initialize(): void { // Merge properties with parent - $this->allowedFields = array_merge($this->allowedFields, [ + $this->allowedFields = [ + ...$this->allowedFields, // Add here your custom fields // 'first_name', - ]); + ]; } } From 49cd606fcba3e8f85c68ccebd9c62cc2cc4bdaa2 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Dadashi Date: Wed, 2 Nov 2022 11:47:28 +0330 Subject: [PATCH 09/16] Update tests/Commands/UserModelGeneratorTest.php Co-authored-by: John Paul E. Balandan, CPA --- tests/Commands/UserModelGeneratorTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Commands/UserModelGeneratorTest.php b/tests/Commands/UserModelGeneratorTest.php index 02cc5686b..55abba230 100644 --- a/tests/Commands/UserModelGeneratorTest.php +++ b/tests/Commands/UserModelGeneratorTest.php @@ -16,10 +16,11 @@ final class UserModelGeneratorTest extends CIUnitTestCase protected function setUp(): void { + parent::setUp(); + CITestStreamFilter::$buffer = ''; $this->streamFilter = stream_filter_append(STDOUT, 'CITestStreamFilter'); $this->streamFilter = stream_filter_append(STDERR, 'CITestStreamFilter'); - parent::setUp(); } protected function tearDown(): void From baf6a2689d04b65bfe3d0e90a469fb660d39bce1 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Dadashi Date: Wed, 2 Nov 2022 11:48:02 +0330 Subject: [PATCH 10/16] Update src/Commands/Generators/UserModelGenerator.php Co-authored-by: John Paul E. Balandan, CPA --- src/Commands/Generators/UserModelGenerator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Commands/Generators/UserModelGenerator.php b/src/Commands/Generators/UserModelGenerator.php index 613fd4a79..8aa29d57c 100644 --- a/src/Commands/Generators/UserModelGenerator.php +++ b/src/Commands/Generators/UserModelGenerator.php @@ -54,7 +54,7 @@ class UserModelGenerator extends BaseCommand /** * The Command's Options * - * @var array + * @var array */ protected $options = [ '--namespace' => 'Set root namespace. Default: "APP_NAMESPACE".', From 105c101d30c87aca2958ccdbdd7b29688a63ec52 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Dadashi Date: Wed, 2 Nov 2022 11:48:41 +0330 Subject: [PATCH 11/16] Update src/Commands/Generators/UserModelGenerator.php Co-authored-by: John Paul E. Balandan, CPA --- src/Commands/Generators/UserModelGenerator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Commands/Generators/UserModelGenerator.php b/src/Commands/Generators/UserModelGenerator.php index 8aa29d57c..c44c19fe9 100644 --- a/src/Commands/Generators/UserModelGenerator.php +++ b/src/Commands/Generators/UserModelGenerator.php @@ -45,7 +45,7 @@ class UserModelGenerator extends BaseCommand /** * The Command's Arguments * - * @var array + * @var array */ protected $arguments = [ 'name' => 'The model class name.', From cd15b5c5aa2dceac7f9f304144fc19f93c86558e Mon Sep 17 00:00:00 2001 From: Pooya Parsa Dadashi Date: Wed, 2 Nov 2022 13:05:49 +0330 Subject: [PATCH 12/16] fix: remove unnecessary method --- src/Commands/Generators/UserModelGenerator.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/Commands/Generators/UserModelGenerator.php b/src/Commands/Generators/UserModelGenerator.php index c44c19fe9..f792abe26 100644 --- a/src/Commands/Generators/UserModelGenerator.php +++ b/src/Commands/Generators/UserModelGenerator.php @@ -74,12 +74,4 @@ public function run(array $params): void $this->classNameLang = 'CLI.generator.className.model'; $this->execute($params); } - - /** - * Prepare options and do the necessary replacements. - */ - protected function prepare(string $class): string - { - return $this->parseTemplate($class); - } } From 4e6b06dd998d3c8a15cd88385362b06b49ed718b Mon Sep 17 00:00:00 2001 From: Pooya Parsa Dadashi Date: Thu, 10 Nov 2022 10:41:06 +0330 Subject: [PATCH 13/16] docs: remove unnecessary details Co-authored-by: John Paul E. Balandan, CPA --- src/Commands/Generators/Views/usermodel.tpl.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Commands/Generators/Views/usermodel.tpl.php b/src/Commands/Generators/Views/usermodel.tpl.php index 4189d3884..e25f6cb1a 100644 --- a/src/Commands/Generators/Views/usermodel.tpl.php +++ b/src/Commands/Generators/Views/usermodel.tpl.php @@ -10,7 +10,6 @@ class {class} extends UserModel { protected function initialize(): void { - // Merge properties with parent $this->allowedFields = [ ...$this->allowedFields, // Add here your custom fields From de0c36efed3f871a618020e34883740972249f46 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Dadashi Date: Thu, 10 Nov 2022 10:42:35 +0330 Subject: [PATCH 14/16] fix: remove unnecessary line Co-authored-by: John Paul E. Balandan, CPA --- tests/Commands/UserModelGeneratorTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Commands/UserModelGeneratorTest.php b/tests/Commands/UserModelGeneratorTest.php index 55abba230..c6c4cd49a 100644 --- a/tests/Commands/UserModelGeneratorTest.php +++ b/tests/Commands/UserModelGeneratorTest.php @@ -97,7 +97,6 @@ public function testGenerateUserModelWithSuffix(): void $this->assertStringContainsString('File created: ', CITestStreamFilter::$buffer); $this->assertFileExists($filepath); - $this->assertStringContainsString('class MyUserModel extends UserModel', $this->getFileContents($filepath)); } } From ee2984088ba79a9fed9438057713c6f0f48aad74 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Dadashi Date: Thu, 10 Nov 2022 10:57:22 +0330 Subject: [PATCH 15/16] updat: use `class` for suport IDE Co-authored-by: John Paul E. Balandan, CPA --- docs/concepts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts.md b/docs/concepts.md index 3ae2f27dd..717313076 100644 --- a/docs/concepts.md +++ b/docs/concepts.md @@ -35,7 +35,7 @@ php spark shield:model MyUserModel You should set `Config\Auth::$userProvider` as follows: ```php -public $userProvider = 'App\Models\MyUserModel'; +public $userProvider = \App\Models\MyUserModel::class; ``` From 3047309aa1132a92a489a384ece42d4b8f7797eb Mon Sep 17 00:00:00 2001 From: Pooya Parsa Dadashi Date: Thu, 10 Nov 2022 21:39:44 +0330 Subject: [PATCH 16/16] fix: user `tearDown()` for delete file --- tests/Commands/UserModelGeneratorTest.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/Commands/UserModelGeneratorTest.php b/tests/Commands/UserModelGeneratorTest.php index c6c4cd49a..bb8e74b4e 100644 --- a/tests/Commands/UserModelGeneratorTest.php +++ b/tests/Commands/UserModelGeneratorTest.php @@ -85,9 +85,7 @@ public function testGenerateUserModelWithForce(): void $this->assertStringContainsString('File overwritten: ', CITestStreamFilter::$buffer); $filepath = APPPATH . 'Models/MyUserModel.php'; - if (is_file($filepath)) { - unlink($filepath); - } + $this->assertFileExists($filepath); } public function testGenerateUserModelWithSuffix(): void