Skip to content

Commit ad8e7ee

Browse files
Merge pull request #8 from michaeldyrynda/chore/laravel-5.7-support
Laravel 5.7 support
2 parents 262d2e1 + 3e89923 commit ad8e7ee

File tree

10 files changed

+53
-263
lines changed

10 files changed

+53
-263
lines changed

.styleci.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1 @@
11
preset: laravel
2-
3-
linting: true

.travis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ cache:
77
matrix:
88
include:
99
- php: 7.1
10-
env: ILLUMINATE_VERSION=5.6.*
10+
env: ILLUMINATE_VERSION=5.7.*
1111
- php: 7.2
12-
env: ILLUMINATE_VERSION=5.6.*
12+
env: ILLUMINATE_VERSION=5.7.*
1313

1414
before_install: travis_retry composer require "illuminate/database:${ILLUMINATE_VERSION}" "illuminate/events:${ILLUMINATE_VERSION}" --no-update -v
1515

README.md

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Laravel Make User
2-
## v3.0.0
2+
## v4.0.0
33

44
[![Build Status](https://travis-ci.org/michaeldyrynda/laravel-make-user.svg?branch=master)](https://travis-ci.org/michaeldyrynda/laravel-make-user)
55
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/michaeldyrynda/laravel-make-user/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/michaeldyrynda/laravel-make-user/?branch=master)
@@ -11,7 +11,7 @@
1111

1212
## Introduction
1313

14-
Out of the box, Laravel makes it really simple to scaffold out with its [authentication quickstart](https://laravel.com/docs/5.4/authentication#authentication-quickstart). Whilst this makes it really easy to register and authenticate users, for many of the applications I find myself building, we usually remove the ability for visitors to register themselves.
14+
Out of the box, Laravel makes it really simple to scaffold out with its [authentication quickstart](https://laravel.com/docs/5.7/authentication#authentication-quickstart). Whilst this makes it really easy to register and authenticate users, for many of the applications I find myself building, we usually remove the ability for visitors to register themselves.
1515

1616
I still need a way to get users into those applications, however, and whilst they're in early development this usually involves firing up Laravel Tinker. This can be a tedious process, and one that I repeat many times over.
1717

@@ -24,45 +24,26 @@ Laravel | Package
2424
5.4.* | 1.0.*
2525
5.5.* | 2.0.*
2626
5.6.* | 3.0.*
27+
5.7.* | 4.0.*
2728

2829
## Code Samples
2930

3031
This package exposes a `make:user` command, which is accessed via the Artisan command line utility. The package will use the model defined in your `auth.providers.users.model` configuration value.
3132

3233
```
33-
php artisan make:user email {--name=NAME} {--password=PASSWORD} {--send-reset} {--fields=FIELDS} {--force}
34+
php artisan make:user
3435
```
3536

36-
If the password is not specified, the `--send-reset` option is implicit, sending the default password reset notification to the user. This package does not currently provide support to customise the content or notification sent as my general practice is to create a user account, then have the user manually perform a password reset. The implied `--send-reset` saves a manual step in this process.
37-
38-
This package runs on the assumption that you are using Laravel's default `users` table structure. If you have additional columns in your database, they can be specified using the `--fields` option, separating each key/value pair with a comma:
39-
40-
```
41-
php artisan make:user [email protected] --fields="admin:true,other_field:other value"
42-
```
43-
44-
This will create a new user with the email address `[email protected]`, a randomly generated password, send the password reset email to `[email protected]`, and set the `admin` field to `true`. Should you need to circumvent your user model's guarded fields, you can pass the `--force` option, and the user model will be created using the `forceCreate` method.
37+
This package runs on the assumption that you are using Laravel's default `users` table structure. You can specify additional fields when prompted.
4538

4639
## Installation
4740

4841
This package is installed via [Composer](https://getcomposer.org/). To install, run the following command.
4942

5043
```bash
51-
composer require "dyrynda/laravel-make-user:~3.0"
44+
composer require "dyrynda/laravel-make-user:~4.0"
5245
```
5346

54-
Then add the service provider to your `config/app.php` file:
55-
56-
```php
57-
'providers' => [
58-
// ...
59-
Dyrynda\Artisan\MakeUserServiceProvider::class,
60-
// ...
61-
]
62-
```
63-
64-
Note, this package has support for Laravel's auto package discovery, which will be available from version 5.5 onwards.
65-
6647
## Support
6748

6849
If you are having general issues with this package, feel free to contact me on [Twitter](https://twitter.com/michaeldyrynda).

composer.json

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,22 @@
1111
}
1212
],
1313
"require": {
14-
"php": ">=7.1.3",
15-
"illuminate/support": "5.6.*",
16-
"illuminate/console": "5.6.*",
17-
"illuminate/database": "5.6.*",
18-
"illuminate/auth": "5.6.*",
19-
"illuminate/notifications": "5.6.*"
14+
"php": "^7.1.3",
15+
"illuminate/support": "5.7.*",
16+
"illuminate/console": "5.7.*",
17+
"illuminate/database": "5.7.*",
18+
"illuminate/auth": "5.7.*",
19+
"illuminate/notifications": "5.7.*"
2020
},
2121
"autoload": {
2222
"psr-4": {
2323
"Dyrynda\\Artisan\\": "src/"
2424
}
2525
},
2626
"require-dev": {
27+
"mockery/mockery": "^1.0",
2728
"phpunit/phpunit": "~7.0",
28-
"orchestra/testbench": "~3.0"
29+
"orchestra/testbench": "^3.7"
2930
},
3031
"autoload-dev": {
3132
"psr-4": {

phpunit.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,7 @@
1919
<directory suffix=".php">src/</directory>
2020
</whitelist>
2121
</filter>
22+
<php>
23+
<env name="MAIL_DRIVER" value="null"/>
24+
</php>
2225
</phpunit>

src/Console/Commands/MakeUser.php

Lines changed: 19 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,7 @@ class MakeUser extends Command
1414
*
1515
* @var string
1616
*/
17-
protected $signature = 'make:user {email} {--name= : Set the name for the new user}
18-
{--password= : The password to set for the new user}
19-
{--send-reset : Send a password reset email for the new user}
20-
{--fields= : Additional database fields to set on the user}
21-
{--force : Create the user model circumventing guarded fields}';
17+
protected $signature = 'make:user';
2218

2319
/**
2420
* The console command description.
@@ -27,6 +23,13 @@ class MakeUser extends Command
2723
*/
2824
protected $description = 'Create a new application user';
2925

26+
/**
27+
* Array of custom fields to attach to the user.
28+
*
29+
* @var array
30+
*/
31+
protected $customFields = [];
32+
3033
/**
3134
* Execute the console command.
3235
*
@@ -36,20 +39,24 @@ class MakeUser extends Command
3639
*/
3740
public function handle()
3841
{
39-
$email = $this->argument('email');
40-
$name = $this->option('name') ?: '';
41-
$password = bcrypt($this->option('password') ?: str_random(32));
42-
$modelCommand = $this->option('force') ? 'forceCreate' : 'create';
43-
$sendReset = ! $this->option('password') || $this->option('send-reset');
42+
$email = $this->ask("What is the new user's email address?");
43+
$name = $this->ask("What is the new user's name?") ?: '';
44+
$password = bcrypt($this->secret("What is the new user's password? (blank generates a random one)", str_random(32)));
45+
$sendReset = $this->confirm('Do you want to send a password reset email?');
46+
47+
while ($custom = $this->ask('Do you have any custom user fields to add? Field=Value (blank continues)', false)) {
48+
list($key, $value) = explode('=', $custom);
49+
$this->customFields[$key] = value($value);
50+
}
4451

4552
try {
4653
app('db')->beginTransaction();
4754

4855
$this->validateEmail($email);
4956

50-
app(config('auth.providers.users.model'))->{$modelCommand}(array_merge(
57+
app(config('auth.providers.users.model'))->create(array_merge(
5158
compact('email', 'name', 'password'),
52-
$this->additionalFields()
59+
$this->customFields
5360
));
5461

5562
if ($sendReset) {
@@ -88,45 +95,4 @@ private function validateEmail($email)
8895
throw MakeUserException::emailExists($email);
8996
}
9097
}
91-
92-
/**
93-
* Return any additional database fields passed by the --fields option.
94-
*
95-
* @return array
96-
*/
97-
private function additionalFields()
98-
{
99-
if (! $this->option('fields')) {
100-
return [];
101-
}
102-
103-
return collect(explode(',', $this->option('fields')))->mapWithKeys(function ($field) {
104-
list($column, $value) = explode(':', $field);
105-
106-
return [trim($column) => $this->normaliseValue($value)];
107-
})->toArray();
108-
}
109-
110-
/**
111-
* Normalise the given (database) field input value.
112-
*
113-
* @param mixed $value
114-
* @return mixed
115-
*/
116-
private function normaliseValue($value)
117-
{
118-
if ($value == 'null') {
119-
return;
120-
}
121-
122-
if (in_array($value, [1, 'true', true], true)) {
123-
return true;
124-
}
125-
126-
if (in_array($value, [0, 'false', false], true)) {
127-
return false;
128-
}
129-
130-
return trim($value);
131-
}
13298
}

tests/MakeUserTest.php

Lines changed: 15 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -2,116 +2,28 @@
22

33
namespace Tests;
44

5-
use Illuminate\Support\Facades\Hash;
6-
use Illuminate\Support\Facades\Artisan;
7-
use Illuminate\Support\Facades\Notification;
8-
use Illuminate\Auth\Notifications\ResetPassword;
9-
105
class MakeUserTest extends TestCase
116
{
127
/** @test */
13-
public function it_requires_a_valid_email_address()
14-
{
15-
Artisan::call('make:user', ['email' => 'invalidemail']);
16-
17-
$this->assertFalse(User::where('email', 'invalidemail')->exists());
18-
}
19-
20-
/** @test */
21-
public function it_requires_a_unique_email_address()
22-
{
23-
User::create(['name' => 'Adam Wathan', 'email' => '[email protected]', 'password' => '']);
24-
25-
$exitCode = Artisan::call('make:user', ['email' => '[email protected]']);
26-
27-
$this->assertContains('The user was not created', Artisan::output());
28-
$this->assertEquals(1, User::where('email', '[email protected]')->count());
29-
}
30-
31-
/** @test */
32-
public function it_hashes_the_password_when_specified()
33-
{
34-
Artisan::call('make:user', ['email' => '[email protected]', '--password' => 'secret']);
35-
36-
tap(User::first(), function ($user) {
37-
$this->assertTrue(Hash::check('secret', $user->password));
38-
});
39-
}
40-
41-
/** @test */
42-
public function it_sends_the_password_reset_email_when_generating_a_password()
43-
{
44-
Notification::fake();
45-
46-
Artisan::call('make:user', ['email' => '[email protected]', '--name' => 'Michael Dyrynda']);
47-
48-
Notification::assertSentTo(User::first(), ResetPassword::class);
49-
50-
tap(['email' => '[email protected]', 'name' => 'Michael Dyrynda'], function ($credentials) {
51-
$this->assertTrue(User::where($credentials)->exists());
52-
$this->assertEquals(1, User::where($credentials)->count());
53-
});
54-
}
55-
56-
/** @test */
57-
public function it_does_not_send_the_password_reset_email_when_the_password_is_specified()
58-
{
59-
Notification::fake();
60-
61-
Artisan::call('make:user', ['email' => '[email protected]', '--password' => 'secret']);
62-
63-
Notification::assertNotSentTo(User::first(), ResetPassword::class);
64-
65-
tap(['email' => '[email protected]'], function ($credentials) {
66-
$this->assertTrue(User::where($credentials)->exists());
67-
$this->assertEquals(1, User::where($credentials)->count());
68-
});
69-
}
70-
71-
/** @test */
72-
public function it_sends_the_password_reset_email_when_flagged_to_do_so()
73-
{
74-
Notification::fake();
75-
76-
Artisan::call('make:user', ['email' => '[email protected]', '--password' => 'secret', '--send-reset' => true]);
77-
78-
Notification::assertSentTo(User::first(), ResetPassword::class);
79-
}
80-
81-
/** @test */
82-
public function it_fills_additional_fields_when_specified()
8+
public function it_creates_a_new_user()
839
{
84-
Artisan::call('make:user', ['email' => '[email protected]', '--password' => 'secret', '--fields' => 'admin:true']);
85-
86-
$this->assertTrue(User::where([
87-
'email' => '[email protected]',
88-
'admin' => true,
89-
])->exists());
10+
$this->artisan('make:user')
11+
->expectsQuestion("What is the new user's email address?", '[email protected]')
12+
->expectsQuestion("What is the new user's name?", 'Test User')
13+
->expectsQuestion("What is the new user's password? (blank generates a random one)", '')
14+
->expectsQuestion('Do you want to send a password reset email?', 'no')
15+
->expectsQuestion('Do you have any custom user fields to add? Field=Value (blank continues)', '');
9016
}
9117

9218
/** @test */
93-
public function it_handles_null_field_values_correctly()
19+
public function it_creates_a_new_user_with_additional_fields()
9420
{
95-
Artisan::call('make:user', ['email' => '[email protected]', '--fields' => 'force_filled:null']);
96-
97-
tap(User::first(), function ($user) {
98-
$this->assertNull($user->force_filled);
99-
});
100-
}
101-
102-
/** @test */
103-
public function it_force_filles_guarded_properties_when_instructed()
104-
{
105-
Artisan::call('make:user', [
106-
'email' => '[email protected]',
107-
'--password' => 'secret',
108-
'--force' => true,
109-
'--fields' => 'admin:false,force_filled:string field',
110-
]);
111-
112-
tap(User::first(), function ($user) {
113-
$this->assertFalse($user->admin);
114-
$this->assertEquals('string field', $user->force_filled);
115-
});
21+
$this->artisan('make:user')
22+
->expectsQuestion("What is the new user's email address?", '[email protected]')
23+
->expectsQuestion("What is the new user's name?", 'Test User')
24+
->expectsQuestion("What is the new user's password? (blank generates a random one)", '')
25+
->expectsQuestion('Do you want to send a password reset email?', 'no')
26+
->expectsQuestion('Do you have any custom user fields to add? Field=Value (blank continues)', 'field=value')
27+
->expectsQuestion('Do you have any custom user fields to add? Field=Value (blank continues)', '');
11628
}
11729
}

tests/TestCase.php

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,29 +7,10 @@
77

88
abstract class TestCase extends Orchestra
99
{
10-
public function setUp()
11-
{
12-
parent::setUp();
13-
14-
$this->loadLaravelMigrations('testing');
15-
16-
$this->loadMigrationsFrom(realpath(__DIR__.'/migrations'));
17-
}
18-
1910
protected function getPackageProviders($app)
2011
{
2112
return [
2213
MakeUserServiceProvider::class,
2314
];
2415
}
25-
26-
protected function getEnvironmentSetUp($app)
27-
{
28-
$app['config']->set('database.connections.testing', [
29-
'driver' => 'sqlite',
30-
'database' => ':memory:',
31-
]);
32-
$app['config']->set('auth.providers.users.model', User::class);
33-
$app['router']->get('/password/reset')->name('password.reset');
34-
}
3516
}

0 commit comments

Comments
 (0)