From e61a26d6048519f58193e6c85483ebb4285bade0 Mon Sep 17 00:00:00 2001 From: lukinovec Date: Mon, 20 Feb 2023 23:47:10 +0100 Subject: [PATCH] Add L10 support to 4.x (merge 3.x to master) (#1071) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * exclude master from CI * Add space after 'up' in 'docker-compose up-d' (#900) * Fix ArgumentCountError on the TenantAssetsController (#894) * Fix ArgumentCount exception on the TenantAssetsController when no `$path` is provided * CS * CS * Handle null case explicitly * code style Co-authored-by: Bram Wubs Co-authored-by: Samuel Štancl * Add support for nested tenant config override (#920) * feat: add support for nested tenant config override * test: ensure nested tenant values are mapped * fix: typo mistake (#954) * [3.x] Add Vite helper for tenancy (#956) * Add Vite helper for tenancy * Move Vite bundler to an Optional Feature * Rename to foundation vite * Add ViteBundlerTest * Add missing end of file * Update tests * remove unnecessary end() call Co-authored-by: Samuel Štancl * rewrite ViteBundlerTest to phpunit syntax * skip vite test in Laravel < 9 * convert ViteBundler to PHP 7 syntax * remove import of nonexistent class in older Laravel versions * remove import of Foundation\Vite in tests * try to exclude Vite.php from coverage report * remove typehint * update channel name * Cache crash fix (#1048) * Don't prevent accessing missing Tenant attributes. (#1045) * [3.x] L10 compatibility (#1065) * Bump dependencies for Laravel 10 * Update GitHub Actions for Laravel 10 * ci: do not test L10 using PHP 7.3 * drop < L9 support * use `dispatch_sync` instead of `dispatch_now` * migrate phpunit configuration * Update ci.yml * drop laravel < 9 support * misc L10 fixes, new docker image * specify odbc version * wip * properly list php versions as strings * minor changes * Add `getValue($queryGrammar)` to raw query * Clean up `isVersion8` code * rewrite hasFailed assertion * phpunit schema update * Upgrade `doctrine/dbal` --------- Co-authored-by: Samuel Štancl Co-authored-by: Samuel Štancl Co-authored-by: lukinovec * Update ci.yml * Fix code style (php-cs-fixer) * Update dependencies * Change invade version * Delete ViteBundlerTest * Fix PHPStan error * Delete PHPStan error ignore * Fix CONTRIBUTING.md * Delete ViteBundler remains * Bring back ViteBundler * Convert ViteBundlerTest to Pest * Update ci.yml --------- Co-authored-by: Samuel Štancl Co-authored-by: Bram Wubs Co-authored-by: Bram Wubs Co-authored-by: Samuel Štancl Co-authored-by: George Bishop Co-authored-by: Anbuselvan Rocky <15264938+anburocky3@users.noreply.github.com> Co-authored-by: Wilsen Hernández <13445515+wilsenhc@users.noreply.github.com> Co-authored-by: Joel Stein Co-authored-by: Guilherme Saade Co-authored-by: PHP CS Fixer --- .github/workflows/ci.yml | 8 +++-- assets/config.php | 3 +- composer.json | 17 ++++++----- phpstan.neon | 4 --- src/Database/Models/ImpersonationToken.php | 5 ++-- src/Database/Models/Tenant.php | 2 ++ ...rmissionControlledMySQLDatabaseManager.php | 3 +- src/Features/ViteBundler.php | 26 +++++++++++++++++ src/TenancyServiceProvider.php | 1 + src/Vite.php | 22 ++++++++++++++ tests/EventListenerTest.php | 7 +++-- tests/Features/ViteBundlerTest.php | 29 +++++++++++++++++++ tests/TenantDatabaseManagerTest.php | 4 +-- 13 files changed, 107 insertions(+), 24 deletions(-) create mode 100644 src/Features/ViteBundler.php create mode 100644 src/Vite.php create mode 100644 tests/Features/ViteBundlerTest.php diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 314d6e4c..8ecb863b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,11 @@ jobs: strategy: matrix: - laravel: ['^9.0'] + include: + - laravel: 9 + php: "8.0" + - laravel: 10 + php: "8.1" steps: - name: Checkout @@ -23,7 +27,7 @@ jobs: - name: Install Composer dependencies run: | - composer require "laravel/framework:${{ matrix.laravel }}" --no-interaction --no-update + composer require "laravel/framework:^${{ matrix.laravel }}.0" --no-interaction --no-update composer update --prefer-dist --no-interaction - name: Run tests run: ./vendor/bin/pest diff --git a/assets/config.php b/assets/config.php index bbfa9974..7fc6c928 100644 --- a/assets/config.php +++ b/assets/config.php @@ -258,7 +258,7 @@ return [ ], /** - * Redis tenancy config. Used by RedisTenancyBoostrapper. + * Redis tenancy config. Used by RedisTenancyBootstrapper. * * Note: You need phpredis to use Redis tenancy. * @@ -286,6 +286,7 @@ return [ // Stancl\Tenancy\Features\TelescopeTags::class, // Stancl\Tenancy\Features\TenantConfig::class, // https://tenancyforlaravel.com/docs/v3/features/tenant-config // Stancl\Tenancy\Features\CrossDomainRedirect::class, // https://tenancyforlaravel.com/docs/v3/features/cross-domain-redirect + // Stancl\Tenancy\Features\ViteBundler::class, ], /** diff --git a/composer.json b/composer.json index bb11040e..b5734c1b 100644 --- a/composer.json +++ b/composer.json @@ -17,18 +17,19 @@ "require": { "php": "^8.2", "ext-json": "*", - "illuminate/support": "^9.38", + "illuminate/support": "^9.38|^10.0", + "facade/ignition-contracts": "^1.0.2", "spatie/ignition": "^1.4", - "ramsey/uuid": "^4.0", - "stancl/jobpipeline": "^1.0", - "stancl/virtualcolumn": "^1.3", + "ramsey/uuid": "^4.7.3", + "stancl/jobpipeline": "^1.6.2", + "stancl/virtualcolumn": "^1.3.1", "spatie/invade": "^1.1" }, "require-dev": { - "laravel/framework": "^9.38", - "orchestra/testbench": "^7.0", - "league/flysystem-aws-s3-v3": "^3.0", - "doctrine/dbal": "^2.10", + "laravel/framework": "^9.38|^10.0", + "orchestra/testbench": "^7.0|^8.0", + "league/flysystem-aws-s3-v3": "^3.12.2", + "doctrine/dbal": "^3.6.0", "spatie/valuestore": "^1.2.5", "pestphp/pest": "^1.21", "nunomaduro/larastan": "^2.4", diff --git a/phpstan.neon b/phpstan.neon index 91e9f3af..19cda805 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -40,10 +40,6 @@ parameters: message: '#Illuminate\\Routing\\UrlGenerator#' paths: - src/Bootstrappers/FilesystemTenancyBootstrapper.php - - - message: '#select\(\) expects string, Illuminate\\Database\\Query\\Expression given#' - paths: - - src/Database/TenantDatabaseManagers/PermissionControlledMySQLDatabaseManager.php - message: '#Trying to invoke Closure\|null but it might not be a callable#' paths: diff --git a/src/Database/Models/ImpersonationToken.php b/src/Database/Models/ImpersonationToken.php index 05d17ad4..3d7b595b 100644 --- a/src/Database/Models/ImpersonationToken.php +++ b/src/Database/Models/ImpersonationToken.php @@ -33,9 +33,8 @@ class ImpersonationToken extends Model public $incrementing = false; protected $table = 'tenant_user_impersonation_tokens'; - - protected $dates = [ - 'created_at', + protected $casts = [ + 'created_at' => 'datetime', ]; public static function booted(): void diff --git a/src/Database/Models/Tenant.php b/src/Database/Models/Tenant.php index 37c2af2d..c3574942 100644 --- a/src/Database/Models/Tenant.php +++ b/src/Database/Models/Tenant.php @@ -32,6 +32,8 @@ class Tenant extends Model implements Contracts\Tenant Concerns\InitializationHelpers, Concerns\InvalidatesResolverCache; + protected static $modelsShouldPreventAccessingMissingAttributes = false; + protected $table = 'tenants'; protected $primaryKey = 'id'; protected $guarded = []; diff --git a/src/Database/TenantDatabaseManagers/PermissionControlledMySQLDatabaseManager.php b/src/Database/TenantDatabaseManagers/PermissionControlledMySQLDatabaseManager.php index f7e7440e..308d8786 100644 --- a/src/Database/TenantDatabaseManagers/PermissionControlledMySQLDatabaseManager.php +++ b/src/Database/TenantDatabaseManagers/PermissionControlledMySQLDatabaseManager.php @@ -41,7 +41,8 @@ class PermissionControlledMySQLDatabaseManager extends MySQLDatabaseManager impl protected function isVersion8(): bool { - $version = $this->database()->select($this->database()->raw('select version()'))[0]->{'version()'}; + $versionSelect = (string) $this->database()->raw('select version()')->getValue($this->database()->getQueryGrammar()); + $version = $this->database()->select($versionSelect)[0]->{'version()'}; return version_compare($version, '8.0.0') >= 0; } diff --git a/src/Features/ViteBundler.php b/src/Features/ViteBundler.php new file mode 100644 index 00000000..e3fee2fa --- /dev/null +++ b/src/Features/ViteBundler.php @@ -0,0 +1,26 @@ +app = $app; + } + + public function bootstrap(Tenancy $tenancy): void + { + $this->app->singleton(\Illuminate\Foundation\Vite::class, Vite::class); + } +} diff --git a/src/TenancyServiceProvider.php b/src/TenancyServiceProvider.php index 23fb6473..bde37055 100644 --- a/src/TenancyServiceProvider.php +++ b/src/TenancyServiceProvider.php @@ -62,6 +62,7 @@ class TenancyServiceProvider extends ServiceProvider $this->app->singleton(Commands\Rollback::class, function ($app) { return new Commands\Rollback($app['migrator']); }); + $this->app->singleton(Commands\Seed::class, function ($app) { return new Commands\Seed($app['db']); }); diff --git a/src/Vite.php b/src/Vite.php new file mode 100644 index 00000000..ca47fcc3 --- /dev/null +++ b/src/Vite.php @@ -0,0 +1,22 @@ +assertFalse($tenant->database()->manager()->databaseExists( $tenant->database()->getName() @@ -171,12 +171,13 @@ test('database is not migrated if creation is disabled', function () { })->toListener() ); - Tenant::create([ + $tenant = Tenant::create([ 'tenancy_create_database' => false, 'tenancy_db_name' => 'already_created', ]); - expect(pest()->hasFailed())->toBeFalse(); + // assert test didn't fail + $this->assertTrue($tenant->exists()); }); class FooListener extends QueueableListener diff --git a/tests/Features/ViteBundlerTest.php b/tests/Features/ViteBundlerTest.php new file mode 100644 index 00000000..0d4c9069 --- /dev/null +++ b/tests/Features/ViteBundlerTest.php @@ -0,0 +1,29 @@ +toBeInstanceOf(Vite::class); + expect($vite)->not()->toBeInstanceOf(StanclVite::class); + + config([ + 'tenancy.features' => [ViteBundler::class], + ]); + + $tenant = Tenant::create(); + + tenancy()->initialize($tenant); + + app()->forgetInstance(Vite::class); + + $vite = app(Vite::class); + + expect($vite)->toBeInstanceOf(StanclVite::class); +}); diff --git a/tests/TenantDatabaseManagerTest.php b/tests/TenantDatabaseManagerTest.php index 5d9a15d6..c776d7a1 100644 --- a/tests/TenantDatabaseManagerTest.php +++ b/tests/TenantDatabaseManagerTest.php @@ -302,7 +302,7 @@ test('database credentials can be provided to PermissionControlledMySQLDatabaseM $mysql2DB->statement("CREATE USER `{$username}`@`%` IDENTIFIED BY '{$password}';"); $mysql2DB->statement("GRANT ALL PRIVILEGES ON *.* TO `{$username}`@`%` identified by '{$password}' WITH GRANT OPTION;"); $mysql2DB->statement("FLUSH PRIVILEGES;"); - + DB::purge('mysql2'); // forget the mysql2 connection so that it uses the new credentials the next time config(['database.connections.mysql2.username' => $username]); @@ -347,7 +347,7 @@ test('tenant database can be created by using the username and password from ten $mysqlDB->statement("CREATE USER `{$username}`@`%` IDENTIFIED BY '{$password}';"); $mysqlDB->statement("GRANT ALL PRIVILEGES ON *.* TO `{$username}`@`%` identified by '{$password}' WITH GRANT OPTION;"); $mysqlDB->statement("FLUSH PRIVILEGES;"); - + DB::purge('mysql2'); // forget the mysql2 connection so that it uses the new credentials the next time // Remove `mysql` credentials to make sure we will be using the credentials from the tenant config