Files
ABSDEV/Modules/Settings/Http/Controllers/SettingController.php
T

110 lines
4.9 KiB
PHP

<?php
namespace Modules\Settings\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Illuminate\View\View;
use Modules\Settings\Services\SettingsRepository;
use Modules\Stylist\Theme\Loader;
final class SettingController extends Controller
{
public function index(SettingsRepository $settings, Loader $themes): View
{
return view('settings::index', [
'values' => $settings->site(),
'sections' => $this->sections($themes),
]);
}
public function update(Request $request, SettingsRepository $settings, Loader $themes): RedirectResponse
{
$rules = [];
foreach ($this->sections($themes) as $fields) {
foreach ($fields as $key => $definition) {
$rules["settings.$key"] = $definition['rules'];
}
}
$validated = $request->validate($rules);
foreach ($validated['settings'] ?? [] as $key => $value) {
$settings->put($key, $value, 'site', 'string', true);
}
return back()->with('status', 'Site settings saved. The active frontend and backend themes have been updated.');
}
/** @return array<string, array<string, array<string, mixed>>> */
private function sections(Loader $themes): array
{
$text = ['type' => 'text', 'rules' => ['nullable', 'string', 'max:255']];
$url = ['type' => 'text', 'rules' => ['nullable', 'string', 'max:2048'], 'placeholder' => '/path or https://example.com'];
$textarea = ['type' => 'textarea', 'rules' => ['nullable', 'string', 'max:5000']];
$backendThemes = $themes->all()
->filter(fn ($theme): bool => $theme->type() === 'backend')
->mapWithKeys(fn ($theme): array => [$theme->key() => $theme->name()])
->all();
$frontendThemes = $themes->all()
->filter(fn ($theme): bool => $theme->type() === 'frontend')
->mapWithKeys(fn ($theme): array => [$theme->key() => $theme->name()])
->all();
return [
'Themes' => [
'backend_theme' => [
'type' => 'select',
'rules' => ['required', 'string', Rule::in(array_keys($backendThemes))],
'label' => 'Backend theme',
'help' => 'Used for the authenticated administration area.',
'options' => $backendThemes,
],
'frontend_theme' => [
'type' => 'select',
'rules' => ['required', 'string', Rule::in(array_keys($frontendThemes))],
'label' => 'Frontend theme',
'help' => 'Used for the public website.',
'options' => $frontendThemes,
],
],
'General' => [
'site_name' => $text + ['label' => 'Site name', 'help' => 'Used in the header, footer, browser titles and metadata.'],
'tagline' => $text + ['label' => 'Tagline'],
'site_description' => $textarea + ['label' => 'Site description'],
'company_name' => $text + ['label' => 'Legal company name'],
'site_url' => $url + ['label' => 'Canonical site URL'],
'copyright' => $text + ['label' => 'Copyright text', 'help' => 'Leave blank to generate it automatically.'],
],
'Branding' => [
'logo_url' => $url + ['label' => 'Primary logo'],
'logo_dark_url' => $url + ['label' => 'Dark-mode logo'],
'favicon_url' => $url + ['label' => 'Favicon'],
],
'Contact' => [
'contact_email' => ['type' => 'email', 'rules' => ['nullable', 'email', 'max:255'], 'label' => 'Public email'],
'contact_phone' => $text + ['label' => 'Public telephone'],
'address' => $textarea + ['label' => 'Address'],
],
'Social' => [
'facebook_url' => $url + ['label' => 'Facebook'],
'x_url' => $url + ['label' => 'X / Twitter'],
'linkedin_url' => $url + ['label' => 'LinkedIn'],
'instagram_url' => $url + ['label' => 'Instagram'],
],
'Account navigation' => [
'dashboard_label' => $text + ['label' => 'Dashboard label'],
'login_label' => $text + ['label' => 'Login label'],
'registration_label' => $text + ['label' => 'Registration label'],
],
'SEO defaults' => [
'default_meta_title' => $text + ['label' => 'Default meta title', 'help' => 'Leave blank to use the site name.'],
'default_meta_description' => $textarea + ['label' => 'Default meta description', 'help' => 'Leave blank to use the site description.'],
],
];
}
}