Skip to content
This repository has been archived by the owner on Aug 7, 2022. It is now read-only.

Commit

Permalink
Merge pull request #3 from luisprmat/main
Browse files Browse the repository at this point in the history
Optimize load of [locale].json exluding not required translations
  • Loading branch information
luisprmat authored Sep 13, 2021
2 parents 5fba20a + 65af63b commit 596b796
Show file tree
Hide file tree
Showing 24 changed files with 637 additions and 76 deletions.
5 changes: 4 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,7 @@ indent_size = 4
trim_trailing_whitespace = true

[*.md]
trim_trailing_whitespace = false
trim_trailing_whitespace = false

[*.json]
insert_final_newline = false
44 changes: 38 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
# Laravel Lang Installer
<h1 align="center">Laravel Lang Installer</h1>

<p align="center">
<a href="https://packagist.org/packages/luisprmat/laravel-lang-installer">
<img src="https://img.shields.io/packagist/dt/luisprmat/laravel-lang-installer" alt="Total Downloads">
</a>
<a href="https://packagist.org/packages/luisprmat/laravel-lang-installer">
<img src="https://img.shields.io/packagist/v/luisprmat/laravel-lang-installer" alt="Latest Stable Version">
</a>
<a href="https://packagist.org/packages/luisprmat/laravel-lang-installer">
<img src="https://img.shields.io/packagist/l/luisprmat/laravel-lang-installer" alt="License">
</a>
</p>

This package helps us to quickly install the language files in a preferably fresh Laravel application.

Expand All @@ -12,11 +24,19 @@ composer require luisprmat/laravel-lang-installer --dev

## Usage

After install a new laravel application with `Laravel >= 5.5` the package autodiscover system will register the new command `lang:add`.
### Add new language
After install a new laravel application with `Laravel >= 5.5` the package autodiscover system will register the new command `lang:add` and you can call with

This command can take a unique argument (or none) that will be the short name of the language according to **ISO 15897**.
```bash
php artisan lang:add <locale>
```
where `<locale>` refers to the short name of any of the [supported languages](README.md#supported-languages)
> ### *Warnings*
> - **Add lang** action overwrites the language files so that you already had custom translations you could lose them.
> - When adding a language this package first consults the `composer.json` file to copy only the translations of the supported packages that are installed ([Laravel Breeze](https://laravel.com/docs/8.x/starter-kits#laravel-breeze), [Laravel Cashier](https://laravel.com/docs/8.x/billing), [Laravel Fortify](https://laravel.com/docs/8.x/fortify) and [Laravel Jetstream](https://jetstream.laravel.com/2.x/introduction.html) are supported) `resources/lang/<locale>.json`. So it is good that you first install the supported packages that you will use and then run the command `php artisan lang:add <locale>`
> - If this command does not receive arguments, the Spanish language [`es`] will be installed by default.
If this command does not receive arguments, the Spanish language [`es`] will be installed by default.
This command can take a unique argument (or none) that will be the short name of the language according to **ISO 15897**.

This command also modifies the key `locale` in the `config/app.php` file to set the default language as passed through the parameter.

Expand Down Expand Up @@ -51,12 +71,24 @@ php artisan lang:add pt_BR --no-default
php artisan lang:add ar --inline
```


## Supported languages
`af`, `ar`, `az`, `be`, `bg`, `bn`, `bs`, `ca`, `cs`, `cy`, `da`, `de`, `de_CH`
, `el`, `es`, `et`, `eu`, `fa`, `fi`, `fil`, `fr`, `gl`, `he`, `hi`, `hr`, `hu`,
`hy`, `id`, `is`, `it`, `ja`, `ka`, `kk`, `km`, `kn`, `ko`, `lt`, `lv`, `mk`, `
mn`, `mr`, `ms`, `nb`, `ne`, `nl`, `nn`, `oc`, `pl`, `ps`, `pt`, `pt_BR`, `ro`,
`ru`, `sc`, `si`, `sk`, `sl`, `sq`, `sr_Cyrl`, `sr_Latn`, `sr_Latn_ME`, `sv`, `s
w`, `tg`, `th`, `tk`, `tl`, `tr`, `ug`, `uk`, `ur`, `uz_Cyrl`, `uz_Latn`, `vi`,
`zh_CN`, `zh_HK`, `zh_TW`

## Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

This package does not modify the translations, only copies them of [`laravel-lang/lang`](https://github.com/Laravel-Lang/lang/). So if you want to suggest changes in the translations you can make a PR to the [`laravel-lang/lang` package](https://github.com/Laravel-Lang/lang/blob/master/docs/contributing-to-dev.md)
This package does not modify the translations, only copies them from [`laravel-lang/lang`](https://github.com/Laravel-Lang/lang/). So if you want to suggest changes in the translations you can make a PR to the [`laravel-lang/lang` package](https://github.com/Laravel-Lang/lang/blob/master/docs/contributing-to-dev.md)

## License
[MIT](LICENSE.md)

## Todo

- [ ] Allow merge translations instead of overwrite them.
- [ ] Add Command `lang:update` to update translations and detect new installed packages to update their translations.
81 changes: 75 additions & 6 deletions src/Console/InstallCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

use Illuminate\Console\Command;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;

class InstallCommand extends Command
{
Expand All @@ -13,15 +15,27 @@ class InstallCommand extends Command

protected $description = "Install translations for language 'locale' (default 'es')";

private array $supportedPackages = [
'breeze' => 'laravel/breeze',
'fortify' => 'laravel/fortify',
'cashier' => 'laravel/cashier',
'jetstream' => 'laravel/jetstream'
];

public function handle()
{
$locale = (string)$this->argument('locale');

if (!in_array($locale, $this->getLocales())) {
if (!in_array($locale, $this->getLocales(base_path('vendor/laravel-lang/lang/locales')))) {
$this->error("Language [{$locale}] is not supported!");
return;
}

if (!File::exists(base_path('composer.json'))) {
$this->error('composer.json not found!');
return;
}

(new Filesystem)->ensureDirectoryExists(resource_path("lang/{$locale}"));

copy(base_path("vendor/laravel-lang/lang/locales/{$locale}/auth.php"), resource_path("lang/{$locale}/auth.php"));
Expand All @@ -34,7 +48,14 @@ public function handle()
copy(base_path("vendor/laravel-lang/lang/locales/{$locale}/validation.php"), resource_path("lang/{$locale}/validation.php"));
}

$this->loadJsonFile($locale);
$discoveredPackages = $this->discoveredPackages();

// Add 'fortify' translations if 'jetstream' is installed
if (in_array('jetstream', $discoveredPackages)) {
array_push($discoveredPackages, 'fortify');
}

$this->loadJsonFile($locale, $discoveredPackages);

if (!$this->option('no-default')) {
// Set config('app.locale')
Expand All @@ -43,6 +64,13 @@ public function handle()
} else {
$this->info("Language [{$locale}] installed successfully, but it isn't the default language.");
}

if (!empty($discoveredPackages)) {
$this->info(
'Translations for ['. implode(', ', $discoveredPackages) .'] '
. Str::plural('package', count($discoveredPackages)) .' merged!'
);
}
}

/**
Expand All @@ -58,19 +86,40 @@ protected function pregReplaceInFile($search, $replace, $path)
file_put_contents($path, preg_replace($search, $replace, file_get_contents($path)));
}

private function loadJsonFile($locale)
private function loadJsonFile($locale, $packages = [])
{
copy(base_path("vendor/laravel-lang/lang/locales/{$locale}/{$locale}.json"), resource_path("lang/{$locale}.json"));
$baseSource = json_decode(File::get(base_path('vendor/laravel-lang/lang/source/en.json')));
$jsonLocale = json_decode(File::get(base_path("vendor/laravel-lang/lang/locales/{$locale}/{$locale}.json")), true);

$showTags = $baseSource;

foreach ($packages as $package) {
$showTags = array_merge(
$showTags,
json_decode(File::get(base_path("vendor/laravel-lang/lang/source/packages/{$package}.json")))
);
}

$showTags = array_unique($showTags);
sort($showTags);

$modify = array_filter($jsonLocale, function ($item) use ($showTags) {
return in_array($item, $showTags);
}, ARRAY_FILTER_USE_KEY);

$modifiedJson = json_encode($modify, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);

File::put(resource_path("lang/{$locale}.json"), $modifiedJson);
}

/**
* @param string $path
* @return array
*/
protected function getLocales(): array
protected function getLocales(string $path): array
{
$filesystem = new Filesystem;

$path = base_path("vendor/laravel-lang/lang/locales");
$directories = $filesystem->directories($path);

$locales = [];
Expand All @@ -80,4 +129,24 @@ protected function getLocales(): array
}
return $locales;
}

/**
* Returns list of installed packages that are supported according to composer.json
*
* @return array
*/
protected function discoveredPackages(): array
{
$composer = json_decode(File::get(base_path('composer.json')), true);

$jsonToCreate = array_keys(array_merge($composer['require'], $composer['require-dev']));

$packagesToInstall = array_filter($jsonToCreate, function ($package) {
return in_array($package, $this->supportedPackages);
});

return array_keys(array_filter($this->supportedPackages, function ($package) use ($packagesToInstall) {
return in_array($package, $packagesToInstall);
}));
}
}
69 changes: 69 additions & 0 deletions tests/Feature/DiscoverPackagesTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

namespace Luisprmat\LaravelLangInstaller\Tests\Feature;

use Illuminate\Support\Facades\File;
use Luisprmat\LaravelLangInstaller\Tests\TestCase;

class DiscoverPackagesTest extends TestCase
{
protected function setUp(): void
{
parent::setUp();
$this->app->setBasePath(__DIR__ . '/../fixtures');

File::ensureDirectoryExists(config_path());
File::copy(__DIR__ . '/../stubs/config/app.php', config_path('app.php'));
}

protected function tearDown(): void
{
parent::tearDown();
File::deleteDirectory(config_path());
File::deleteDirectory(resource_path());
File::delete(base_path('composer.json'));
}

/** @test */
function it_doesnt_execute_if_composer_json_doesnt_exist()
{
$this->artisan('lang:add')
->expectsOutput('composer.json not found!')
->assertExitCode(0);
}

/** @test */
function it_discovers_several_supported_packages_installed_from_composer_json()
{
File::put(base_path('composer.json'), $this->buildComposerWithDependencies(
['"laravel/cashier": "^13.5"', '"package/other": "^2.0"'],
['"laravel/breeze": "^1.4"', '"laravel/no-supported": "^1.0"']
));

$command = $this->artisan('lang:add');
$command->expectsOutput('Translations for [breeze, cashier] packages merged!');
}

/** @test */
function it_discovers_one_supported_package_installed_from_composer_json_require_dev()
{
File::put(base_path('composer.json'), $this->buildComposerWithDependencies(
['"package/other": "^2.0"'],
['"laravel/breeze": "^1.4"', '"laravel/no-supported": "^1.0"']
));

$command = $this->artisan('lang:add');
$command->expectsOutput('Translations for [breeze] package merged!');
}

/** @test */
function it_discovers_one_supported_package_installed_from_composer_json_require()
{
File::put(base_path('composer.json'), $this->buildComposerWithDependencies(
['"laravel/cashier": "^13.5"']
));

$command = $this->artisan('lang:add');
$command->expectsOutput('Translations for [cashier] package merged!');
}
}
Loading

0 comments on commit 596b796

Please sign in to comment.