Skip to content

Commit ea921ad

Browse files
authored
Merge pull request #8623 from ProcessMaker/task/FOUR-27735-b
Refactor SwitchTenant task
2 parents 965d673 + a64fbed commit ea921ad

10 files changed

Lines changed: 218 additions & 340 deletions

File tree

ProcessMaker/Application.php

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
use Illuminate\Support\Facades\Config;
1616
use ProcessMaker\Console\Kernel;
1717
use ProcessMaker\Multitenancy\Tenant;
18-
use ProcessMaker\Multitenancy\TenantBootstrapper;
1918

2019
/**
2120
* Class Application.
@@ -103,15 +102,4 @@ public function registerConfiguredProviders()
103102

104103
parent::registerConfiguredProviders();
105104
}
106-
107-
public function bootstrapWith(array $bootstrappers)
108-
{
109-
// Insert TenantBootstrapper after LoadEnvironmentVariables
110-
if ($bootstrappers[0] !== LoadEnvironmentVariables::class) {
111-
throw new \Exception('LoadEnvironmentVariables is not the first bootstrapper. Did a laravel upgrade change this?');
112-
}
113-
array_splice($bootstrappers, 1, 0, [TenantBootstrapper::class]);
114-
115-
return parent::bootstrapWith($bootstrappers);
116-
}
117105
}

ProcessMaker/Console/Commands/HorizonListen.php

Lines changed: 0 additions & 51 deletions
This file was deleted.

ProcessMaker/Console/Commands/TenantsVerify.php

Lines changed: 94 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class TenantsVerify extends Command
1919
*
2020
* @var string
2121
*/
22-
protected $signature = 'tenants:verify';
22+
protected $signature = 'tenants:verify {--json : Output the results as JSON}';
2323

2424
/**
2525
* The console command description.
@@ -33,20 +33,29 @@ class TenantsVerify extends Command
3333
*
3434
* @return int
3535
*/
36+
private $jsonData = [];
37+
3638
public function handle()
3739
{
40+
if (!config('app.multitenancy')) {
41+
$this->info('Multitenancy is disabled');
42+
43+
return;
44+
}
45+
46+
$errors = [];
3847
$currentTenant = null;
3948
if (app()->has('currentTenant')) {
4049
$currentTenant = app('currentTenant');
4150
}
4251

43-
if (config('app.multitenancy') && !$currentTenant) {
52+
if (!$currentTenant) {
4453
$this->error('Multitenancy enabled but no current tenant found.');
4554

4655
return;
4756
}
4857

49-
$this->info('Current Tenant ID: ' . ($currentTenant?->id ?? 'NONE'));
58+
\Log::warning('TenantsVerify: Current Tenant ID: ' . ($currentTenant?->id ?? 'NONE'));
5059

5160
$paths = [
5261
['Storage Path', storage_path()],
@@ -55,32 +64,44 @@ public function handle()
5564
];
5665

5766
// Display paths in a nice table
58-
$this->table(['Path', 'Value'], $paths);
67+
$this->infoTable(['Path', 'Value'], $paths);
5968

6069
$configs = [
61-
'app.key',
62-
'app.url',
63-
'app.instance',
64-
'cache.prefix',
65-
'database.redis.options.prefix',
66-
'cache.stores.cache_settings.prefix',
67-
'script-runner-microservice.callback',
68-
'database.connections.processmaker.database',
69-
'logging.channels.daily.path',
70-
'filesystems.disks.public.root',
71-
'filesystems.disks.local.root',
72-
'filesystems.disks.lang.root',
70+
'app.key' => null,
71+
'app.url' => null,
72+
'app.instance' => null,
73+
'cache.prefix' => 'tenant_{tenant_id}:',
74+
'database.redis.options.prefix' => null,
75+
'cache.stores.cache_settings.prefix' => 'tenant_{tenant_id}:settings',
76+
'script-runner-microservice.callback' => null,
77+
'database.connections.processmaker.database' => null,
78+
'logging.channels.daily.path' => base_path() . '/storage/tenant_{tenant_id}/logs/processmaker.log',
79+
'filesystems.disks.public.root' => base_path() . '/storage/tenant_{tenant_id}/app/public',
80+
'filesystems.disks.local.root' => base_path() . '/storage/tenant_{tenant_id}/app',
81+
'filesystems.disks.lang.root' => base_path() . '/resources/lang/tenant_{tenant_id}',
7382
];
7483

75-
$configs = array_map(function ($config) {
84+
$configs = array_map(function ($config) use ($configs, $currentTenant, &$errors) {
85+
$ok = '';
86+
if ($configs[$config] !== null) {
87+
$expected = str_replace('{tenant_id}', $currentTenant->id, $configs[$config]);
88+
if (config($config) === $expected) {
89+
$ok = '';
90+
} else {
91+
$ok = '';
92+
$errors[] = 'Expected: ' . $expected . ' != Actual: ' . config($config);
93+
}
94+
}
95+
7696
return [
7797
$config,
7898
config($config),
99+
$ok,
79100
];
80-
}, $configs);
101+
}, array_keys($configs));
81102

82103
// Display configs in a nice table
83-
$this->table(['Config', 'Value'], $configs);
104+
$this->infoTable(['Config', 'Value', 'OK'], $configs);
84105

85106
$env = EnvironmentVariable::first();
86107
if (!$env) {
@@ -102,10 +123,62 @@ public function handle()
102123
['Tenant Config Is Cached', File::exists(app()->getCachedConfigPath()) ? 'Yes' : 'No'],
103124
['First username (database check)', User::first()?->username ?? 'No users found'],
104125
['Decrypted check', substr($decrypted, 0, 50)],
105-
['Original App URL (landlord)', $currentTenant?->getOriginalValue('APP_URL') ?? config('app.url')],
126+
// ['Original App URL (landlord)', $currentTenant?->getOriginalValue('APP_URL') ?? config('app.url')],
127+
['config("app.url")', config('app.url')],
128+
['getenv("APP_URL")', getenv('APP_URL')],
129+
['env("APP_URL")', env('APP_URL')],
130+
['$_SERVER["APP_URL"]', $_SERVER['APP_URL'] ?? 'NOT SET'],
131+
['$_ENV["APP_URL"]', $_ENV['APP_URL'] ?? 'NOT SET'],
132+
['Current PID', getmypid()],
106133
];
107134

108135
// Display other in a nice table
109-
$this->table(['Other', 'Value'], $other);
136+
$this->infoTable(['Other', 'Value'], $other);
137+
138+
$checkUrls = [
139+
'config("app.url")' => config('app.url'),
140+
'getenv("APP_URL")' => getenv('APP_URL'),
141+
'env("APP_URL")' => env('APP_URL'),
142+
'$_SERVER["APP_URL"]' => $_SERVER['APP_URL'] ?? 'NOT SET',
143+
'$_ENV["APP_URL"]' => $_ENV['APP_URL'] ?? 'NOT SET',
144+
];
145+
146+
foreach ($checkUrls as $key => $value) {
147+
if ($value !== $currentTenant?->config['app.url']) {
148+
$errors[] = 'Expected: ' . $key . ' to be ' . $currentTenant?->config['app.url'] . ' but got ' . $value;
149+
}
150+
}
151+
152+
$this->finish($errors);
153+
}
154+
155+
private function finish($errors)
156+
{
157+
if (count($errors) > 0) {
158+
$this->error('Errors found');
159+
} else {
160+
$this->info('No errors found');
161+
}
162+
163+
if ($this->option('json')) {
164+
$this->jsonData['Errors'] = $errors;
165+
$this->line(json_encode($this->jsonData, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
166+
}
167+
}
168+
169+
private function infoTable($headers, $rows)
170+
{
171+
if ($this->option('json')) {
172+
$section = [];
173+
foreach ($rows as $row) {
174+
$section[$row[0]] = $row[1];
175+
}
176+
$this->jsonData[$headers[0]] = $section;
177+
} else {
178+
foreach ($rows as $row) {
179+
\Log::warning($row[0] . ': ' . $row[1]);
180+
}
181+
$this->table($headers, $rows);
182+
}
110183
}
111184
}

ProcessMaker/Multitenancy/MakeQueueTenantAwareAction.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,14 @@
77
class MakeQueueTenantAwareAction extends BaseMakeQueueTenantAwareAction
88
{
99
/**
10-
* We're handling tenant aware queues manually, however, we still need to implement this because for some
11-
* reason the Spatie package calls it in Multitenancy::start(), weather it's a configured action or not.
10+
* Non-multitenant environments shouldn't throw an exception if the tenant is not found.
1211
*/
1312
public function execute() : void
1413
{
15-
// Do nothing
14+
if (!config('app.multitenancy')) {
15+
return;
16+
}
17+
18+
parent::execute();
1619
}
1720
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace ProcessMaker\Multitenancy;
4+
5+
use Spatie\Multitenancy\Contracts\IsTenant;
6+
use Spatie\Multitenancy\Tasks\PrefixCacheTask as SpatiePrefixCacheTask;
7+
8+
class PrefixCacheTask extends SpatiePrefixCacheTask
9+
{
10+
private $originalSettingsPrefix;
11+
12+
public function makeCurrent(IsTenant $tenant): void
13+
{
14+
$cachePrefix = 'tenant_' . $tenant->getKey() . ':';
15+
$this->setCachePrefix($cachePrefix);
16+
17+
$this->originalSettingsPrefix = config('cache.stores.cache_settings.prefix');
18+
$tenantSettingsPrefix = 'tenant_' . $tenant->getKey() . ':' . $this->originalSettingsPrefix;
19+
config()->set('cache.stores.cache_settings.prefix', $tenantSettingsPrefix);
20+
$this->storeName = 'cache_settings';
21+
$this->setCachePrefix($cachePrefix);
22+
}
23+
24+
public function forgetCurrent(): void
25+
{
26+
$this->setCachePrefix($this->originalPrefix);
27+
28+
config()->set('cache.stores.cache_settings.prefix', $this->originalSettingsPrefix);
29+
$this->storeName = 'cache_settings';
30+
$this->setCachePrefix($this->originalPrefix);
31+
}
32+
}

0 commit comments

Comments
 (0)