generated from boboko/starter
97 lines
3.0 KiB
PHP
97 lines
3.0 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use Spatie\YamlFrontMatter\YamlFrontMatter;
|
|
|
|
/**
|
|
* Site-wide, marketing-editable settings from Stoic's `settings` singleton
|
|
* (resources/stoic/content/{locale}/settings.md). Read directly rather than
|
|
* through a Paper model: Paper models map to a folder of entries, and this is
|
|
* one file per locale. Legal and transactional details (address, ΑΦΜ, phone)
|
|
* live in boboko-core's StoreDetails instead.
|
|
*
|
|
* Stoic writes every field to the default locale's file and only the
|
|
* translatable ones (e.g. meta_description) to the others, so the current
|
|
* locale's file is layered over the default one; empty values fall through.
|
|
*
|
|
* Bound as scoped in AppServiceProvider, so files are parsed at most once per
|
|
* locale per request (or queued job) and edits in Stoic show up on the next one.
|
|
* The locale is read per call, not at construction, so a mail rendered with
|
|
* ->locale() still gets its own locale's values.
|
|
*/
|
|
class StoicSettings
|
|
{
|
|
private const SOCIALS = [
|
|
'facebook' => 'Facebook',
|
|
'instagram' => 'Instagram',
|
|
'tiktok' => 'TikTok',
|
|
];
|
|
|
|
/** @var array<string, array<string, mixed>> keyed by locale */
|
|
private array $data = [];
|
|
|
|
public function get(string $key, mixed $default = null): mixed
|
|
{
|
|
$value = $this->data()[$key] ?? null;
|
|
|
|
return filled($value) ? $value : $default;
|
|
}
|
|
|
|
/**
|
|
* Absolute og:image URL for a Stoic image field value (the page's own, else
|
|
* the default from settings.md), or null. Image fields store a
|
|
* comma-separated list; only the first is used.
|
|
*/
|
|
public function ogImageUrl(?string $pageImage = null): ?string
|
|
{
|
|
$filename = trim(explode(',', $pageImage ?: (string) $this->get('og_image', ''))[0]);
|
|
|
|
return $filename === '' ? null : url(Stoic::image($filename, 'large'));
|
|
}
|
|
|
|
/**
|
|
* Only the networks that have a URL set, in display order.
|
|
*
|
|
* @return list<array{icon: string, label: string, url: string}>
|
|
*/
|
|
public function socialLinks(): array
|
|
{
|
|
$links = [];
|
|
|
|
foreach (self::SOCIALS as $icon => $label) {
|
|
if ($url = $this->get("{$icon}_url")) {
|
|
$links[] = ['icon' => $icon, 'label' => $label, 'url' => $url];
|
|
}
|
|
}
|
|
|
|
return $links;
|
|
}
|
|
|
|
private function data(): array
|
|
{
|
|
$locale = app()->getLocale();
|
|
|
|
return $this->data[$locale] ??= $this->load();
|
|
}
|
|
|
|
private function load(): array
|
|
{
|
|
$default = Stoic::defaultLocale();
|
|
|
|
if ($default === null) {
|
|
return $this->parse(resource_path('stoic/content/settings.md'));
|
|
}
|
|
|
|
return array_merge(
|
|
$this->parse(resource_path("stoic/content/{$default}/settings.md")),
|
|
Stoic::localeOverrides('settings.md'),
|
|
);
|
|
}
|
|
|
|
private function parse(string $path): array
|
|
{
|
|
return is_file($path) ? YamlFrontMatter::parse(file_get_contents($path))->matter() : [];
|
|
}
|
|
}
|