1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2025-12-12 11:34:03 +00:00

get down to 21 phpstan errors

This commit is contained in:
Samuel Štancl 2022-09-29 23:39:35 +02:00
parent a94227a19c
commit f98a901aeb
16 changed files with 85 additions and 26 deletions

View file

@ -31,6 +31,18 @@ parameters:
message: '#PHPDoc tag \@param has invalid value \(dynamic#'
paths:
- src/helpers.php
-
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:
- src/Database/DatabaseConfig.php
checkMissingIterableValueType: false
treatPhpDocTypesAsCertain: false

View file

@ -120,7 +120,7 @@ class QueueTenancyBootstrapper implements TenancyBootstrapper
tenancy()->initialize($tenant);
}
protected static function revertToPreviousState($event, ?Tenant &$previousTenant): void
protected static function revertToPreviousState(JobProcessed|JobFailed $event, ?Tenant &$previousTenant): void
{
$tenantId = $event->job->payload()['tenant_id'] ?? null;

View file

@ -20,7 +20,7 @@ class Down extends DownCommand
protected $description = 'Put tenants into maintenance mode.';
public function handle(): void
public function handle(): int
{
// The base down command is heavily used. Instead of saving the data inside a file,
// the data is stored the tenant database, which means some Laravel features
@ -29,16 +29,18 @@ class Down extends DownCommand
$payload = $this->getDownDatabasePayload();
// This runs for all tenants if no --tenants are specified
tenancy()->runForMultiple($this->option('tenants'), function ($tenant) use ($payload) {
tenancy()->runForMultiple($this->getTenants(), function ($tenant) use ($payload) {
$this->line("Tenant: {$tenant['id']}");
$tenant->putDownForMaintenance($payload);
});
$this->comment('Tenants are now in maintenance mode.');
return 0;
}
/** Get the payload to be placed in the "down" file. */
protected function getDownDatabasePayload()
protected function getDownDatabasePayload(): array
{
return [
'except' => $this->excludedPaths(),
@ -46,7 +48,7 @@ class Down extends DownCommand
'retry' => $this->getRetryTime(),
'refresh' => $this->option('refresh'),
'secret' => $this->option('secret'),
'status' => (int) $this->option('status', 503),
'status' => (int) ($this->option('status') ?? 503),
];
}
}

View file

@ -49,8 +49,8 @@ class Link extends Command
{
CreateStorageSymlinksAction::handle(
$tenants,
$this->option('relative') ?? false,
$this->option('force') ?? false,
(bool) ($this->option('relative') ?? false),
(bool) ($this->option('force') ?? false),
);
$this->info('The links have been created.');

View file

@ -36,7 +36,7 @@ class Rollback extends RollbackCommand
return 1;
}
tenancy()->runForMultiple($this->option('tenants'), function ($tenant) {
tenancy()->runForMultiple($this->getTenants(), function ($tenant) {
$this->line("Tenant: {$tenant->getTenantKey()}");
event(new RollingBackDatabase($tenant));

View file

@ -6,11 +6,14 @@ namespace Stancl\Tenancy\Commands;
use Illuminate\Console\Command;
use Illuminate\Contracts\Console\Kernel;
use Stancl\Tenancy\Concerns\HasATenantsOption;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Output\ConsoleOutput;
class Run extends Command
{
use HasATenantsOption;
protected $description = 'Run a command for tenant(s)';
protected $signature = 'tenants:run {commandname : The artisan command.}
@ -19,7 +22,8 @@ class Run extends Command
public function handle(): void
{
$argvInput = $this->argvInput();
tenancy()->runForMultiple($this->option('tenants'), function ($tenant) use ($argvInput) {
tenancy()->runForMultiple($this->getTenants(), function ($tenant) use ($argvInput) {
$this->line("Tenant: {$tenant->getTenantKey()}");
$this->getLaravel()
@ -30,12 +34,15 @@ class Run extends Command
protected function argvInput(): ArgvInput
{
/** @var string $commandname */
$commandname = $this->argument('commandname');
// Convert string command to array
$subCommand = explode(' ', $this->argument('commandname'));
$subcommand = explode(' ', $commandname);
// Add "artisan" as first parameter because ArgvInput expects "artisan" as first parameter and later removes it
array_unshift($subCommand, 'artisan');
array_unshift($subcommand, 'artisan');
return new ArgvInput($subCommand);
return new ArgvInput($subcommand);
}
}

View file

@ -35,7 +35,7 @@ class Seed extends SeedCommand
return 1;
}
tenancy()->runForMultiple($this->option('tenants'), function ($tenant) {
tenancy()->runForMultiple($this->getTenants(), function ($tenant) {
$this->line("Tenant: {$tenant->getTenantKey()}");
event(new SeedingDatabase($tenant));

View file

@ -4,6 +4,8 @@ declare(strict_types=1);
namespace Stancl\Tenancy\Contracts;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
/**
* @property-read Tenant $tenant
*
@ -15,5 +17,5 @@ namespace Stancl\Tenancy\Contracts;
*/
interface Domain
{
public function tenant();
public function tenant(): BelongsTo;
}

View file

@ -8,6 +8,7 @@ abstract class TenantCannotBeCreatedException extends \Exception
{
abstract public function reason(): string;
/** @var string */
protected $message;
public function __construct()

View file

@ -6,6 +6,7 @@ namespace Stancl\Tenancy\Controllers;
use Closure;
use Illuminate\Routing\Controller;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Throwable;
class TenantAssetsController extends Controller // todo rename this to TenantAssetController & update references in docs
@ -17,7 +18,10 @@ class TenantAssetsController extends Controller // todo rename this to TenantAss
$this->middleware(static::$tenancyMiddleware);
}
public function asset(string $path = null)
/**
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
*/
public function asset(string $path = null): BinaryFileResponse
{
abort_if($path === null, 404);

View file

@ -9,5 +9,15 @@ use Stancl\Tenancy\Database\DatabaseConfig;
interface TenantWithDatabase extends Tenant
{
/** Get the tenant's database config. */
public function database(): DatabaseConfig;
/** Get the internal prefix. */
public static function internalPrefix(): string;
/** Get an internal key. */
public function getInternal(string $key): mixed;
/** Set internal key. */
public function setInternal(string $key, mixed $value): static;
}

View file

@ -81,7 +81,7 @@ class DatabaseConfig
*/
public function makeCredentials(): void
{
$this->tenant->setInternal('db_name', $this->getName() ?? (static::$databaseNameGenerator)($this->tenant));
$this->tenant->setInternal('db_name', $this->getName());
if ($this->manager() instanceof Contracts\ManagesDatabaseUsers) {
$this->tenant->setInternal('db_username', $this->getUsername() ?? (static::$usernameGenerator)($this->tenant));

View file

@ -18,7 +18,7 @@ class TenantConfig implements Feature
{
public array $originalConfig = [];
/** @var array<string, string> */
/** @var array<string, string|array> */
public static array $storageToConfigMap = [
// 'paypal_api_key' => 'services.paypal.api_key',
];
@ -30,7 +30,10 @@ class TenantConfig implements Feature
public function bootstrap(Tenancy $tenancy): void
{
Event::listen(TenancyBootstrapped::class, function (TenancyBootstrapped $event) {
$this->setTenantConfig($event->tenancy->tenant);
/** @var Tenant $tenant */
$tenant = $event->tenancy->tenant;
$this->setTenantConfig($tenant);
});
Event::listen(RevertedToCentralContext::class, function () {
@ -40,8 +43,8 @@ class TenantConfig implements Feature
public function setTenantConfig(Tenant $tenant): void
{
/** @var Tenant|Model $tenant */
foreach (static::$storageToConfigMap as $storageKey => $configKey) {
/** @var Tenant&Model $tenant */
$override = Arr::get($tenant, $storageKey);
if (! is_null($override)) {

View file

@ -4,6 +4,7 @@ declare(strict_types=1);
namespace Stancl\Tenancy\Listeners;
use Stancl\Tenancy\Contracts\Tenant;
use Stancl\Tenancy\Events\BootstrappingTenancy;
use Stancl\Tenancy\Events\TenancyBootstrapped;
use Stancl\Tenancy\Events\TenancyInitialized;
@ -15,7 +16,10 @@ class BootstrapTenancy
event(new BootstrappingTenancy($event->tenancy));
foreach ($event->tenancy->getBootstrappers() as $bootstrapper) {
$bootstrapper->bootstrap($event->tenancy->tenant);
/** @var Tenant $tenant */
$tenant = $event->tenancy->tenant;
$bootstrapper->bootstrap($tenant);
}
event(new TenancyBootstrapped($event->tenancy));

View file

@ -99,19 +99,30 @@ class Tenancy
{
$class = config('tenancy.tenant_model');
return new $class;
/** @var Tenant&Model $model */
$model = new $class;
return $model;
}
/**
* Try to find a tenant using an ID.
*
* @return (Tenant&Model)|null
*/
public static function find(int|string $id): Tenant|null
{
return static::model()->where(static::model()->getTenantKeyName(), $id)->first();
/** @var (Tenant&Model)|null */
$tenant = static::model()->where(static::model()->getTenantKeyName(), $id)->first();
return $tenant;
}
/**
* Run a callback in the central context.
* Atomic, safely reverts to previous context.
*/
public function central(Closure $callback)
public function central(Closure $callback): mixed
{
$previousTenant = $this->tenant;
@ -132,7 +143,7 @@ class Tenancy
* Run a callback for multiple tenants.
* More performant than running $tenant->run() one by one.
*
* @param array<Tenant>|array<string>|\Traversable|null $tenants
* @param array<Tenant>|array<string|int>|\Traversable|string|int|null $tenants
*/
public function runForMultiple($tenants, Closure $callback): void
{
@ -155,6 +166,7 @@ class Tenancy
$tenant = $this->find($tenant);
}
/** @var Tenant $tenant */
$this->initialize($tenant);
$callback($tenant);
}

View file

@ -3,6 +3,7 @@
declare(strict_types=1);
use Illuminate\Database\DatabaseManager;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Event;
@ -201,8 +202,9 @@ test('run command with array of tenants works', function () {
Artisan::call('tenants:migrate-fresh');
pest()->artisan("tenants:run --tenants=$tenantId1 --tenants=$tenantId2 'foo foo --b=bar --c=xyz'")
->expectsOutput('Tenant: ' . $tenantId1)
->expectsOutput('Tenant: ' . $tenantId2);
->expectsOutputToContain('Tenant: ' . $tenantId1)
->expectsOutputToContain('Tenant: ' . $tenantId2)
->assertExitCode(0);
});
test('link command works', function() {