Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
356 lines (304 sloc) 10.3 KB
<?php
namespace JoeDixon\Translation\Drivers;
use Illuminate\Support\Collection;
use Illuminate\Filesystem\Filesystem;
use JoeDixon\Translation\Exceptions\LanguageExistsException;
class File extends Translation implements DriverInterface
{
private $disk;
private $languageFilesPath;
protected $sourceLanguage;
protected $scanner;
public function __construct(Filesystem $disk, $languageFilesPath, $sourceLanguage, $scanner)
{
$this->disk = $disk;
$this->languageFilesPath = $languageFilesPath;
$this->sourceLanguage = $sourceLanguage;
$this->scanner = $scanner;
}
/**
* Get all languages from the application.
*
* @return Collection
*/
public function allLanguages()
{
// As per the docs, there should be a subdirectory within the
// languages path so we can return these directory names as a collection
$directories = Collection::make($this->disk->directories($this->languageFilesPath));
return $directories->mapWithKeys(function ($directory) {
$language = basename($directory);
return [$language => $language];
})->filter(function ($language) {
// at the moemnt, we're not supporting vendor specific translations
return $language != 'vendor';
});
}
/**
* Get all group translations from the application.
*
* @return array
*/
public function allGroup($language)
{
$groupPath = "{$this->languageFilesPath}/{$language}";
if (! $this->disk->exists($groupPath)) {
return [];
}
$groups = Collection::make($this->disk->allFiles($groupPath));
return $groups->map(function ($group) {
return $group->getBasename('.php');
});
}
/**
* Get all the translations from the application.
*
* @return Collection
*/
public function allTranslations()
{
return $this->allLanguages()->mapWithKeys(function ($language) {
return [$language => $this->allTranslationsFor($language)];
});
}
/**
* Get all translations for a particular language.
*
* @param string $language
* @return Collection
*/
public function allTranslationsFor($language)
{
return Collection::make([
'group' => $this->getGroupTranslationsFor($language),
'single' => $this->getSingleTranslationsFor($language),
]);
}
/**
* Add a new language to the application.
*
* @param string $language
* @return void
*/
public function addLanguage($language, $name = null)
{
if ($this->languageExists($language)) {
throw new LanguageExistsException(__('translation::errors.language_exists', ['language' => $language]));
}
$this->disk->makeDirectory("{$this->languageFilesPath}/$language");
if (! $this->disk->exists("{$this->languageFilesPath}/{$language}.json")) {
$this->saveSingleTranslations($language, []);
}
}
/**
* Add a new group type translation.
*
* @param string $language
* @param string $key
* @param string $value
* @return void
*/
public function addGroupTranslation($language, $key, $value = '')
{
if (! $this->languageExists($language)) {
$this->addLanguage($language);
}
list($group, $key) = explode('.', $key);
$translations = $this->getGroupTranslationsFor($language);
// does the group exist? If not, create it.
if (! $translations->keys()->contains($group)) {
$translations->put($group, []);
}
$values = $translations->get($group);
$values[$key] = $value;
$translations->put($group, $values);
$this->saveGroupTranslations($language, $group, $translations->get($group));
}
/**
* Add a new single type translation.
*
* @param string $language
* @param string $key
* @param string $value
* @return void
*/
public function addSingleTranslation($language, $key, $value = '')
{
if (! $this->languageExists($language)) {
$this->addLanguage($language);
}
$translations = $this->getSingleTranslationsFor($language);
$translations->put($key, $value);
$this->saveSingleTranslations($language, $translations);
}
/**
* Get all of the single translations for a given language.
*
* @param string $language
* @return Collection
*/
public function getSingleTranslationsFor($language)
{
$singlePath = $this->languageFilesPath."/$language.json";
if ($this->disk->exists($singlePath)) {
return new Collection(json_decode($this->disk->get($singlePath), true));
}
return new Collection;
}
/**
* Get all of the group translations for a given language.
*
* @param string $language
* @return Collection
*/
public function getGroupTranslationsFor($language)
{
return $this->getGroupFilesFor($language)->mapWithKeys(function ($group) {
// here we check if the path contains 'vendor' as these will be the
// files which need namespacing
if (str_contains($group->getPathname(), 'vendor')) {
$vendor = str_before(str_after($group->getPathname(), 'vendor/'), '/');
return ["{$vendor}::{$group->getBasename('.php')}" => $this->disk->getRequire($group->getPathname())];
}
return [$group->getBasename('.php') => $this->disk->getRequire($group->getPathname())];
});
}
/**
* Get all the translations for a given file.
*
* @param string $language
* @param string $file
* @return array
*/
public function getTranslationsForFile($language, $file)
{
$file = str_finish($file, '.php');
$filePath = "{$this->languageFilesPath}/{$language}/{$file}";
$translations = [];
if ($this->disk->exists($filePath)) {
return $this->disk->getRequire($filePath);
}
return [];
}
/**
* Determine whether or not a language exists.
*
* @param string $language
* @return bool
*/
public function languageExists($language)
{
return $this->allLanguages()->contains($language);
}
/**
* Add a new group of translations.
*
* @param string $language
* @param string $group
* @return void
*/
public function addGroup($language, $group)
{
$this->saveGroupTranslations($language, $group, []);
}
/**
* Save group type language translations.
*
* @param string $language
* @param string $group
* @param array $translations
* @return void
*/
private function saveGroupTranslations($language, $group, $translations)
{
// here we check if it's a namespaced translation which need saving to a
// different path
if (str_contains($group, '::')) {
return $this->saveNamespacedGroupTranslations($language, $group, $translations);
}
$this->disk->put("{$this->languageFilesPath}/{$language}/{$group}.php", "<?php\n\nreturn ".var_export($translations, true).';'.\PHP_EOL);
}
/**
* Save namespaced group type language translations.
*
* @param string $language
* @param string $group
* @param array $translations
* @return void
*/
private function saveNamespacedGroupTranslations($language, $group, $translations)
{
list($namespace, $group) = explode('::', $group);
$directory = "{$this->languageFilesPath}/vendor/{$namespace}/{$language}";
if (! $this->disk->exists($directory)) {
$this->disk->makeDirectory($directory, 0755, true);
}
$this->disk->put("$directory/{$group}.php", "<?php\n\nreturn ".var_export($translations, true).';'.\PHP_EOL);
}
/**
* Save single type language translations.
*
* @param string $language
* @param array $translations
* @return void
*/
private function saveSingleTranslations($language, $translations)
{
$this->disk->put(
"{$this->languageFilesPath}/$language.json",
json_encode((object) $translations, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)
);
}
/**
* Get all the group files for a given language.
*
* @param string $language
* @return Collection
*/
public function getGroupFilesFor($language)
{
$groups = new Collection($this->disk->allFiles("{$this->languageFilesPath}/{$language}"));
// namespaced files reside in the vendor directory so we'll grab these
// the `getVendorGroupFileFor` method
$groups = $groups->merge($this->getVendorGroupFilesFor($language));
return $groups;
}
/**
* Get a collection of group names for a given language.
*
* @param string $language
* @return Collection
*/
public function getGroupsFor($language)
{
return $this->getGroupFilesFor($language)->map(function ($file) {
if (str_contains($file->getPathname(), 'vendor')) {
$vendor = str_before(str_after($file->getPathname(), 'vendor/'), '/');
return "{$vendor}::{$file->getBasename('.php')}";
}
return $file->getBasename('.php');
});
}
/**
* Get all the vendor group files for a given language.
*
* @param string $language
* @return Collection
*/
public function getVendorGroupFilesFor($language)
{
if (! $this->disk->exists("{$this->languageFilesPath}/vendor")) {
return;
}
$vendorGroups = [];
foreach ($this->disk->directories("{$this->languageFilesPath}/vendor") as $vendor) {
$vendor = array_last(explode('/', $vendor));
if (! $this->disk->exists("{$this->languageFilesPath}/vendor/{$vendor}/{$language}")) {
array_push($vendorGroups, []);
} else {
array_push($vendorGroups, $this->disk->allFiles("{$this->languageFilesPath}/vendor/{$vendor}/{$language}"));
}
}
return new Collection(array_flatten($vendorGroups));
}
}