.php * theme.php one theme definition with its 'id'; registered in themes.themes and made the active theme * lang/ translation overrides, merged key by key: .json, /.php and * vendor///.php * views/ template overrides, whole files: e.g. emails/..., logos/.blade.php; views/mail/ for the * mail components (header, footer, button); views/vendor// for package views * public/ favicons, mail-logo.png, mail-logo-inverted.png; served at /platform/ through the link * public/platform (php artisan platform:link) */ class PlatformServiceProvider extends ServiceProvider { public function register(): void { $config = platform_path('config.php'); if (is_file($config)) { config([config('app.timebank_config', 'timebank-default') => require $config]); } $theme = platform_path('theme.php'); if (is_file($theme)) { $definition = require $theme; $id = $definition['id'] ?? 'platform'; unset($definition['id']); config(["themes.themes.{$id}" => $definition, 'themes.active' => $id]); } // Read when the mail Markdown renderer is first made, so set it before that happens $mailViews = platform_path('views/mail'); if (is_dir($mailViews)) { config(['mail.markdown.paths' => [$mailViews, ...config('mail.markdown.paths', [])]]); } } public function boot(): void { // addPath, not addJsonPath: Laravel merges the main lang folder after the JSON paths, so only a path added // after it can override a text. It also covers vendor/ translations. $lang = platform_path('lang'); if (is_dir($lang)) { $this->app['translator']->getLoader()->addPath($lang); } $views = platform_path('views'); if (is_dir($views)) { View::prependLocation($views); // Package view overrides are looked up when the package registers its views, so a location added // now is not searched for them: prepend each package folder to its namespace. foreach (glob("{$views}/vendor/*", GLOB_ONLYDIR) ?: [] as $packageViews) { View::prependNamespace(basename($packageViews), $packageViews); } } } }