186 lines
4.9 KiB
PHP
186 lines
4.9 KiB
PHP
<?php
|
|
|
|
namespace Database\Seeders;
|
|
|
|
use FluxCms\Core\Models\CmsContent;
|
|
use Illuminate\Database\Seeder;
|
|
use Illuminate\Support\Arr;
|
|
|
|
class CmsContentSeeder extends Seeder
|
|
{
|
|
/**
|
|
* Files to skip entirely (handled by dedicated seeders or irrelevant).
|
|
*
|
|
* @var array<string>
|
|
*/
|
|
protected array $skipFiles = [
|
|
'faqs',
|
|
'sections',
|
|
'search_index',
|
|
'validation',
|
|
'auth',
|
|
'passwords',
|
|
'pagination',
|
|
];
|
|
|
|
/**
|
|
* Keys to skip within specific groups (handled by dedicated models).
|
|
*
|
|
* @var array<string, array<string>>
|
|
*/
|
|
protected array $skipKeys = [
|
|
'components' => ['news_band', 'industries_band'],
|
|
];
|
|
|
|
public function run(): void
|
|
{
|
|
$locales = ['de', 'en'];
|
|
|
|
$deFiles = glob(lang_path('de/*.php'));
|
|
if (! $deFiles) {
|
|
return;
|
|
}
|
|
|
|
foreach ($deFiles as $filePath) {
|
|
$group = pathinfo($filePath, PATHINFO_FILENAME);
|
|
|
|
if (in_array($group, $this->skipFiles)) {
|
|
continue;
|
|
}
|
|
|
|
$translations = [];
|
|
foreach ($locales as $locale) {
|
|
$localePath = lang_path("{$locale}/{$group}.php");
|
|
if (file_exists($localePath)) {
|
|
$translations[$locale] = require $localePath;
|
|
}
|
|
}
|
|
|
|
if (empty($translations)) {
|
|
continue;
|
|
}
|
|
|
|
$deData = $translations['de'] ?? [];
|
|
$enData = $translations['en'] ?? [];
|
|
|
|
$flatDe = $this->flatten($deData);
|
|
$flatEn = $this->flatten($enData);
|
|
|
|
$allKeys = array_keys($flatDe);
|
|
foreach (array_keys($flatEn) as $enKey) {
|
|
if (! in_array($enKey, $allKeys)) {
|
|
$allKeys[] = $enKey;
|
|
}
|
|
}
|
|
|
|
$order = 0;
|
|
foreach ($allKeys as $key) {
|
|
if ($this->shouldSkipKey($group, $key)) {
|
|
continue;
|
|
}
|
|
|
|
$deValue = $flatDe[$key] ?? null;
|
|
$enValue = $flatEn[$key] ?? null;
|
|
|
|
$type = $this->detectType($deValue ?? $enValue);
|
|
|
|
$translatedValue = [];
|
|
if ($deValue !== null) {
|
|
$translatedValue['de'] = is_string($deValue) ? $this->cleanHtml($deValue) : $deValue;
|
|
}
|
|
if ($enValue !== null) {
|
|
$translatedValue['en'] = is_string($enValue) ? $this->cleanHtml($enValue) : $enValue;
|
|
}
|
|
|
|
CmsContent::updateOrCreate(
|
|
['group' => $group, 'key' => $key],
|
|
[
|
|
'type' => $type,
|
|
'value' => $translatedValue,
|
|
'order' => $order++,
|
|
]
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Flatten a nested array into dot-notation keys.
|
|
* Arrays of objects (indexed arrays) are stored as JSON type.
|
|
*
|
|
* @return array<string, mixed>
|
|
*/
|
|
protected function flatten(array $array, string $prefix = ''): array
|
|
{
|
|
$result = [];
|
|
|
|
foreach ($array as $key => $value) {
|
|
$fullKey = $prefix ? "{$prefix}.{$key}" : (string) $key;
|
|
|
|
if (is_array($value) && ! Arr::isAssoc($value)) {
|
|
$result[$fullKey] = $value;
|
|
} elseif (is_array($value)) {
|
|
$result = array_merge($result, $this->flatten($value, $fullKey));
|
|
} else {
|
|
$result[$fullKey] = $value;
|
|
}
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
protected function detectType(mixed $value): string
|
|
{
|
|
if (is_array($value)) {
|
|
return 'json';
|
|
}
|
|
|
|
if (! is_string($value)) {
|
|
return 'text';
|
|
}
|
|
|
|
if (preg_match('/<[a-z][\s\S]*>/i', $value)) {
|
|
return 'html';
|
|
}
|
|
|
|
if (preg_match('/\.(jpg|jpeg|png|gif|webp|svg)(\?.*)?$/i', $value)) {
|
|
return 'image';
|
|
}
|
|
|
|
if (preg_match('/\.(pdf|doc|docx)$/i', $value)) {
|
|
return 'link';
|
|
}
|
|
|
|
return 'text';
|
|
}
|
|
|
|
/**
|
|
* Clean HTML by converting font-weight spans to <strong> tags.
|
|
* Preserves text-gradient-premium spans and email-protection spans.
|
|
*/
|
|
protected function cleanHtml(string $value): string
|
|
{
|
|
$value = preg_replace(
|
|
'/<span\s+class="[^"]*(?:font-semibold|font-bold)[^"]*">(\s*)(.*?)<\/span>/si',
|
|
'$1<strong>$2</strong>',
|
|
$value
|
|
);
|
|
|
|
return $value;
|
|
}
|
|
|
|
protected function shouldSkipKey(string $group, string $key): bool
|
|
{
|
|
if (! isset($this->skipKeys[$group])) {
|
|
return false;
|
|
}
|
|
|
|
foreach ($this->skipKeys[$group] as $skipPrefix) {
|
|
if ($key === $skipPrefix || str_starts_with($key, "{$skipPrefix}.")) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|