1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2025-12-12 08:24:04 +00:00

get down to 59 phpstan errors

This commit is contained in:
Samuel Štancl 2022-09-29 22:20:55 +02:00
parent 193e044777
commit a94227a19c
26 changed files with 130 additions and 130 deletions

View file

@ -13,14 +13,16 @@ parameters:
- Illuminate\Database\Eloquent\Model
ignoreErrors:
-
message: '#Cannot access offset (.*?) on Illuminate\\Contracts\\Foundation\\Application#'
paths:
- src/TenancyServiceProvider.php
- '#Cannot access offset (.*?) on Illuminate\\Contracts\\Foundation\\Application#'
- '#Cannot access offset (.*?) on Illuminate\\Contracts\\Config\\Repository#'
-
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:

View file

@ -23,14 +23,14 @@ class BatchTenancyBootstrapper implements TenancyBootstrapper
) {
}
public function bootstrap(Tenant $tenant)
public function bootstrap(Tenant $tenant): void
{
// Update batch repository connection to use the tenant connection
$this->previousConnection = $this->batchRepository->getConnection();
$this->batchRepository->setConnection($this->databaseManager->connection('tenant'));
}
public function revert()
public function revert(): void
{
if ($this->previousConnection) {
// Replace batch repository connection with the previously replaced one

View file

@ -13,18 +13,13 @@ use Stancl\Tenancy\Contracts\Tenant;
class CacheTenancyBootstrapper implements TenancyBootstrapper
{
/** @var CacheManager */
protected $originalCache;
protected ?CacheManager $originalCache = null;
/** @var Application */
protected $app;
public function __construct(
protected Application $app
) {}
public function __construct(Application $app)
{
$this->app = $app;
}
public function bootstrap(Tenant $tenant)
public function bootstrap(Tenant $tenant): void
{
$this->resetFacadeCache();
@ -34,7 +29,7 @@ class CacheTenancyBootstrapper implements TenancyBootstrapper
});
}
public function revert()
public function revert(): void
{
$this->resetFacadeCache();
@ -50,7 +45,7 @@ class CacheTenancyBootstrapper implements TenancyBootstrapper
* facade has been made prior to bootstrapping tenancy. The
* facade has its own cache, separate from the container.
*/
public function resetFacadeCache()
public function resetFacadeCache(): void
{
Cache::clearResolvedInstances();
}

View file

@ -8,7 +8,7 @@ use Stancl\Tenancy\Contracts\TenancyBootstrapper;
use Stancl\Tenancy\Contracts\Tenant;
use Stancl\Tenancy\Database\Contracts\TenantWithDatabase;
use Stancl\Tenancy\Database\DatabaseManager;
use Stancl\Tenancy\Exceptions\TenantDatabaseDoesNotExistException;
use Stancl\Tenancy\Database\Exceptions\TenantDatabaseDoesNotExistException;
class DatabaseTenancyBootstrapper implements TenancyBootstrapper
{
@ -20,7 +20,7 @@ class DatabaseTenancyBootstrapper implements TenancyBootstrapper
$this->database = $database;
}
public function bootstrap(Tenant $tenant)
public function bootstrap(Tenant $tenant): void
{
/** @var TenantWithDatabase $tenant */
@ -35,7 +35,7 @@ class DatabaseTenancyBootstrapper implements TenancyBootstrapper
$this->database->connectToTenant($tenant);
}
public function revert()
public function revert(): void
{
$this->database->reconnectToCentral();
}

View file

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace Stancl\Tenancy\Bootstrappers;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Routing\UrlGenerator;
use Illuminate\Support\Facades\Storage;
use Stancl\Tenancy\Contracts\TenancyBootstrapper;
use Stancl\Tenancy\Contracts\Tenant;
@ -27,13 +28,14 @@ class FilesystemTenancyBootstrapper implements TenancyBootstrapper
];
$this->app['url']->macro('setAssetRoot', function ($root) {
/** @var UrlGenerator $this */
$this->assetRoot = $root;
return $this;
});
}
public function bootstrap(Tenant $tenant)
public function bootstrap(Tenant $tenant): void
{
$suffix = $this->app['config']['tenancy.filesystem.suffix_base'] . $tenant->getTenantKey();
@ -91,7 +93,7 @@ class FilesystemTenancyBootstrapper implements TenancyBootstrapper
}
}
public function revert()
public function revert(): void
{
// storage_path()
$this->app->useStoragePath($this->originalPaths['storage']);

View file

@ -10,27 +10,22 @@ use Stancl\Tenancy\Contracts\Tenant;
class ScoutTenancyBootstrapper implements TenancyBootstrapper
{
/** @var Repository */
protected $config;
protected ?string $originalScoutPrefix = null;
/** @var string */
protected $originalScoutPrefix;
public function __construct(
protected Repository $config,
) {}
public function __construct(Repository $config)
public function bootstrap(Tenant $tenant): void
{
$this->config = $config;
}
public function bootstrap(Tenant $tenant)
{
if (! isset($this->originalScoutPrefix)) {
if ($this->originalScoutPrefix !== null) {
$this->originalScoutPrefix = $this->config->get('scout.prefix');
}
$this->config->set('scout.prefix', $this->getTenantPrefix($tenant));
}
public function revert()
public function revert(): void
{
$this->config->set('scout.prefix', $this->originalScoutPrefix);
}

View file

@ -39,7 +39,7 @@ class QueueTenancyBootstrapper implements TenancyBootstrapper
* However, we're registering a hook to initialize tenancy. Therefore,
* we need to register the hook at service provider execution time.
*/
public static function __constructStatic(Application $app)
public static function __constructStatic(Application $app): void
{
static::setUpJobListener($app->make(Dispatcher::class), $app->runningUnitTests());
}
@ -52,7 +52,7 @@ class QueueTenancyBootstrapper implements TenancyBootstrapper
$this->setUpPayloadGenerator();
}
protected static function setUpJobListener($dispatcher, $runningTests)
protected static function setUpJobListener(Dispatcher $dispatcher, bool $runningTests): void
{
$previousTenant = null;
@ -79,7 +79,7 @@ class QueueTenancyBootstrapper implements TenancyBootstrapper
$dispatcher->listen(JobFailed::class, $revertToPreviousState); // artisan('queue:work') which fails
}
protected static function initializeTenancyForQueue($tenantId)
protected static function initializeTenancyForQueue(string|int $tenantId): void
{
if (! $tenantId) {
// The job is not tenant-aware
@ -97,7 +97,9 @@ class QueueTenancyBootstrapper implements TenancyBootstrapper
tenancy()->end();
}
tenancy()->initialize(tenancy()->find($tenantId));
/** @var Tenant $tenant */
$tenant = tenancy()->find($tenantId);
tenancy()->initialize($tenant);
return;
}
@ -112,10 +114,13 @@ class QueueTenancyBootstrapper implements TenancyBootstrapper
// Tenancy was either not initialized, or initialized for a different tenant.
// Therefore, we initialize it for the correct tenant.
tenancy()->initialize(tenancy()->find($tenantId));
/** @var Tenant $tenant */
$tenant = tenancy()->find($tenantId);
tenancy()->initialize($tenant);
}
protected static function revertToPreviousState($event, &$previousTenant)
protected static function revertToPreviousState($event, ?Tenant &$previousTenant): void
{
$tenantId = $event->job->payload()['tenant_id'] ?? null;
@ -135,7 +140,7 @@ class QueueTenancyBootstrapper implements TenancyBootstrapper
}
}
protected function setUpPayloadGenerator()
protected function setUpPayloadGenerator(): void
{
$bootstrapper = &$this;
@ -146,17 +151,17 @@ class QueueTenancyBootstrapper implements TenancyBootstrapper
}
}
public function bootstrap(Tenant $tenant)
public function bootstrap(Tenant $tenant): void
{
//
}
public function revert()
public function revert(): void
{
//
}
public function getPayload(string $connection)
public function getPayload(string $connection): array
{
if (! tenancy()->initialized) {
return [];

View file

@ -22,18 +22,21 @@ class RedisTenancyBootstrapper implements TenancyBootstrapper
$this->config = $config;
}
public function bootstrap(Tenant $tenant)
public function bootstrap(Tenant $tenant): void
{
foreach ($this->prefixedConnections() as $connection) {
$prefix = $this->config['tenancy.redis.prefix_base'] . $tenant->getTenantKey();
$client = Redis::connection($connection)->client();
$this->originalPrefixes[$connection] = $client->getOption($client::OPT_PREFIX);
/** @var string $originalPrefix */
$originalPrefix = $client->getOption($client::OPT_PREFIX);
$this->originalPrefixes[$connection] = $originalPrefix;
$client->setOption($client::OPT_PREFIX, $prefix);
}
}
public function revert()
public function revert(): void
{
foreach ($this->prefixedConnections() as $connection) {
$client = Redis::connection($connection)->client();
@ -44,7 +47,8 @@ class RedisTenancyBootstrapper implements TenancyBootstrapper
$this->originalPrefixes = [];
}
protected function prefixedConnections()
/** @return string[] */
protected function prefixedConnections(): array
{
return $this->config['tenancy.redis.prefixed_connections'];
}

View file

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace Stancl\Tenancy\Commands;
use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Model;
use Stancl\Tenancy\Contracts\Tenant;
class TenantList extends Command
@ -16,15 +17,16 @@ class TenantList extends Command
public function handle(): void
{
$this->info('Listing all tenants.');
tenancy()
->query()
->cursor()
->each(function (Tenant $tenant) {
$tenants = tenancy()->query()->cursor();
foreach ($tenants as $tenant) {
/** @var Model&Tenant $tenant */
if ($tenant->domains) {
$this->line("[Tenant] {$tenant->getTenantKeyName()}: {$tenant->getTenantKey()} @ " . implode('; ', $tenant->domains->pluck('domain')->toArray() ?? []));
} else {
$this->line("[Tenant] {$tenant->getTenantKeyName()}: {$tenant->getTenantKey()}");
}
});
}
}
}

View file

@ -5,7 +5,7 @@ declare(strict_types=1);
namespace Stancl\Tenancy\Concerns;
use Illuminate\Support\Collection;
use Stancl\Tenancy\Database\Models\Tenant;
use Stancl\Tenancy\Contracts\Tenant;
trait DealsWithTenantSymlinks
{
@ -23,12 +23,14 @@ trait DealsWithTenantSymlinks
$diskUrls = config('tenancy.filesystem.url_override');
$disks = config('tenancy.filesystem.root_override');
$suffixBase = config('tenancy.filesystem.suffix_base');
$symlinks = collect();
$tenantKey = $tenant->getTenantKey();
/** @var Collection<array<string, string>> $symlinks */
$symlinks = collect([]);
foreach ($diskUrls as $disk => $publicPath) {
$storagePath = str_replace('%storage_path%', $suffixBase . $tenantKey, $disks[$disk]);
$publicPath = str_replace('%tenant_id%', $tenantKey, $publicPath);
$publicPath = str_replace('%tenant_id%', (string) $tenantKey, $publicPath);
tenancy()->central(function () use ($symlinks, $publicPath, $storagePath) {
$symlinks->push([public_path($publicPath) => storage_path($storagePath)]);

View file

@ -9,7 +9,7 @@ namespace Stancl\Tenancy\Contracts;
*/
interface TenancyBootstrapper
{
public function bootstrap(Tenant $tenant);
public function bootstrap(Tenant $tenant): void;
public function revert();
public function revert(): void;
}

View file

@ -10,7 +10,7 @@ use Throwable;
class TenantAssetsController extends Controller // todo rename this to TenantAssetController & update references in docs
{
public static string|array|Closure $tenancyMiddleware = Stancl\Tenancy\Middleware\InitializeTenancyByDomain::class;
public static string|array|Closure $tenancyMiddleware = \Stancl\Tenancy\Middleware\InitializeTenancyByDomain::class;
public function __construct()
{

View file

@ -10,6 +10,7 @@ use Stancl\Tenancy\Resolvers\Contracts\CachedTenantResolver;
trait InvalidatesResolverCache
{
/** @var array<class-string<CachedTenantResolver>> */
public static $resolvers = [
Resolvers\DomainTenantResolver::class,
Resolvers\PathTenantResolver::class,

View file

@ -13,7 +13,8 @@ use Stancl\Tenancy\Resolvers\Contracts\CachedTenantResolver;
*/
trait InvalidatesTenantsResolverCache
{
public static $resolvers = [
/** @var array<class-string<CachedTenantResolver>> */
public static array $resolvers = [ // todo single source of truth for this here and in InvalidatesResolverCache
Resolvers\DomainTenantResolver::class,
Resolvers\PathTenantResolver::class,
Resolvers\RequestDataTenantResolver::class,

View file

@ -26,20 +26,20 @@ class DatabaseConfig
public static function __constructStatic(): void
{
static::$usernameGenerator = static::$usernameGenerator ?? function (Tenant $tenant) {
static::$usernameGenerator = static::$usernameGenerator ?? function (Model&Tenant $tenant) {
return Str::random(16);
};
static::$passwordGenerator = static::$passwordGenerator ?? function (Tenant $tenant) {
static::$passwordGenerator = static::$passwordGenerator ?? function (Model&Tenant $tenant) {
return Hash::make(Str::random(32));
};
static::$databaseNameGenerator = static::$databaseNameGenerator ?? function (Tenant $tenant) {
static::$databaseNameGenerator = static::$databaseNameGenerator ?? function (Model&Tenant $tenant) {
return config('tenancy.database.prefix') . $tenant->getTenantKey() . config('tenancy.database.suffix');
};
}
public function __construct(Tenant $tenant)
public function __construct(Model&Tenant $tenant)
{
static::__constructStatic();
@ -61,7 +61,7 @@ class DatabaseConfig
static::$passwordGenerator = $passwordGenerator;
}
public function getName(): ?string
public function getName(): string
{
return $this->tenant->getInternal('db_name') ?? (static::$databaseNameGenerator)($this->tenant);
}

View file

@ -15,25 +15,13 @@ use Stancl\Tenancy\Database\Contracts\TenantWithDatabase;
*/
class DatabaseManager
{
/** @var Application */
protected $app;
public function __construct(
protected Application $app,
protected BaseDatabaseManager $database,
protected Repository $config,
) {}
/** @var BaseDatabaseManager */
protected $database;
/** @var Repository */
protected $config;
public function __construct(Application $app, BaseDatabaseManager $database, Repository $config)
{
$this->app = $app;
$this->database = $database;
$this->config = $config;
}
/**
* Connect to a tenant's database.
*/
/** Connect to a tenant's database. */
public function connectToTenant(TenantWithDatabase $tenant): void
{
$this->purgeTenantConnection();
@ -41,35 +29,27 @@ class DatabaseManager
$this->setDefaultConnection('tenant');
}
/**
* Reconnect to the default non-tenant connection.
*/
/** Reconnect to the default non-tenant connection. */
public function reconnectToCentral(): void
{
$this->purgeTenantConnection();
$this->setDefaultConnection($this->config->get('tenancy.database.central_connection'));
}
/**
* Change the default database connection config.
*/
/** Change the default database connection config. */
public function setDefaultConnection(string $connection): void
{
$this->config['database.default'] = $connection;
$this->database->setDefaultConnection($connection);
}
/**
* Create the tenant database connection.
*/
/** Create the tenant database connection. */
public function createTenantConnection(TenantWithDatabase $tenant): void
{
$this->config['database.connections.tenant'] = $tenant->database()->connection();
}
/**
* Purge the tenant database connection.
*/
/** Purge the tenant database connection. */
public function purgeTenantConnection(): void
{
if (array_key_exists('tenant', $this->database->getConnections())) {
@ -83,8 +63,8 @@ class DatabaseManager
* Check if a tenant can be created.
*
* @throws TenantCannotBeCreatedException
* @throws DatabaseManagerNotRegisteredException
* @throws TenantDatabaseAlreadyExistsException
* @throws Exceptions\DatabaseManagerNotRegisteredException
* @throws Exceptions\TenantDatabaseAlreadyExistsException
*/
public function ensureTenantCanBeCreated(TenantWithDatabase $tenant): void
{
@ -94,8 +74,13 @@ class DatabaseManager
throw new Exceptions\TenantDatabaseAlreadyExistsException($database);
}
if ($manager instanceof Contracts\ManagesDatabaseUsers && $manager->userExists($username = $tenant->database()->getUsername())) {
if ($manager instanceof Contracts\ManagesDatabaseUsers) {
/** @var string $username */
$username = $tenant->database()->getUsername();
if ($manager->userExists($username)) {
throw new Exceptions\TenantDatabaseUserAlreadyExistsException($username);
}
}
}
}

View file

@ -19,7 +19,7 @@ class ParentModelScope implements Scope
$builder->whereHas($builder->getModel()->getRelationshipToPrimaryModel());
}
public function extend(Builder $builder)
public function extend(Builder $builder): void
{
$builder->macro('withoutParentModel', function (Builder $builder) {
return $builder->withoutGlobalScope($this);

View file

@ -12,7 +12,8 @@ class PermissionControlledMySQLDatabaseManager extends MySQLDatabaseManager impl
{
use CreatesDatabaseUsers;
public static $grants = [
/** @var string[] */
public static array $grants = [
'ALTER', 'ALTER ROUTINE', 'CREATE', 'CREATE ROUTINE', 'CREATE TEMPORARY TABLES', 'CREATE VIEW',
'DELETE', 'DROP', 'EVENT', 'EXECUTE', 'INDEX', 'INSERT', 'LOCK TABLES', 'REFERENCES', 'SELECT',
'SHOW VIEW', 'TRIGGER', 'UPDATE',

View file

@ -20,7 +20,7 @@ class TenantScope implements Scope
$builder->where($model->qualifyColumn(BelongsToTenant::$tenantIdColumn), tenant()->getTenantKey());
}
public function extend(Builder $builder)
public function extend(Builder $builder): void
{
$builder->macro('withoutTenancy', function (Builder $builder) {
return $builder->withoutGlobalScope($this);

View file

@ -16,19 +16,16 @@ use Stancl\Tenancy\Tenancy;
class TenantConfig implements Feature
{
/** @var Repository */
protected $config;
public array $originalConfig = [];
public static $storageToConfigMap = [
/** @var array<string, string> */
public static array $storageToConfigMap = [
// 'paypal_api_key' => 'services.paypal.api_key',
];
public function __construct(Repository $config)
{
$this->config = $config;
}
public function __construct(
protected Repository $config,
) {}
public function bootstrap(Tenancy $tenancy): void
{

View file

@ -16,6 +16,7 @@ class UniversalRoutes implements Feature
public static string $middlewareGroup = 'universal';
// todo docblock
/** @var array<class-string<\Stancl\Tenancy\Middleware\IdentificationMiddleware>> */
public static array $identificationMiddlewares = [
Middleware\InitializeTenancyByDomain::class,
Middleware\InitializeTenancyBySubdomain::class,
@ -42,7 +43,10 @@ class UniversalRoutes implements Feature
public static function routeHasMiddleware(Route $route, string $middleware): bool
{
if (in_array($middleware, $route->middleware(), true)) {
/** @var array $routeMiddleware */
$routeMiddleware = $route->middleware();
if (in_array($middleware, $routeMiddleware, true)) {
return true;
}

View file

@ -4,21 +4,21 @@ declare(strict_types=1);
namespace Stancl\Tenancy\Listeners;
use Stancl\Tenancy\Database\Contracts\TenantWithDatabase;
use Stancl\Tenancy\Database\DatabaseManager;
use Stancl\Tenancy\Events\Contracts\TenantEvent;
class CreateTenantConnection
{
/** @var DatabaseManager */
protected $database;
public function __construct(DatabaseManager $database)
{
$this->database = $database;
}
public function __construct(
protected DatabaseManager $database,
) {}
public function handle(TenantEvent $event): void
{
$this->database->createTenantConnection($event->tenant);
/** @var TenantWithDatabase */
$tenant = $event->tenant;
$this->database->createTenantConnection($tenant);
}
}

View file

@ -13,7 +13,7 @@ abstract class QueueableListener implements ShouldQueue
{
public static bool $shouldQueue = false;
public function shouldQueue($event): bool
public function shouldQueue(object $event): bool
{
if (static::$shouldQueue) {
return true;

View file

@ -9,6 +9,7 @@ use Illuminate\Http\Request;
use Illuminate\Routing\Route;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\URL;
use Stancl\Tenancy\Contracts\Tenant;
use Stancl\Tenancy\Events\InitializingTenancy;
use Stancl\Tenancy\Exceptions\RouteIsMissingTenantParameterException;
use Stancl\Tenancy\Resolvers\PathTenantResolver;
@ -36,7 +37,10 @@ class InitializeTenancyByPath extends IdentificationMiddleware
if ($route->parameterNames()[0] === PathTenantResolver::$tenantParameterName) {
// Set tenant as a default parameter for the URLs in the current request
Event::listen(InitializingTenancy::class, function (InitializingTenancy $event) {
URL::defaults([PathTenantResolver::$tenantParameterName => $event->tenancy->tenant->getTenantKey()]);
/** @var Tenant $tenant */
$tenant = $event->tenancy->tenant;
URL::defaults([PathTenantResolver::$tenantParameterName => $tenant->getTenantKey()]);
});
return $this->initializeTenancy(

View file

@ -132,7 +132,7 @@ class Tenancy
* Run a callback for multiple tenants.
* More performant than running $tenant->run() one by one.
*
* @param Tenant[]|\Traversable|string[]|null $tenants
* @param array<Tenant>|array<string>|\Traversable|null $tenants
*/
public function runForMultiple($tenants, Closure $callback): void
{

View file

@ -107,12 +107,12 @@ function contextIsSwitchedWhenTenancyInitialized()
class MyBootstrapper implements TenancyBootstrapper
{
public function bootstrap(\Stancl\Tenancy\Contracts\Tenant $tenant)
public function bootstrap(\Stancl\Tenancy\Contracts\Tenant $tenant): void
{
app()->instance('tenancy_initialized_for_tenant', $tenant->getTenantKey());
}
public function revert()
public function revert(): void
{
app()->instance('tenancy_ended', true);
}