diff --git a/phpstan.neon b/phpstan.neon index 0567d5ff..a6bce96d 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -16,14 +16,17 @@ parameters: ignoreErrors: - '#Cannot access offset (.*?) on Illuminate\\Contracts\\Foundation\\Application#' - '#Cannot access offset (.*?) on Illuminate\\Contracts\\Config\\Repository#' + - + message: '#Call to an undefined (method|static method) Illuminate\\Database\\Eloquent\\(Model|Builder)#' + paths: + - src/Commands/CreatePendingTenants.php + - src/Commands/ClearPendingTenants.php + - src/Database/Concerns/PendingScope.php + - src/Database/ParentModelScope.php - message: '#invalid type Laravel\\Telescope\\IncomingEntry#' paths: - src/Features/TelescopeTags.php - - - message: '#Call to an undefined method Illuminate\\Database\\Eloquent\\Model::getRelationshipToPrimaryModel\(\)#' - paths: - - src/Database/ParentModelScope.php - message: '#Parameter \#1 \$key of method Illuminate\\Contracts\\Cache\\Repository::put\(\) expects string#' paths: @@ -44,6 +47,7 @@ parameters: message: '#Trying to invoke Closure\|null but it might not be a callable#' paths: - src/Database/DatabaseConfig.php + - '#Method Stancl\\Tenancy\\Tenancy::cachedResolvers\(\) should return array#' checkMissingIterableValueType: false treatPhpDocTypesAsCertain: false diff --git a/src/Commands/ClearPendingTenants.php b/src/Commands/ClearPendingTenants.php index 18d9fa42..19d31195 100644 --- a/src/Commands/ClearPendingTenants.php +++ b/src/Commands/ClearPendingTenants.php @@ -9,27 +9,14 @@ use Illuminate\Database\Eloquent\Builder; class ClearPendingTenants extends Command { - /** - * The name and signature of the console command. - * - * @var string - */ protected $signature = 'tenants:pending-clear {--all : Override the default settings and deletes all pending tenants} {--older-than-days= : Deletes all pending tenants older than the amount of days} {--older-than-hours= : Deletes all pending tenants older than the amount of hours}'; - /** - * The console command description. - * - * @var string - */ protected $description = 'Remove pending tenants.'; - /** - * Execute the console command. - */ - public function handle() + public function handle(): int { $this->info('Removing pending tenants.'); @@ -39,7 +26,10 @@ class ClearPendingTenants extends Command // Skip the time constraints if the 'all' option is given if (! $this->option('all')) { + /** @var ?int $olderThanDays */ $olderThanDays = $this->option('older-than-days'); + + /** @var ?int $olderThanHours */ $olderThanHours = $this->option('older-than-hours'); if ($olderThanDays && $olderThanHours) { @@ -70,5 +60,7 @@ class ClearPendingTenants extends Command ->count(); $this->info($deletedTenantCount . ' pending ' . str('tenant')->plural($deletedTenantCount) . ' deleted.'); + + return 0; } } diff --git a/src/Commands/CreatePendingTenants.php b/src/Commands/CreatePendingTenants.php index 88202093..7b2c7934 100644 --- a/src/Commands/CreatePendingTenants.php +++ b/src/Commands/CreatePendingTenants.php @@ -8,24 +8,11 @@ use Illuminate\Console\Command; class CreatePendingTenants extends Command { - /** - * The name and signature of the console command. - * - * @var string - */ protected $signature = 'tenants:pending-create {--count= : The number of pending tenants to be created}'; - /** - * The console command description. - * - * @var string - */ protected $description = 'Create pending tenants.'; - /** - * Execute the console command. - */ - public function handle() + public function handle(): int { $this->info('Creating pending tenants.'); @@ -46,13 +33,11 @@ class CreatePendingTenants extends Command $this->info($createdCount . ' ' . str('tenant')->plural($createdCount) . ' created.'); $this->info($maxPendingTenantCount . ' ' . str('tenant')->plural($maxPendingTenantCount) . ' ready to be used.'); - return 1; + return 0; } - /** - * Calculate the number of currently available pending tenants. - */ - private function getPendingTenantCount(): int + /** Calculate the number of currently available pending tenants. */ + protected function getPendingTenantCount(): int { return tenancy() ->query() diff --git a/src/Commands/Install.php b/src/Commands/Install.php index 77c96588..c7041a72 100644 --- a/src/Commands/Install.php +++ b/src/Commands/Install.php @@ -117,6 +117,7 @@ class Install extends Command $this->newLine(); } } else { + /** @var string $warning */ $this->components->warn($warning); } } diff --git a/src/Commands/MigrateFresh.php b/src/Commands/MigrateFresh.php index 45a93115..7df75fb0 100644 --- a/src/Commands/MigrateFresh.php +++ b/src/Commands/MigrateFresh.php @@ -4,12 +4,12 @@ declare(strict_types=1); namespace Stancl\Tenancy\Commands; -use Illuminate\Console\Command; +use Illuminate\Database\Console\Migrations\BaseCommand; use Stancl\Tenancy\Concerns\DealsWithMigrations; use Stancl\Tenancy\Concerns\HasTenantOptions; use Symfony\Component\Console\Input\InputOption; -class MigrateFresh extends Command +class MigrateFresh extends BaseCommand { use HasTenantOptions, DealsWithMigrations; diff --git a/src/Concerns/DealsWithMigrations.php b/src/Concerns/DealsWithMigrations.php index 3129c68d..3a757271 100644 --- a/src/Concerns/DealsWithMigrations.php +++ b/src/Concerns/DealsWithMigrations.php @@ -4,6 +4,9 @@ declare(strict_types=1); namespace Stancl\Tenancy\Concerns; +/** + * @mixin \Illuminate\Database\Console\Migrations\BaseCommand + */ trait DealsWithMigrations { protected function getMigrationPaths(): array diff --git a/src/Database/Concerns/HasPending.php b/src/Database/Concerns/HasPending.php index 3fa9399d..4d72486f 100644 --- a/src/Database/Concerns/HasPending.php +++ b/src/Database/Concerns/HasPending.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace Stancl\Tenancy\Database\Concerns; use Carbon\Carbon; +use Illuminate\Database\Eloquent\Model; use Stancl\Tenancy\Contracts\Tenant; use Stancl\Tenancy\Events\CreatingPendingTenant; use Stancl\Tenancy\Events\PendingTenantCreated; @@ -14,7 +15,7 @@ use Stancl\Tenancy\Events\PullingPendingTenant; // todo consider adding a method that sets pending_since to null — to flag tenants as not-pending /** - * @property Carbon $pending_since + * @property ?Carbon $pending_since * * @method static static|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder withPending(bool $withPending = true) * @method static static|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder onlyPending() @@ -22,38 +23,30 @@ use Stancl\Tenancy\Events\PullingPendingTenant; */ trait HasPending { - /** - * Boot the has pending trait for a model. - * - * @return void - */ - public static function bootHasPending() + /** Boot the trait. */ + public static function bootHasPending(): void { static::addGlobalScope(new PendingScope()); } - /** - * Initialize the has pending trait for an instance. - * - * @return void - */ - public function initializeHasPending() + /** Initialize the trait. */ + public function initializeHasPending(): void { $this->casts['pending_since'] = 'timestamp'; } - /** - * Determine if the model instance is in a pending state. - * - * @return bool - */ - public function pending() + /** Determine if the model instance is in a pending state. */ + public function pending(): bool { return ! is_null($this->pending_since); } - /** Create a pending tenant. */ - public static function createPending($attributes = []): Tenant + /** + * Create a pending tenant. + * + * @param array $attributes + */ + public static function createPending(array $attributes = []): Model&Tenant { $tenant = static::create($attributes); @@ -71,9 +64,12 @@ trait HasPending } /** Pull a pending tenant. */ - public static function pullPending(): Tenant + public static function pullPending(): Model&Tenant { - return static::pullPendingFromPool(true); + /** @var Model&Tenant $pendingTenant */ + $pendingTenant = static::pullPendingFromPool(true); + + return $pendingTenant; } /** Try to pull a tenant from the pool of pending tenants. */ @@ -88,6 +84,7 @@ trait HasPending } // A pending tenant is surely available at this point + /** @var Model&Tenant $tenant */ $tenant = static::onlyPending()->first(); event(new PullingPendingTenant($tenant)); diff --git a/src/Jobs/ClearPendingTenants.php b/src/Jobs/ClearPendingTenants.php index 7cd78495..773e3e93 100644 --- a/src/Jobs/ClearPendingTenants.php +++ b/src/Jobs/ClearPendingTenants.php @@ -16,12 +16,7 @@ class ClearPendingTenants implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; - /** - * Execute the job. - * - * @return void - */ - public function handle() + public function handle(): void { Artisan::call(ClearPendingTenantsCommand::class); } diff --git a/src/Jobs/CreatePendingTenants.php b/src/Jobs/CreatePendingTenants.php index 8f3da218..81199761 100644 --- a/src/Jobs/CreatePendingTenants.php +++ b/src/Jobs/CreatePendingTenants.php @@ -16,12 +16,7 @@ class CreatePendingTenants implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; - /** - * Execute the job. - * - * @return void - */ - public function handle() + public function handle(): void { Artisan::call(CreatePendingTenantsCommand::class); } diff --git a/src/Middleware/InitializeTenancyByPath.php b/src/Middleware/InitializeTenancyByPath.php index 3e484f87..e73605e3 100644 --- a/src/Middleware/InitializeTenancyByPath.php +++ b/src/Middleware/InitializeTenancyByPath.php @@ -45,8 +45,6 @@ class InitializeTenancyByPath extends IdentificationMiddleware } else { throw new RouteIsMissingTenantParameterException; } - - return $next($request); } protected function setDefaultTenantForRouteParametersWhenTenancyIsInitialized(): void diff --git a/src/Middleware/InitializeTenancyByRequestData.php b/src/Middleware/InitializeTenancyByRequestData.php index ca29f3d7..925907f0 100644 --- a/src/Middleware/InitializeTenancyByRequestData.php +++ b/src/Middleware/InitializeTenancyByRequestData.php @@ -34,18 +34,17 @@ class InitializeTenancyByRequestData extends IdentificationMiddleware protected function getPayload(Request $request): ?string { + $payload = null; + if (static::$header && $request->hasHeader(static::$header)) { - return $request->header(static::$header); + $payload = $request->header(static::$header); + } elseif (static::$queryParameter && $request->has(static::$queryParameter)) { + $payload = $request->get(static::$queryParameter); + } elseif (static::$cookie && $request->hasCookie(static::$cookie)) { + $payload = $request->cookie(static::$cookie); } - if (static::$queryParameter && $request->has(static::$queryParameter)) { - return $request->get(static::$queryParameter); - } - - if (static::$cookie && $request->hasCookie(static::$cookie)) { - return $request->cookie(static::$cookie); - } - - return null; + /** @var ?string $payload */ + return $payload; } } diff --git a/src/Tenancy.php b/src/Tenancy.php index e95e0059..5b30e3e0 100644 --- a/src/Tenancy.php +++ b/src/Tenancy.php @@ -42,8 +42,7 @@ class Tenancy } } - // todo1 for phpstan this should be $this->tenant?, but first I want to clean up the $initialized logic and explore removing the property - if ($this->initialized && $this->tenant->getTenantKey() === $tenant->getTenantKey()) { + if ($this->initialized && $this->tenant?->getTenantKey() === $tenant->getTenantKey()) { return; } @@ -52,6 +51,7 @@ class Tenancy $this->end(); } + /** @var Tenant&Model $tenant */ $this->tenant = $tenant; event(new Events\InitializingTenancy($this));