cacheKey = 'language_properties'; } function storeLanguage($data) { $langPath = base_path('lang'); $langDir = $langPath . "/" . $data['code']; $appLangPath = storage_path('app/lang/default'); $language = Language::create($data); $this->syncLanguagePropertiesFromFiles($language); $alreadyExists = is_dir($langDir); if (! $alreadyExists) { File::makeDirectory($langDir, 0777, true, true); File::copyDirectory($appLangPath, $langDir); } } function updateLanguage($id, $data) { Language::find($id)->update($data); } public function syncLanguageFromFiles(string $locale): void { $language = Language::where('code', $locale)->first(); if (! $language) { return; } $this->syncLanguagePropertiesFromFiles($language); $this->forgetLanguageCache($locale); } protected function loadLanguageGroup(string $locale, string $groupName): array { $defaultGroupPath = storage_path("app/lang/groups/{$groupName}.php"); $defaultGroups = file_exists($defaultGroupPath) ? require $defaultGroupPath : []; $repoGroupPath = base_path("lang/{$locale}/groups/{$groupName}.php"); if (file_exists($repoGroupPath)) { return require $repoGroupPath; } $flatFilePath = base_path("lang/{$locale}/{$groupName}.php"); if (file_exists($flatFilePath)) { $flatTranslations = require $flatFilePath; return $this->mergeFlatTranslations($defaultGroups, $flatTranslations, $groupName); } return $defaultGroups; } protected function mergeFlatTranslations(array $defaultGroups, array $flatTranslations, string $groupName): array { if (empty($defaultGroups)) { return [[ 'name' => ucfirst(str_replace('_', ' ', $groupName)), 'slug' => $groupName, 'properties' => $flatTranslations, ]]; } $groups = []; foreach ($defaultGroups as $group) { $properties = []; foreach ($group['properties'] as $key => $value) { if (array_key_exists($key, $flatTranslations)) { $properties[$key] = $flatTranslations[$key]; unset($flatTranslations[$key]); } else { $properties[$key] = $value; } } $groups[] = [ ...$group, 'properties' => $properties, ]; } if (! empty($flatTranslations)) { $groups[] = [ 'name' => ucfirst(str_replace('_', ' ', $groupName)) . ' Extra', 'slug' => "{$groupName}_extra", 'properties' => $flatTranslations, ]; } return $groups; } protected function syncLanguagePropertiesFromFiles(Language $language): void { foreach ($this->groupNames as $groupName) { $groups = $this->loadLanguageGroup($language->code, $groupName); foreach ($groups as $group) { LanguageProperty::updateOrCreate( [ 'language_id' => $language->id, 'group' => $groupName, 'slug' => $group['slug'], ], [ 'name' => $group['name'], 'properties' => $group['properties'], ] ); } } } function defaultLanguage($id) { Language::where('is_default', true)->update(['is_default' => false]); Language::where('id', $id)->update(['is_default' => true]); } protected function getCacheKey(string $locale): string { return "{$this->cacheKey}_{$locale}"; } public function forgetLanguageCache(string $locale): void { Cache::forget($this->getCacheKey($locale)); } protected function getDefaultLocale(): string { $default = Language::where('is_default', true)->value('code'); if ($default) { return $default; } return config('app.locale', 'en'); } protected function buildTranslationsFromFiles(string $locale): array { $langPath = lang_path($locale); if (! is_dir($langPath)) { return []; } $translations = []; foreach (File::allFiles($langPath) as $file) { if ($file->getExtension() !== 'php') { continue; } $group = $file->getFilenameWithoutExtension(); $values = require $file->getPathname(); foreach (Arr::dot($values) as $key => $value) { $translations[$group . '.' . $key] = $value; } } return $translations; } function setLanguageProperties(string $locale): void { $cacheKey = $this->getCacheKey($locale); $cached = Cache::rememberForever($cacheKey, function () use ($locale) { $language = Language::where('code', $locale) ->with('properties') ->first(); if (! $language) { return []; } $groups = []; foreach ($language->properties as $property) { $groups[$property->group] = array_merge($groups[$property->group] ?? [], $property->properties); } $translations = []; foreach ($groups as $group => $properties) { foreach ($properties as $key => $value) { $translations[$group . '.' . $key] = $value; } } return $translations; }); if (empty($cached)) { $cached = $this->buildTranslationsFromFiles($locale); } Lang::addLines($cached, $locale); } function deleteLanguage($id) { $lang = Language::find($id); $langPath = base_path('lang'); $langDir = $langPath . "/" . $lang->code; if ($lang->is_default) { throw new Exception("Default language can't be deleted"); } if (is_dir($langDir)) { File::deleteDirectory($langDir); } $lang->delete(); } }