From cfcaf56dfc5f671f732c53fe85797616581c4d0a Mon Sep 17 00:00:00 2001 From: danilopolani Date: Fri, 15 Mar 2024 22:20:29 +0100 Subject: [PATCH 1/7] add support for Laravel 11 --- composer.json | 13 ++-- database/migrations/1_create_users_table.php | 20 ++++++- routes/stubs/api.php.stub | 12 ---- routes/stubs/web.php.stub | 14 ----- src/Commands/Command.php | 11 ---- src/Commands/InstallCommand.php | 54 +++++++---------- src/Commands/UserCommand.php | 7 +-- src/Dto/CastableDataTransferObject.php | 37 ++++++++++++ src/Dto/ContactDto.php | 1 - src/Dto/LogTemplateDto.php | 1 - src/Exceptions/stubs/Handler.php.stub | 20 ------- src/Models/Casts/CastUsingJsonFlags.php | 15 +++++ src/Models/Casts/DataTransferObject.php | 62 ++++++++++++++++++++ src/Models/User.php | 1 + stubs/bootstrap_app.php.stub | 17 ++++++ stubs/bootstrap_providers.php.stub | 6 ++ 16 files changed, 185 insertions(+), 106 deletions(-) delete mode 100644 routes/stubs/api.php.stub delete mode 100644 routes/stubs/web.php.stub create mode 100644 src/Dto/CastableDataTransferObject.php delete mode 100644 src/Exceptions/stubs/Handler.php.stub create mode 100644 src/Models/Casts/CastUsingJsonFlags.php create mode 100644 src/Models/Casts/DataTransferObject.php create mode 100644 stubs/bootstrap_app.php.stub create mode 100644 stubs/bootstrap_providers.php.stub diff --git a/composer.json b/composer.json index e37063e..644349e 100644 --- a/composer.json +++ b/composer.json @@ -18,15 +18,14 @@ "php": "^8.1", "composer/semver": "^3.3.2", "filament/filament": "^3.2", - "flowframe/laravel-trend": "^0.1.5", - "illuminate/contracts": "^10.0", - "illuminate/database": "^10.0", - "jessarcher/laravel-castable-data-transfer-object": "^2.3", - "laravel/prompts": "^0.1.15", - "laravel/sanctum": "^3.2.1", + "flowframe/laravel-trend": "^0.2", + "illuminate/contracts": "^10.0|^11.0", + "illuminate/database": "^10.0|^11.0", + "laravel/prompts": "^0.1.16", + "laravel/sanctum": "^3.2.1|^4.0", "laravel/socialite": "^5.6.1", "livewire/livewire": "^3.4", - "nunomaduro/termwind": "^1.15.1", + "nunomaduro/termwind": "^2.0", "ralphjsmit/laravel-filament-components": "^2.0", "socialiteproviders/manager": "^4.3", "spatie/data-transfer-object": "^3.9.1", diff --git a/database/migrations/1_create_users_table.php b/database/migrations/1_create_users_table.php index a720645..229cdac 100644 --- a/database/migrations/1_create_users_table.php +++ b/database/migrations/1_create_users_table.php @@ -4,7 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration { +return new class extends Migration +{ /** * Run the migrations. */ @@ -21,6 +22,21 @@ public function up(): void $table->rememberToken(); $table->timestamps(); }); + + Schema::create('password_reset_tokens', function (Blueprint $table) { + $table->string('email')->primary(); + $table->string('token'); + $table->timestamp('created_at')->nullable(); + }); + + Schema::create('sessions', function (Blueprint $table) { + $table->string('id')->primary(); + $table->foreignId('user_id')->nullable()->index(); + $table->string('ip_address', 45)->nullable(); + $table->text('user_agent')->nullable(); + $table->longText('payload'); + $table->integer('last_activity')->index(); + }); } /** @@ -29,5 +45,7 @@ public function up(): void public function down(): void { Schema::dropIfExists('users'); + Schema::dropIfExists('password_reset_tokens'); + Schema::dropIfExists('sessions'); } }; diff --git a/routes/stubs/api.php.stub b/routes/stubs/api.php.stub deleted file mode 100644 index 51535fb..0000000 --- a/routes/stubs/api.php.stub +++ /dev/null @@ -1,12 +0,0 @@ - $value], - ['field' => $rules], - )->errors()->first('field'); - } - /** * Show a success message for a task. */ diff --git a/src/Commands/InstallCommand.php b/src/Commands/InstallCommand.php index 18982ed..95de99f 100644 --- a/src/Commands/InstallCommand.php +++ b/src/Commands/InstallCommand.php @@ -2,7 +2,6 @@ namespace MailCarrier\Commands; -use Composer\Semver\Comparator; use Illuminate\Database\QueryException; use Illuminate\Support\Facades\Schema; use Illuminate\Support\Str; @@ -60,10 +59,10 @@ protected function cleanupLaravel(): void { $this->overrideMigrations(); $this->overrideModels(); + $this->overrideBootstrap(); $this->overrideRoutes(); $this->overrideProviders(); $this->overrideViews(); - $this->overrideHandler(); $this->overrideReadme(); $this->deleteFiles(); @@ -75,7 +74,10 @@ protected function cleanupLaravel(): void */ protected function overrideMigrations(): void { - @unlink(getcwd() . '/database/migrations/2014_10_12_000000_create_users_table.php'); + // Remove existing users table + $this->call('migrate:rollback'); + + @unlink(getcwd() . '/database/migrations/0001_01_01_000000_create_users_table.php'); @unlink(getcwd() . '/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php'); } @@ -87,28 +89,22 @@ protected function overrideModels(): void copy(__DIR__ . '/../../src/Models/stubs/User.php.stub', getcwd() . '/app/Models/User.php'); } + /** + * Override the default models. + */ + protected function overrideBootstrap(): void + { + copy(__DIR__ . '/../../stubs/bootstrap_app.php.stub', getcwd() . '/bootstrap/app.php'); + copy(__DIR__ . '/../../stubs/bootstrap_providers.php.stub', getcwd() . '/bootstrap/providers.php'); + } + /** * Override the default routes. */ protected function overrideRoutes(): void { - $kernelPath = getcwd() . '/app/Console/Kernel.php'; - $kernel = file_get_contents($kernelPath); - - $kernel = str_replace( - "require base_path('routes/console.php'); - ", - '', - $kernel - ); - - file_put_contents($kernelPath, $kernel); - - @unlink(getcwd() . '/routes/channels.php'); @unlink(getcwd() . '/routes/console.php'); - - copy(__DIR__ . '/../../routes/stubs/api.php.stub', getcwd() . '/routes/api.php'); - copy(__DIR__ . '/../../routes/stubs/web.php.stub', getcwd() . '/routes/web.php'); + @unlink(getcwd() . '/routes/web.php'); } /** @@ -118,7 +114,6 @@ public function overrideProviders(): void { copy(__DIR__ . '/../Providers/stubs/AppServiceProvider.php.stub', getcwd() . '/app/Providers/AppServiceProvider.php'); copy(__DIR__ . '/../Providers/stubs/AuthServiceProvider.php.stub', getcwd() . '/app/Providers/AuthServiceProvider.php'); - copy(__DIR__ . '/../Providers/stubs/EventServiceProvider.php.stub', getcwd() . '/app/Providers/EventServiceProvider.php'); } /** @@ -134,14 +129,6 @@ protected function overrideViews(): void copy(__DIR__ . '/../../resources/views/stubs/401.blade.php.stub', $errorsTargetDir . '/401.blade.php'); } - /** - * Override the default models. - */ - protected function overrideHandler(): void - { - copy(__DIR__ . '/../../src/Exceptions/stubs/Handler.php.stub', getcwd() . '/app/Exceptions/Handler.php'); - } - /** * Override the default readme. */ @@ -167,11 +154,6 @@ protected function updateComposerJson(): void $composerJsonPath = getcwd() . '/composer.json'; $composerJson = file_get_contents($composerJsonPath); - // Set minimum PHP version - if (Comparator::lessThan($this->getComposerValue($composerJson, 'php'), '^8.1')) { - $composerJson = $this->setComposerValue($composerJson, 'php', '^8.1'); - } - // Install hook to update MailCarrier if (!str_contains($composerJson, '"@php artisan mailcarrier:upgrade"')) { $composerJson = str_replace( @@ -227,7 +209,11 @@ protected function publishVendor(): void '--tag' => 'mailcarrier-assets', ]); - $this->labeledLine('Configuration files and assets copied.'); + $this->callSilently('vendor:publish', [ + '--tag' => 'sanctum-migrations', + ]); + + $this->labeledLine('Vendor files copied.'); } /** diff --git a/src/Commands/UserCommand.php b/src/Commands/UserCommand.php index 5fe85c5..672f638 100644 --- a/src/Commands/UserCommand.php +++ b/src/Commands/UserCommand.php @@ -46,12 +46,12 @@ protected function getUserData(): array 'email' => text( 'Email address', required: true, - validate: fn (string $value) => $this->validatePrompt($value, ['email', 'unique:\MailCarrier\Models\User,email']), + validate: ['email' => 'unique:\MailCarrier\Models\User,email'], ), 'password' => password( 'Password', hint: 'Leave it blank for a random one', - validate: fn (?string $value) => $this->validatePrompt($value, ['nullable', 'min:8']), + validate: ['password' => 'nullable', 'min:8'], ), ]; @@ -60,9 +60,6 @@ protected function getUserData(): array $data['password'] = $this->rawRandomPassword = Str::password(16); } - // Finally encrypt the password - $data['password'] = Hash::make($data['password']); - return $data; } } diff --git a/src/Dto/CastableDataTransferObject.php b/src/Dto/CastableDataTransferObject.php new file mode 100644 index 0000000..d5e5e0c --- /dev/null +++ b/src/Dto/CastableDataTransferObject.php @@ -0,0 +1,37 @@ +toArray(), $options); + } + + public static function fromJson(string $json, int $options = 0) + { + // @phpstan-ignore-next-line + return new static(json_decode( + $json, + true, // assoc + 512, // depth + $options // flags + )); + } +} diff --git a/src/Dto/ContactDto.php b/src/Dto/ContactDto.php index f97d19d..164d0a6 100644 --- a/src/Dto/ContactDto.php +++ b/src/Dto/ContactDto.php @@ -2,7 +2,6 @@ namespace MailCarrier\Dto; -use JessArcher\CastableDataTransferObject\CastableDataTransferObject; use MailCarrier\Dto\Validators\Email; use Spatie\DataTransferObject\Attributes\Strict; diff --git a/src/Dto/LogTemplateDto.php b/src/Dto/LogTemplateDto.php index 7902238..2fe6bf2 100644 --- a/src/Dto/LogTemplateDto.php +++ b/src/Dto/LogTemplateDto.php @@ -2,7 +2,6 @@ namespace MailCarrier\Dto; -use JessArcher\CastableDataTransferObject\CastableDataTransferObject; use Spatie\DataTransferObject\Attributes\Strict; #[Strict] diff --git a/src/Exceptions/stubs/Handler.php.stub b/src/Exceptions/stubs/Handler.php.stub deleted file mode 100644 index c174150..0000000 --- a/src/Exceptions/stubs/Handler.php.stub +++ /dev/null @@ -1,20 +0,0 @@ -reportable(function (\Throwable $e) { - // - }); - } -} diff --git a/src/Models/Casts/CastUsingJsonFlags.php b/src/Models/Casts/CastUsingJsonFlags.php new file mode 100644 index 0000000..df4781f --- /dev/null +++ b/src/Models/Casts/CastUsingJsonFlags.php @@ -0,0 +1,15 @@ +parameters)) { + $value = '{}'; + } + + if (is_null($value)) { + return; + } + + return $this->class::fromJson($value, $this->getJsonFlags()->decode); + } + + /** + * Prepare the given value for storage. + */ + public function set($model, string $key, $value, array $attributes) + { + if (is_null($value)) { + return; + } + + if (is_array($value)) { + $value = new $this->class($value); + } + + if (!$value instanceof $this->class) { + throw new \InvalidArgumentException("Value must be of type [$this->class], array, or null"); + } + + return $value->toJson($this->getJsonFlags()->encode); + } + + protected function getJsonFlags(): CastUsingJsonFlags + { + $attributes = (new \ReflectionClass($this->class)) + ->getAttributes(CastUsingJsonFlags::class); + + return ($attributes[0] ?? null)?->newInstance() + ?? new CastUsingJsonFlags(); + } +} diff --git a/src/Models/User.php b/src/Models/User.php index 9739964..9bd5135 100644 --- a/src/Models/User.php +++ b/src/Models/User.php @@ -53,6 +53,7 @@ class User extends Authenticatable implements FilamentUser, HasAvatar, HasName */ protected $casts = [ 'oauth_raw' => 'array', + 'password' => 'hashed', ]; /** diff --git a/stubs/bootstrap_app.php.stub b/stubs/bootstrap_app.php.stub new file mode 100644 index 0000000..c76add0 --- /dev/null +++ b/stubs/bootstrap_app.php.stub @@ -0,0 +1,17 @@ +withRouting() + ->withMiddleware() + ->withExceptions(function (Exceptions $exceptions) { + $exceptions->render(function (RouteNotFoundException $e) { + if (str_contains($e->getMessage(), '[login]')) { + return redirect('/login'); + } + }); + }) + ->create(); diff --git a/stubs/bootstrap_providers.php.stub b/stubs/bootstrap_providers.php.stub new file mode 100644 index 0000000..8dc3a48 --- /dev/null +++ b/stubs/bootstrap_providers.php.stub @@ -0,0 +1,6 @@ + Date: Fri, 15 Mar 2024 22:22:20 +0100 Subject: [PATCH 2/7] fix icon on send test email from template --- src/Resources/TemplateResource/Pages/EditTemplate.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Resources/TemplateResource/Pages/EditTemplate.php b/src/Resources/TemplateResource/Pages/EditTemplate.php index 228f63a..179b194 100644 --- a/src/Resources/TemplateResource/Pages/EditTemplate.php +++ b/src/Resources/TemplateResource/Pages/EditTemplate.php @@ -86,7 +86,7 @@ protected function sendTestMail(array $data): void Notification::make() ->title('Test email sent correctly') - ->icon('heroicon-o-mail') + ->icon('heroicon-o-envelope') ->success() ->send(); } From 4bdd52ae7f605ce7a9dbe2b6abe727d6fb6552bf Mon Sep 17 00:00:00 2001 From: danilopolani Date: Fri, 15 Mar 2024 22:22:49 +0100 Subject: [PATCH 3/7] format --- database/migrations/1_create_users_table.php | 3 +-- src/Commands/Command.php | 1 - src/Commands/UserCommand.php | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/database/migrations/1_create_users_table.php b/database/migrations/1_create_users_table.php index 229cdac..689d4c4 100644 --- a/database/migrations/1_create_users_table.php +++ b/database/migrations/1_create_users_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/src/Commands/Command.php b/src/Commands/Command.php index 52d1112..ac23388 100644 --- a/src/Commands/Command.php +++ b/src/Commands/Command.php @@ -2,7 +2,6 @@ namespace MailCarrier\Commands; -use Illuminate\Support\Facades\Validator; use function Termwind\render; abstract class Command extends \Illuminate\Console\Command diff --git a/src/Commands/UserCommand.php b/src/Commands/UserCommand.php index 672f638..5faa305 100644 --- a/src/Commands/UserCommand.php +++ b/src/Commands/UserCommand.php @@ -3,7 +3,6 @@ namespace MailCarrier\Commands; use Illuminate\Support\Facades\Config; -use Illuminate\Support\Facades\Hash; use Illuminate\Support\Str; use MailCarrier\Models\User; use function Laravel\Prompts\password; From afa4a429443909970226527442b64f0b06d25e5e Mon Sep 17 00:00:00 2001 From: danilopolani Date: Fri, 15 Mar 2024 22:23:58 +0100 Subject: [PATCH 4/7] add laravel 11 to github workflow --- .github/workflows/run-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index d47f2fd..b5dac9c 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -13,7 +13,7 @@ jobs: fail-fast: true matrix: php: [8.1, 8.2, 8.3] - laravel: [10.*] + laravel: [10.*, 11.*] name: P${{ matrix.php }} - L${{ matrix.laravel }} From faa6e1e5d3058ee4b4bea0c56d087f9f65e0fcde Mon Sep 17 00:00:00 2001 From: danilopolani Date: Sat, 16 Mar 2024 11:26:37 +0100 Subject: [PATCH 5/7] update dependencies --- composer.json | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index 644349e..c32777b 100644 --- a/composer.json +++ b/composer.json @@ -16,9 +16,8 @@ ], "require": { "php": "^8.1", - "composer/semver": "^3.3.2", "filament/filament": "^3.2", - "flowframe/laravel-trend": "^0.2", + "flowframe/laravel-trend": "^0.1.5|^0.2", "illuminate/contracts": "^10.0|^11.0", "illuminate/database": "^10.0|^11.0", "laravel/prompts": "^0.1.16", @@ -35,14 +34,13 @@ "filament/upgrade": "^3.2", "larastan/larastan": "^2.8", "laravel/pint": "^1.7", - "nunomaduro/collision": "^7.0", - "orchestra/testbench": "^8.0", + "nunomaduro/collision": "^7.0|^8.1", + "orchestra/testbench": "^8.0|^9.0", "pestphp/pest": "^2.3", "pestphp/pest-plugin-faker": "^2.0", "pestphp/pest-plugin-laravel": "^2.0", "phpstan/extension-installer": "^1.2", "phpstan/phpstan-deprecation-rules": "^1.1.3", - "spatie/invade": "^1.1.1", "spatie/laravel-package-tools": "^1.16" }, "autoload": { From 0aa453be94492fb90b4996f1bb25c0701aed4aba Mon Sep 17 00:00:00 2001 From: danilopolani Date: Sat, 16 Mar 2024 11:40:24 +0100 Subject: [PATCH 6/7] update dependencies --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index c32777b..ad3913a 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ "laravel/sanctum": "^3.2.1|^4.0", "laravel/socialite": "^5.6.1", "livewire/livewire": "^3.4", - "nunomaduro/termwind": "^2.0", + "nunomaduro/termwind": "^1.15|^2.0", "ralphjsmit/laravel-filament-components": "^2.0", "socialiteproviders/manager": "^4.3", "spatie/data-transfer-object": "^3.9.1", From 235f2d22a59525a55fd0c0885407a9945fa5ec54 Mon Sep 17 00:00:00 2001 From: danilopolani Date: Sat, 16 Mar 2024 11:44:03 +0100 Subject: [PATCH 7/7] exclude Laravel 11 from PHP8.1 tests --- .github/workflows/run-tests.yml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index b5dac9c..69e0f2a 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -13,9 +13,17 @@ jobs: fail-fast: true matrix: php: [8.1, 8.2, 8.3] - laravel: [10.*, 11.*] - - name: P${{ matrix.php }} - L${{ matrix.laravel }} + laravel: ["^11.0", "^10.0"] + include: + - laravel: "^11.0" + testbench: 9.* + - laravel: "^10.0" + testbench: 8.* + exclude: + - laravel: "^11.0" + php: 8.1 + + name: PHP ${{ matrix.php }} - Laravel ${{ matrix.laravel }} steps: - name: Checkout code