Skip to content

Commit 09eadca

Browse files
datamwebpaulbalandan
authored andcommitted
feat: add new CLI command for make custom UserModel
1 parent 58a9779 commit 09eadca

File tree

5 files changed

+216
-2
lines changed

5 files changed

+216
-2
lines changed

docs/concepts.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,19 @@ on the standard Config class if nothing is found in the database.
2525
## User Providers
2626

2727
You can use your own models to handle user persistence. Shield calls this the "User Provider" class. A default model
28-
is provided for you at `CodeIgniter\Shield\Models\UserModel`. You can change this in the `Config\Auth::$userProvider` setting.
28+
is provided for you at `CodeIgniter\Shield\Models\UserModel`. You can change this in the `Config\Auth->userProvider` setting.
2929
The only requirement is that your new class MUST extend the provided `UserModel`.
3030

31+
Shield has a CLI command to quickly create a custom `MyUserModel` by running the following command in terminal:
32+
33+
```console
34+
php spark shield:model MyUserModel
35+
```
36+
37+
You should set `Config\Auth::$userProvider` as follows:
38+
3139
```php
32-
public string $userProvider = UserModel::class;
40+
public string $userProvider = \App\Models\MyUserModel::class;
3341
```
3442

3543
## User Identities
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace CodeIgniter\Shield\Commands\Generators;
6+
7+
use CodeIgniter\CLI\BaseCommand;
8+
use CodeIgniter\CLI\GeneratorTrait;
9+
10+
/**
11+
* Generates a skeleton command file.
12+
*/
13+
class UserModelGenerator extends BaseCommand
14+
{
15+
use GeneratorTrait;
16+
17+
/**
18+
* The Command's Group
19+
*
20+
* @var string
21+
*/
22+
protected $group = 'Shield';
23+
24+
/**
25+
* The Command's Name
26+
*
27+
* @var string
28+
*/
29+
protected $name = 'shield:model';
30+
31+
/**
32+
* The Command's Description
33+
*
34+
* @var string
35+
*/
36+
protected $description = 'Generates a new UserModel file.';
37+
38+
/**
39+
* The Command's Usage
40+
*
41+
* @var string
42+
*/
43+
protected $usage = 'shield:model <name> [options]';
44+
45+
/**
46+
* The Command's Arguments
47+
*
48+
* @var array<string, string>
49+
*/
50+
protected $arguments = [
51+
'name' => 'The model class name.',
52+
];
53+
54+
/**
55+
* The Command's Options
56+
*
57+
* @var array<string, string>
58+
*/
59+
protected $options = [
60+
'--namespace' => 'Set root namespace. Default: "APP_NAMESPACE".',
61+
'--suffix' => 'Append the component title to the class name (e.g. User => UserModel).',
62+
'--force' => 'Force overwrite existing file.',
63+
];
64+
65+
/**
66+
* Actually execute a command.
67+
*/
68+
public function run(array $params): void
69+
{
70+
$this->component = 'Model';
71+
$this->directory = 'Models';
72+
$this->template = 'usermodel.tpl.php';
73+
74+
$this->classNameLang = 'CLI.generator.className.model';
75+
$this->execute($params);
76+
}
77+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<@php
2+
3+
declare(strict_types=1);
4+
5+
namespace {namespace};
6+
7+
use CodeIgniter\Shield\Models\UserModel;
8+
9+
class {class} extends UserModel
10+
{
11+
protected function initialize(): void
12+
{
13+
$this->allowedFields = [
14+
...$this->allowedFields,
15+
// Add here your custom fields
16+
// 'first_name',
17+
];
18+
}
19+
}
20+

src/Config/Registrar.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,13 @@ public static function Toolbar(): array
4545
],
4646
];
4747
}
48+
49+
public static function Generators(): array
50+
{
51+
return [
52+
'views' => [
53+
'shield:model' => 'CodeIgniter\Shield\Commands\Generators\Views\usermodel.tpl.php',
54+
],
55+
];
56+
}
4857
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tests\Commands;
6+
7+
use CodeIgniter\Test\CIUnitTestCase;
8+
use CodeIgniter\Test\Filters\CITestStreamFilter;
9+
10+
/**
11+
* @internal
12+
*/
13+
final class UserModelGeneratorTest extends CIUnitTestCase
14+
{
15+
protected $streamFilter;
16+
17+
protected function setUp(): void
18+
{
19+
parent::setUp();
20+
21+
CITestStreamFilter::$buffer = '';
22+
$this->streamFilter = stream_filter_append(STDOUT, 'CITestStreamFilter');
23+
$this->streamFilter = stream_filter_append(STDERR, 'CITestStreamFilter');
24+
}
25+
26+
protected function tearDown(): void
27+
{
28+
parent::tearDown();
29+
30+
stream_filter_remove($this->streamFilter);
31+
$result = str_replace(["\033[0;32m", "\033[0m", "\n"], '', CITestStreamFilter::$buffer);
32+
33+
$filepath = str_replace('APPPATH' . DIRECTORY_SEPARATOR, APPPATH, trim(substr($result, 14)));
34+
if (is_file($filepath)) {
35+
unlink($filepath);
36+
}
37+
}
38+
39+
protected function getFileContents(string $filepath): string
40+
{
41+
if (! file_exists($filepath)) {
42+
return '';
43+
}
44+
45+
return file_get_contents($filepath) ?: '';
46+
}
47+
48+
public function testGenerateUserModel(): void
49+
{
50+
command('shield:model MyUserModel');
51+
$filepath = APPPATH . 'Models/MyUserModel.php';
52+
53+
$this->assertStringContainsString('File created: ', CITestStreamFilter::$buffer);
54+
$this->assertFileExists($filepath);
55+
56+
$this->assertStringContainsString('namespace App\Models;', $this->getFileContents($filepath));
57+
$this->assertStringContainsString('class MyUserModel extends UserModel', $this->getFileContents($filepath));
58+
$this->assertStringContainsString('use CodeIgniter\Shield\Models\UserModel;', $this->getFileContents($filepath));
59+
$this->assertStringContainsString('protected function initialize(): void', $this->getFileContents($filepath));
60+
}
61+
62+
public function testGenerateUserModelCustomNamespace(): void
63+
{
64+
command('shield:model MyUserModel --namespace CodeIgniter\\\\Shield');
65+
$filepath = HOMEPATH . 'src/Models/MyUserModel.php';
66+
67+
$this->assertStringContainsString('File created: ', CITestStreamFilter::$buffer);
68+
$this->assertFileExists($filepath);
69+
70+
$this->assertStringContainsString('namespace CodeIgniter\Shield\Models;', $this->getFileContents($filepath));
71+
$this->assertStringContainsString('class MyUserModel extends UserModel', $this->getFileContents($filepath));
72+
$this->assertStringContainsString('use CodeIgniter\Shield\Models\UserModel;', $this->getFileContents($filepath));
73+
$this->assertStringContainsString('protected function initialize(): void', $this->getFileContents($filepath));
74+
75+
if (is_file($filepath)) {
76+
unlink($filepath);
77+
}
78+
}
79+
80+
public function testGenerateUserModelWithForce(): void
81+
{
82+
command('shield:model MyUserModel');
83+
84+
command('shield:model MyUserModel --force');
85+
$this->assertStringContainsString('File overwritten: ', CITestStreamFilter::$buffer);
86+
87+
$filepath = APPPATH . 'Models/MyUserModel.php';
88+
$this->assertFileExists($filepath);
89+
}
90+
91+
public function testGenerateUserModelWithSuffix(): void
92+
{
93+
command('shield:model MyUser --suffix');
94+
$filepath = APPPATH . 'Models/MyUserModel.php';
95+
96+
$this->assertStringContainsString('File created: ', CITestStreamFilter::$buffer);
97+
$this->assertFileExists($filepath);
98+
$this->assertStringContainsString('class MyUserModel extends UserModel', $this->getFileContents($filepath));
99+
}
100+
}

0 commit comments

Comments
 (0)