Skip to content

Commit a816ed3

Browse files
authored
Merge pull request #150 from fleetbase/dev-v1.6.11
v1.6.11 ~ optimized environment mapper settings merge
2 parents a551ab8 + eb449b7 commit a816ed3

File tree

6 files changed

+154
-18
lines changed

6 files changed

+154
-18
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "fleetbase/core-api",
3-
"version": "1.6.10",
3+
"version": "1.6.11",
44
"description": "Core Framework and Resources for Fleetbase API",
55
"keywords": [
66
"fleetbase",

src/Http/Controllers/Internal/v1/SettingController.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
use Illuminate\Http\Request;
1212
use Illuminate\Notifications\AnonymousNotifiable;
1313
use Illuminate\Support\Arr;
14+
use Illuminate\Support\Facades\Artisan;
15+
use Illuminate\Support\Facades\Log;
1416
use Illuminate\Support\Facades\Mail;
1517
use Illuminate\Support\Facades\Queue;
1618
use Illuminate\Support\Facades\Storage;
@@ -95,6 +97,9 @@ public function saveFilesystemConfig(AdminRequest $request)
9597
Setting::configureSystem('filesystem.gcs', $gcs);
9698
Setting::configureSystem('filesystem.s3', array_merge(config('filesystems.disks.s3', []), $s3));
9799

100+
// Refresh config
101+
$this->refreshConfigCache();
102+
98103
return response()->json(['status' => 'OK']);
99104
}
100105

@@ -273,6 +278,9 @@ public function saveMailConfig(AdminRequest $request)
273278
Setting::configureSystem('services.sendgrid', $sendgrid);
274279
Setting::configureSystem('services.resend', $resend);
275280

281+
// Refresh config
282+
$this->refreshConfigCache();
283+
276284
return response()->json(['status' => 'OK']);
277285
}
278286

@@ -379,6 +387,9 @@ public function saveQueueConfig(AdminRequest $request)
379387
Setting::configureSystem('queue.sqs', array_merge(config('queue.connections.sqs'), $sqs));
380388
Setting::configureSystem('queue.beanstalkd', array_merge(config('queue.connections.beanstalkd'), $beanstalkd));
381389

390+
// Refresh config
391+
$this->refreshConfigCache();
392+
382393
return response()->json(['status' => 'OK']);
383394
}
384395

@@ -471,6 +482,9 @@ public function saveServicesConfig(AdminRequest $request)
471482
Setting::configureSystem('services.twilio', array_merge(config('services.twilio', []), $twilio));
472483
Setting::configureSystem('services.sentry', array_merge(config('sentry', []), $sentry));
473484

485+
// Refresh config
486+
$this->refreshConfigCache();
487+
474488
return response()->json(['status' => 'OK']);
475489
}
476490

@@ -520,6 +534,9 @@ public function saveNotificationChannelsConfig(AdminRequest $request)
520534
Setting::configureSystem('broadcasting.apn', array_merge(config('broadcasting.connections.apn', []), $apn));
521535
Setting::configureSystem('firebase.app', array_merge(config('firebase.projects.app', []), $firebase));
522536

537+
// Refresh config
538+
$this->refreshConfigCache();
539+
523540
return response()->json(['status' => 'OK']);
524541
}
525542

@@ -836,4 +853,17 @@ public function testSocketcluster(AdminRequest $request)
836853
]
837854
);
838855
}
856+
857+
/**
858+
* Refresh config cache.
859+
*/
860+
private function refreshConfigCache()
861+
{
862+
try {
863+
Artisan::call('config:clear');
864+
Artisan::call('config:cache');
865+
} catch (\Exception $e) {
866+
Log::error('Failed to refresh config cache.', ['error' => $e->getMessage()]);
867+
}
868+
}
839869
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace Fleetbase\Http\Middleware;
4+
5+
use Fleetbase\Support\EnvironmentMapper;
6+
use Illuminate\Http\Request;
7+
8+
class MergeConfigFromSettings
9+
{
10+
public function handle(Request $request, \Closure $next)
11+
{
12+
EnvironmentMapper::mergeConfigFromSettingsOptimized();
13+
14+
return $next($request);
15+
}
16+
}

src/Providers/CoreServiceProvider.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class CoreServiceProvider extends ServiceProvider
3939
public $globalMiddlewares = [
4040
\Fleetbase\Http\Middleware\RequestTimer::class,
4141
\Fleetbase\Http\Middleware\ResetJsonResourceWrap::class,
42+
\Fleetbase\Http\Middleware\MergeConfigFromSettings::class,
4243
];
4344

4445
/**
@@ -181,7 +182,7 @@ public function registerCustomBladeComponents()
181182
*/
182183
public function mergeConfigFromSettings()
183184
{
184-
EnvironmentMapper::mergeConfigFromSettings();
185+
EnvironmentMapper::mergeConfigFromSettingsOptimized();
185186
}
186187

187188
/**

src/Support/EnvironmentMapper.php

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Fleetbase\Models\Setting;
66
use Illuminate\Support\Arr;
7+
use Illuminate\Support\Str;
78

89
/**
910
* The EnvironmentMapper class is responsible for mapping system settings stored in the database
@@ -216,4 +217,107 @@ protected static function setDefaultMailFrom(): void
216217
config()->set('mail.from.address', Utils::getDefaultMailFromAddress());
217218
}
218219
}
220+
221+
/**
222+
* Optimized merge of database settings into application config.
223+
*
224+
* Batch-fetches all relevant setting records in one query, builds
225+
* a combined config payload, and applies it with a single config() call.
226+
*/
227+
public static function mergeConfigFromSettingsOptimized(): void
228+
{
229+
if (Setting::doesntHaveConnection()) {
230+
return;
231+
}
232+
233+
// Build DB keys for env vars (prefixed with 'system.')
234+
$envDbKeys = array_map(fn ($path) => Str::startsWith($path, 'system.')
235+
? $path
236+
: 'system.' . $path, array_values(static::$environmentVariables)
237+
);
238+
239+
// Build DB keys for settings (use first two segments for nested keys)
240+
$settingDbKeys = array_map(function ($map) {
241+
$key = $map['settingsKey'];
242+
$segments = explode('.', $key);
243+
if (count($segments) >= 3) {
244+
return 'system.' . $segments[0] . '.' . $segments[1];
245+
}
246+
247+
return Str::startsWith($key, 'system.')
248+
? $key
249+
: 'system.' . $key;
250+
}, static::$settings);
251+
252+
// Unique list of keys to fetch
253+
$fetchKeys = array_unique(array_merge($envDbKeys, $settingDbKeys));
254+
255+
// Fetch all values in one query
256+
$dbSettings = Setting::whereIn('key', $fetchKeys)
257+
->pluck('value', 'key')
258+
->all();
259+
260+
// Apply environment variables
261+
static::setEnvironmentVariablesOptimized($dbSettings);
262+
263+
// Build new config payload
264+
$newConfig = [];
265+
foreach (static::$settings as $map) {
266+
$settingsKey = $map['settingsKey'];
267+
$configKey = $map['configKey'];
268+
$segments = explode('.', $settingsKey);
269+
270+
// Determine the DB key we fetched
271+
$dbKey = count($segments) >= 3
272+
? 'system.' . $segments[0] . '.' . $segments[1]
273+
: 'system.' . $settingsKey;
274+
275+
if (!isset($dbSettings[$dbKey])) {
276+
continue;
277+
}
278+
279+
$rawValue = $dbSettings[$dbKey];
280+
281+
// Extract nested subkey if needed
282+
$value = count($segments) >= 3
283+
? data_get($rawValue, implode('.', array_slice($segments, 2)))
284+
: $rawValue;
285+
286+
// Merge arrays rather than overwrite
287+
if (is_array($value) && is_array(config($configKey))) {
288+
$value = array_merge(config($configKey), array_filter($value));
289+
}
290+
291+
$newConfig[$configKey] = $value;
292+
}
293+
294+
// Apply all config changes at once
295+
if (!empty($newConfig)) {
296+
config($newConfig);
297+
}
298+
299+
// Ensure default mail 'from' fallback
300+
static::setDefaultMailFrom();
301+
}
302+
303+
/**
304+
* Sets environment variables using pre-fetched DB settings.
305+
*
306+
* @param array<string,mixed> $dbSettings Map of DB key => raw value
307+
*/
308+
protected static function setEnvironmentVariablesOptimized(array $dbSettings): void
309+
{
310+
foreach (static::$environmentVariables as $envVar => $configPath) {
311+
$dbKey = Str::startsWith($configPath, 'system.')
312+
? $configPath
313+
: 'system.' . $configPath;
314+
315+
if (empty(env($envVar)) && isset($dbSettings[$dbKey])) {
316+
$value = $dbSettings[$dbKey];
317+
if (is_string($value) && $value !== '') {
318+
putenv(sprintf('%s="%s"', $envVar, addcslashes($value, '"')));
319+
}
320+
}
321+
}
322+
}
219323
}

src/Support/Telemetry.php

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -228,22 +228,7 @@ public static function isSourceModified(): bool
228228
*/
229229
public static function getCurrentCommitHash(): ?string
230230
{
231-
try {
232-
$hash = trim(shell_exec('git rev-parse HEAD'));
233-
234-
if (preg_match('/^[a-f0-9]{40}$/', $hash)) {
235-
return $hash;
236-
}
237-
} catch (\Throwable $e) {
238-
Log::error('[Telemetry] Git hash lookup failed.', ['error' => $e->getMessage()]);
239-
}
240-
241-
// Fallback: maybe allow CURRENT_HASH file in rare non-git builds
242-
$path = base_path('../CURRENT_HASH');
243-
if (file_exists($path)) {
244-
return trim(file_get_contents($path));
245-
}
246-
231+
// @todo Implement a method to get current git hash
247232
return null;
248233
}
249234

0 commit comments

Comments
 (0)