├── .gitignore
├── src
├── Commands
│ ├── bundle-file-stub.php
│ ├── MakeBundlesFolder.php
│ ├── LaravelLangBundlerCommand.php
│ ├── MakeNewBundleFile.php
│ └── MakeBundleMod.php
├── BundleItems
│ ├── Mods
│ │ ├── UcfirstMod.php
│ │ ├── ChangeMod.php
│ │ ├── StrtolowerMod.php
│ │ ├── StrtoupperMod.php
│ │ ├── ExplodeMod.php
│ │ ├── ValuesMod.php
│ │ └── CallbackMod.php
│ ├── ModStub.php
│ ├── ItemFactory.php
│ ├── ItemWrapper.php
│ └── BundleItem.php
├── Exceptions
│ └── InvalidModificationArgument.php
├── helpers.php
├── LangBundler.php
├── Translator.php
├── config.php
├── ServiceProvider.php
└── Bundle
│ ├── BundleMap.php
│ └── Bundle.php
├── .travis.yml
├── tests
├── stubs
│ ├── en
│ │ ├── nav.php
│ │ ├── translations.php
│ │ ├── user.php
│ │ └── home.php
│ ├── ja
│ │ ├── nav.php
│ │ └── home.php
│ ├── bin2hex.php
│ ├── bundle5.php
│ ├── bundle6.php
│ ├── bundle7.php
│ ├── bundle9.php
│ ├── bundle8.php
│ ├── bundle1.php
│ ├── components
│ │ ├── sub-components
│ │ │ └── bundle4.php
│ │ └── bundle3.php
│ ├── bundle2.php
│ ├── bundle10.php
│ ├── Bin2hexMod.php
│ └── ExpectedResults.php
├── Unit
│ ├── BundleTest.php
│ ├── CommandsTest.php
│ ├── ItemFactoryTest.php
│ ├── BundleItemTest.php
│ ├── BundleItemModTest.php
│ └── BundleMapTest.php
├── Integration
│ ├── IntegrationTest.php
│ └── TranslatorTest.php
└── TestCase.php
├── .scrutinizer.yaml
├── phpunit.xml
├── composer.json
├── LICENSE
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor
2 | .env
3 | composer.lock
4 |
--------------------------------------------------------------------------------
/src/Commands/bundle-file-stub.php:
--------------------------------------------------------------------------------
1 | 'Home',
5 | 'top' => 'Top',
6 | ];
7 |
--------------------------------------------------------------------------------
/tests/stubs/ja/nav.php:
--------------------------------------------------------------------------------
1 | 'ホーム',
5 | 'top' => 'トップ',
6 | ];
7 |
--------------------------------------------------------------------------------
/tests/stubs/bin2hex.php:
--------------------------------------------------------------------------------
1 | 'ようこそ',
5 | 'signup' => 'サインアップ',
6 | 'login' => 'ログイン',
7 | ];
8 |
--------------------------------------------------------------------------------
/tests/stubs/bundle7.php:
--------------------------------------------------------------------------------
1 | 'Welcome',
5 | 'signup' => 'Signup',
6 | 'login' => 'Login',
7 | 'home' => 'Home',
8 | 'top' => 'Top',
9 | ];
10 |
--------------------------------------------------------------------------------
/tests/stubs/en/user.php:
--------------------------------------------------------------------------------
1 | 'Welcome :user',
5 | 'message_from' => 'You have a message from :sender',
6 | 'welcomeUser' => 'Welcome :user',
7 | 'messageFrom' => 'You have a message from :sender',
8 | 'message_to' => 'You sent a message to :user',
9 | 'invite_from' => 'You have an invite from :user',
10 | ];
11 |
--------------------------------------------------------------------------------
/tests/stubs/bundle2.php:
--------------------------------------------------------------------------------
1 | [
5 | 'home.welcome',
6 | 'home.signup',
7 | 'home.login',
8 | 'nav.home',
9 | 'nav.top',
10 | ],
11 |
12 | 'component2' => [
13 | 'home.welcome',
14 | 'home.signup',
15 | 'home.login',
16 | 'nav.home',
17 | 'nav.top',
18 | ],
19 | ];
20 |
--------------------------------------------------------------------------------
/tests/stubs/components/bundle3.php:
--------------------------------------------------------------------------------
1 | [
5 | 'home.welcome',
6 | 'home.signup',
7 | 'home.login',
8 | 'nav.home',
9 | 'nav.top',
10 | ],
11 |
12 | 'forum' => [
13 | 'component2' => [
14 | 'home.welcome',
15 | 'home.signup',
16 | 'home.login',
17 | 'nav.home',
18 | 'nav.top',
19 | ],
20 |
21 | 'component3' => [
22 | 'payment.creditcard',
23 | 'payment.date',
24 | 'payment.submit',
25 | ],
26 | ],
27 | ];
28 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 | ./tests/
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/BundleItems/Mods/UcfirstMod.php:
--------------------------------------------------------------------------------
1 | wrapperParameters['new'];
19 | }
20 |
21 | /**
22 | * Alter value and return.
23 | *
24 | * @param mixed $value
25 | *
26 | * @return mixed
27 | */
28 | public function value($value)
29 | {
30 | return $value;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/BundleItems/Mods/StrtolowerMod.php:
--------------------------------------------------------------------------------
1 | wrapperParameters['delimiter'], $value);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/BundleItems/Mods/ValuesMod.php:
--------------------------------------------------------------------------------
1 | 'Welcome',
5 | 'signup' => 'Signup',
6 | 'login' => 'Login',
7 | 'months' => [
8 | 'january' => 'Jan',
9 | 'february' => 'Feb',
10 | 'march' => 'March',
11 | 'april' => 'April',
12 | 'may' => 'May',
13 | 'june' => 'June',
14 | 'july' => 'July',
15 | 'august' => 'Aug',
16 | 'september' => 'Sept',
17 | 'october' => 'Oct',
18 | 'november' => 'Nov',
19 | 'december' => 'Dec',
20 | ],
21 | 'inbox_status' => 'You have a new message.|You have new messages',
22 | 'lowercase' => 'lowercase string',
23 | 'uppercase' => 'UPPERSACE STRING',
24 | ];
25 |
--------------------------------------------------------------------------------
/src/Exceptions/InvalidModificationArgument.php:
--------------------------------------------------------------------------------
1 | 'ucfirst',
6 | ]),
7 | bundle_item('user.message_to', 'value_callback', [
8 | 'callback' => 'strtoupper',
9 | ]),
10 | bundle_item('user.invite_from', 'key_callback', [
11 | 'callback' => 'studly_case',
12 | ]),
13 | bundle_item('user.invite_from', 'key_change', [
14 | 'new' => 'newKey',
15 | ]),
16 | bundle_item('home.months', 'value_values'),
17 | bundle_item('user.message_to', 'both_callback', [
18 | 'callback' => 'strtoupper',
19 | ]),
20 | bundle_item('home.lowercase', 'value_ucfirst'),
21 | bundle_item('home.lowercase', 'value_strtoupper'),
22 | bundle_item('home.lowercase', 'value_explode', [
23 | 'delimiter' => ' ',
24 | ]),
25 | bundle_item('home.uppercase', 'value_strtolower'),
26 | ];
27 |
--------------------------------------------------------------------------------
/src/Commands/MakeBundlesFolder.php:
--------------------------------------------------------------------------------
1 | setUp();
27 |
28 | $directory = resource_path('lang'.DIRECTORY_SEPARATOR.'bundles');
29 |
30 | if (!$this->filesystem->exists($directory)) {
31 | $this->filesystem->makeDirectory($directory);
32 | }
33 |
34 | $this->info('Bundles folder successfully created!');
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/BundleItems/Mods/CallbackMod.php:
--------------------------------------------------------------------------------
1 | callCallback($key);
19 | }
20 |
21 | /**
22 | * Alter value and return.
23 | *
24 | * @param string $value
25 | *
26 | * @return mixed
27 | */
28 | public function value($value)
29 | {
30 | return $this->callCallback($value);
31 | }
32 |
33 | /**
34 | * Call the given callback.
35 | *
36 | * @param string $string
37 | *
38 | * @return string
39 | */
40 | protected function callCallback($string)
41 | {
42 | if (is_callable($this->wrapperParameters['callback'])) {
43 | $callback = $this->wrapperParameters['callback'];
44 |
45 | return $callback($string);
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/Commands/LaravelLangBundlerCommand.php:
--------------------------------------------------------------------------------
1 | filesystem = new Filesystem();
23 | }
24 |
25 | /**
26 | * Build path from path array.
27 | *
28 | * @param array $pathArray
29 | * @param string $path
30 | *
31 | * @return string
32 | */
33 | protected function buildPath($pathArray, $path)
34 | {
35 | foreach ($pathArray as $directory) {
36 | $path .= $directory.DIRECTORY_SEPARATOR;
37 |
38 | if (!$this->filesystem->exists($path)) {
39 | $this->filesystem->makeDirectory($path);
40 | }
41 | }
42 |
43 | return $path;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "zachleigh/laravel-lang-bundler",
3 | "description": "Create Laravel translations bundles.",
4 | "keywords": ["laravel", "localization", "translation", "language", "lang"],
5 | "type": "project",
6 | "license": "MIT",
7 | "authors": [
8 | {
9 | "name": "Zach Leigh",
10 | "email": "zachleigh@fastmail.jp"
11 | }
12 | ],
13 |
14 | "require": {
15 | "php": ">=7.1",
16 | "laravel/browser-kit-testing": "^1.0"
17 | },
18 |
19 | "require-dev": {
20 | "laravel/laravel": "5.7.*",
21 | "phpunit/phpunit": "~4.0"
22 | },
23 |
24 | "autoload": {
25 | "psr-4": {
26 | "LaravelLangBundler\\": "src/"
27 | },
28 |
29 | "files": [
30 | "src/helpers.php"
31 | ]
32 | },
33 |
34 | "autoload-dev": {
35 | "psr-4": {
36 | "LaravelLangBundler\\tests\\": "tests/"
37 | }
38 | },
39 |
40 | "scripts": {
41 | "test": "phpunit"
42 | },
43 |
44 | "minimum-stability": "stable",
45 | "prefer-stable": true
46 | }
47 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017 Zach Leigh
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/BundleItems/ModStub.php:
--------------------------------------------------------------------------------
1 | copyStubs('bundle2');
20 |
21 | $bundle = new Bundle('bundles.bundle2.component2', $this->bundleMap);
22 |
23 | foreach ($bundle->getValues() as $value) {
24 | $this->assertInstanceOf(BundleItem::class, $value);
25 | }
26 | }
27 |
28 | /**
29 | * @test
30 | */
31 | public function if_value_is_already_a_translation_object_it_passes()
32 | {
33 | $this->copyStubs('bundle9');
34 |
35 | $bundle = new Bundle('bundle9', $this->bundleMap);
36 |
37 | foreach ($bundle->getValues() as $value) {
38 | $this->assertInstanceOf(BundleItem::class, $value);
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/helpers.php:
--------------------------------------------------------------------------------
1 | trans($id, $parameters, $locale);
22 | }
23 | }
24 |
25 | if (!function_exists('bundle_item')) {
26 | /**
27 | * Create a BundleItem class directly from the bundle registration file.
28 | *
29 | * @param string $id
30 | * @param string $type target_modType
31 | * @param array $parameters
32 | *
33 | * @return BundleItem
34 | */
35 | function bundle_item($id, $type = null, array $parameters = [])
36 | {
37 | return ItemFactory::build($id, $type, $parameters);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/tests/stubs/Bin2hexMod.php:
--------------------------------------------------------------------------------
1 | bundleMap = $bundleMap;
30 | $this->translator = $translator;
31 |
32 | $this->bundleMap->mapBundles();
33 | }
34 |
35 | /**
36 | * Translate the given message.
37 | *
38 | * @param string $id
39 | * @param array $parameters
40 | * @param string $locale
41 | *
42 | * @return \Illuminate\Support\Collection
43 | */
44 | public function trans($id, array $parameters = [], $locale = null)
45 | {
46 | $bundle = new Bundle($id, $this->bundleMap);
47 |
48 | if ($bundle->hasNoValues()) {
49 | return app('translator')->trans($id, $parameters, $locale);
50 | }
51 |
52 | return $this->translator->translateBundle($bundle, $parameters, $locale);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/Translator.php:
--------------------------------------------------------------------------------
1 | getValues()
26 | ->mapWithKeys(function (BundleItem $bundleItem) use ($parameters, $locale) {
27 | $bundleItem->setParameters($parameters);
28 |
29 | if ($choice = $bundleItem->hasChoice()) {
30 | $value = app('translator')->transChoice(
31 | $bundleItem->getId(),
32 | $choice,
33 | $bundleItem->getParameters(),
34 | $locale
35 | );
36 | } else {
37 | $value = app('translator')->trans(
38 | $bundleItem->getId(),
39 | $bundleItem->getParameters(),
40 | $locale
41 | );
42 | }
43 |
44 | return $bundleItem->setValue($value)->getReturnArray();
45 | });
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/Commands/MakeNewBundleFile.php:
--------------------------------------------------------------------------------
1 | setUp();
27 |
28 | $pathArray = collect(explode('.', $this->argument('path')));
29 |
30 | $filename = $pathArray->pop().'.php';
31 |
32 | $pathArray->prepend('bundles');
33 |
34 | $basePath = resource_path('lang'.DIRECTORY_SEPARATOR);
35 |
36 | $path = $this->buildPath($pathArray->all(), $basePath);
37 |
38 | $this->createFile($path, $filename);
39 |
40 | $this->info('Bundle file successfully created!');
41 | }
42 |
43 | /**
44 | * Create file from stub.
45 | *
46 | * @param string $path
47 | * @param string $filename
48 | */
49 | protected function createFile($path, $filename)
50 | {
51 | $filePath = $path.$filename;
52 |
53 | $stub = __DIR__.DIRECTORY_SEPARATOR.'bundle-file-stub.php';
54 |
55 | if (!$this->filesystem->exists($filePath)) {
56 | $this->filesystem->copy($stub, $filePath);
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/config.php:
--------------------------------------------------------------------------------
1 | [
15 | // 'alias' => 'path.to.bundle'
16 | ],
17 |
18 | /*
19 | |--------------------------------------------------------------------------
20 | | Transform Lang Keys
21 | |--------------------------------------------------------------------------
22 | |
23 | | Transform lang value keys.
24 | | Available options: 'camel_case', 'none', 'snake_case', 'studly_case'.
25 | */
26 | 'key_transform' => 'none',
27 |
28 | /*
29 | |--------------------------------------------------------------------------
30 | | Global Key Namespace
31 | |--------------------------------------------------------------------------
32 | |
33 | | If you keep your translations in a single file, it may be useful to use a
34 | | global key namespace. For example, if your translations are in a file
35 | | called 'translations', for every key you have to type 'translations.key'.
36 | | Set the namespace to 'translations' so you only have to type 'key'.
37 | */
38 | 'global_key_namespace' => '',
39 | ];
40 |
--------------------------------------------------------------------------------
/src/ServiceProvider.php:
--------------------------------------------------------------------------------
1 | app->singleton(LangBundler::class, function () {
21 | return new LangBundler(
22 | new BundleMap(),
23 | new Translator()
24 | );
25 | });
26 |
27 | $this->registerCommands();
28 | }
29 |
30 | /**
31 | * Perform post-registration booting of services.
32 | *
33 | * @return void
34 | */
35 | public function boot()
36 | {
37 | $this->publishes([
38 | __DIR__.DIRECTORY_SEPARATOR.'config.php' => config_path('lang-bundler.php'),
39 | ], 'config');
40 | }
41 |
42 | /**
43 | * Register Artisan commands.
44 | */
45 | protected function registerCommands()
46 | {
47 | $this->app->singleton('command.langb.start', function ($app) {
48 | return $app[MakeBundlesFolder::class];
49 | });
50 |
51 | $this->app->singleton('command.langb.new', function ($app) {
52 | return $app[MakeNewBundleFile::class];
53 | });
54 |
55 | $this->app->singleton('command.langb.mod', function ($app) {
56 | return $app[MakeBundleMod::class];
57 | });
58 |
59 | $this->commands('command.langb.start');
60 |
61 | $this->commands('command.langb.new');
62 |
63 | $this->commands('command.langb.mod');
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/tests/Unit/CommandsTest.php:
--------------------------------------------------------------------------------
1 | assertFileNotExists($directory);
17 |
18 | Artisan::call('langb:start');
19 |
20 | $this->assertFileExists($directory);
21 | }
22 |
23 | /**
24 | * @test
25 | */
26 | public function make_new_bundle_file_makes_new_file()
27 | {
28 | $file = resource_path('lang/bundles/test/components/new.php');
29 |
30 | $this->assertFileNotExists($file);
31 |
32 | Artisan::call('langb:new', ['path' => 'test.components.new']);
33 |
34 | $this->assertFileExists($file);
35 | }
36 |
37 | /**
38 | * @test
39 | */
40 | public function make_new_bundle_file_doesnt_overwrite_folders()
41 | {
42 | Artisan::call('langb:new', ['path' => 'test.new']);
43 |
44 | Artisan::call('langb:new', ['path' => 'test.components.new']);
45 |
46 | Artisan::call('langb:new', ['path' => 'test.newer']);
47 |
48 | Artisan::call('langb:new', ['path' => 'new']);
49 |
50 | $files = [
51 | resource_path('lang/bundles/test/new.php'),
52 | resource_path('lang/bundles/test/components/new.php'),
53 | resource_path('lang/bundles/test/newer.php'),
54 | resource_path('lang/bundles/new.php'),
55 | ];
56 |
57 | foreach ($files as $file) {
58 | $this->assertFileExists($file);
59 | }
60 | }
61 |
62 | /**
63 | * @test
64 | */
65 | public function make_bundle_wrapper_makes_a_bundle_wrapper()
66 | {
67 | Artisan::call('langb:mod', ['name' => 'test']);
68 |
69 | $this->assertFileExists(app_path('LangBundler/Mods/TestMod.php'));
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/BundleItems/ItemFactory.php:
--------------------------------------------------------------------------------
1 | getNamespace();
43 |
44 | $localClass = "\\{$appNamespace}LangBundler\\Mods\\{$className}";
45 |
46 | $vendorClass = "\LaravelLangBundler\\BundleItems\\Mods\\{$className}";
47 |
48 | if (class_exists($localClass)) {
49 | return new $localClass($id, $target, $parameters);
50 | } elseif (class_exists($vendorClass)) {
51 | return new $vendorClass($id, $target, $parameters);
52 | }
53 |
54 | throw InvalidModificationArgument::modifcationClassNotFound($className);
55 | }
56 |
57 | /**
58 | * Validate the target.
59 | *
60 | * @param string $target
61 | *
62 | * @throws InvalidModificationTarget
63 | */
64 | protected static function validateTarget($target)
65 | {
66 | if (!in_array($target, self::ALLOWEDTARGETS)) {
67 | throw InvalidModificationArgument::targetNotAllowed($target);
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/Commands/MakeBundleMod.php:
--------------------------------------------------------------------------------
1 | setUp();
29 |
30 | $pathArray = ['LangBundler', 'Mods'];
31 |
32 | $basePath = app_path().DIRECTORY_SEPARATOR;
33 |
34 | $this->buildPath($pathArray, $basePath);
35 |
36 | $name = ucfirst($this->argument('name')).'Mod';
37 |
38 | $stub = $this->getStub($name);
39 |
40 | $this->filesystem->put(
41 | app_path(implode(DIRECTORY_SEPARATOR, $pathArray).DIRECTORY_SEPARATOR.$name.'.php'),
42 | $stub
43 | );
44 |
45 | $this->info('New bundle modification file successfully created!');
46 | }
47 |
48 | /**
49 | * Get stub and fill.
50 | *
51 | * @param string $name
52 | *
53 | * @return string
54 | */
55 | protected function getStub($name)
56 | {
57 | $namespace = Container::getInstance()->getNamespace();
58 |
59 | $namespace = $namespace.'LangBundler\\Mods';
60 |
61 | $stub = $this->filesystem->get(
62 | dirname(__DIR__).DIRECTORY_SEPARATOR.'BundleItems'.DIRECTORY_SEPARATOR.'ModStub.php');
63 |
64 | $stub = str_replace(
65 | 'LaravelLangBundler\BundleItems',
66 | $namespace,
67 | $stub
68 | );
69 |
70 | $stub = str_replace(
71 | 'ModStub',
72 | $name,
73 | $stub
74 | );
75 |
76 | return $stub;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/BundleItems/ItemWrapper.php:
--------------------------------------------------------------------------------
1 | target = $target;
33 |
34 | $this->wrapperParameters = $wrapperParameters;
35 | }
36 |
37 | /**
38 | * Get the set target.
39 | *
40 | * @return string
41 | */
42 | public function getAffect()
43 | {
44 | return $this->target;
45 | }
46 |
47 | /**
48 | * If target is key, get key from child. Otherwise, get from parent.
49 | *
50 | * @return string
51 | */
52 | public function getKey()
53 | {
54 | if ($this->target === 'key' || $this->target === 'both') {
55 | return $this->key($this->key);
56 | }
57 |
58 | return parent::getKey();
59 | }
60 |
61 | /**
62 | * If target is value, get value from child. Otherwise, get from parent.
63 | *
64 | * @return mixed
65 | */
66 | public function getValue()
67 | {
68 | if ($this->target === 'value' || $this->target === 'both') {
69 | return $this->value($this->value);
70 | }
71 |
72 | return parent::getValue();
73 | }
74 |
75 | /**
76 | * Alter key and return.
77 | *
78 | * @param string $key
79 | *
80 | * @return string
81 | */
82 | abstract public function key($key);
83 |
84 | /**
85 | * Alter value and return.
86 | *
87 | * @param mixed $value
88 | *
89 | * @return mixed
90 | */
91 | abstract public function value($value);
92 | }
93 |
--------------------------------------------------------------------------------
/tests/Unit/ItemFactoryTest.php:
--------------------------------------------------------------------------------
1 | assertInstanceOf(BundleItem::class, $bundleItem);
23 | }
24 |
25 | /**
26 | * @test
27 | */
28 | public function it_makes_mod_item_with_value()
29 | {
30 | $bundleItem = ItemFactory::build('id', 'value_strtoupper');
31 |
32 | $this->assertInstanceOf(StrtoupperMod::class, $bundleItem);
33 |
34 | $this->assertEquals('value', $bundleItem->getAffect());
35 | }
36 |
37 | /**
38 | * @test
39 | */
40 | public function it_makes_mod_item_with_key()
41 | {
42 | $bundleItem = ItemFactory::build('id', 'key_strtoupper');
43 |
44 | $this->assertInstanceOf(StrtoupperMod::class, $bundleItem);
45 |
46 | $this->assertEquals('key', $bundleItem->getAffect());
47 | }
48 |
49 | /**
50 | * @test
51 | */
52 | public function it_makes_mod_item_with_both()
53 | {
54 | $bundleItem = ItemFactory::build('id', 'both_strtoupper');
55 |
56 | $this->assertInstanceOf(StrtoupperMod::class, $bundleItem);
57 |
58 | $this->assertEquals('both', $bundleItem->getAffect());
59 | }
60 |
61 | /**
62 | * @test
63 | *
64 | * @expectedException LaravelLangBundler\Exceptions\InvalidModificationArgument
65 | * @expectedExceptionMessage Target invalid is not allowed. Allowed targets are 'key', 'value', and 'both'.
66 | */
67 | public function it_throws_exception_for_invalid_target_value()
68 | {
69 | $bundleItem = ItemFactory::build('id', 'invalid_strtoupper');
70 | }
71 |
72 | /**
73 | * @test
74 | *
75 | * @expectedException LaravelLangBundler\Exceptions\InvalidModificationArgument
76 | * @expectedExceptionMessage Class InvalidMod can not be found.
77 | */
78 | public function it_throws_exception_for_invalid_mod_name()
79 | {
80 | $bundleItem = ItemFactory::build('id', 'key_invalid');
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/tests/Unit/BundleItemTest.php:
--------------------------------------------------------------------------------
1 | copyStubs('bundle7');
19 |
20 | $this->copyTranslations();
21 |
22 | app()['config']->set('lang-bundler.global_key_namespace', 'translations');
23 |
24 | $bundle = new Bundle('bundles.bundle7', $this->bundleMap);
25 |
26 | foreach ($bundle->getValues() as $item) {
27 | $expected = 'translations.'.$item->getNamespace();
28 |
29 | $this->assertEquals($expected, $item->getId());
30 | }
31 | }
32 |
33 | /**
34 | * @test
35 | */
36 | public function it_transforms_keys()
37 | {
38 | $this->copyStubs('bundle5');
39 |
40 | $this->copyTranslations();
41 |
42 | app()['config']->set('lang-bundler.key_transform', 'studly_case');
43 |
44 | $bundle = new Bundle('bundles.bundle5', $this->bundleMap);
45 |
46 | foreach ($bundle->getValues() as $item) {
47 | $expected = studly_case($item->getNamespace());
48 |
49 | $this->assertEquals($expected, $item->getKey());
50 | }
51 | }
52 |
53 | /**
54 | * @test
55 | */
56 | public function it_ignores_parameters_with_different_namespaces()
57 | {
58 | $this->copyStubs('bundle8');
59 |
60 | $this->copyTranslations();
61 |
62 | $bundle = new Bundle('bundles.bundle8', $this->bundleMap);
63 |
64 | foreach ($bundle->getValues() as $item) {
65 | $parameters = [
66 | 'welcome_user.user' => 'Bob',
67 | 'message_to.user' => 'Sally',
68 | 'invite_from.user' => 'George',
69 | ];
70 |
71 | $item->setParameters($parameters);
72 |
73 | if (isset($parameters[$item->getKey().'.user'])) {
74 | $expected = $parameters[$item->getKey().'.user'];
75 |
76 | $this->assertEquals($expected, $item->getParameters()['user']);
77 | }
78 | }
79 | }
80 |
81 | /**
82 | * @test
83 | */
84 | public function it_sets_choice_if_namespaced_choice_value_passed_in_parameters()
85 | {
86 | $this->copyStubs('bundle8');
87 |
88 | $this->copyTranslations();
89 |
90 | $bundle = new Bundle('bundles.bundle8', $this->bundleMap);
91 |
92 | $item = $bundle->getValues()[3];
93 |
94 | $item->setParameters([
95 | 'inbox_status.choice' => 3,
96 | ]);
97 |
98 | $this->assertEquals(3, $item->hasChoice());
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/tests/Integration/IntegrationTest.php:
--------------------------------------------------------------------------------
1 | copyStubs('bundle2');
19 |
20 | $this->copyTranslations();
21 |
22 | $translations = app(LangBundler::class)->trans('bundles.bundle2.component1');
23 |
24 | $expected = $this->getExpected(['homeEn', 'navEn']);
25 |
26 | $this->assertEquals($expected, $translations->all());
27 | }
28 |
29 | /**
30 | * @test
31 | */
32 | public function bundles_can_be_accessed_from_helper()
33 | {
34 | $this->copyStubs('bundle2');
35 |
36 | $this->copyTranslations();
37 |
38 | $translations = transB('bundles.bundle2.component1');
39 |
40 | $expected = $this->getExpected(['homeEn', 'navEn']);
41 |
42 | $this->assertEquals($expected, $translations->all());
43 | }
44 |
45 | /**
46 | * @test
47 | */
48 | public function helper_function_with_no_arguments_returns_lang_bundler_class()
49 | {
50 | $langBundler = transB();
51 |
52 | $this->assertInstanceOf('LaravelLangBundler\LangBundler', $langBundler);
53 | }
54 |
55 | /**
56 | * @test
57 | */
58 | public function passing_a_normal_lang_value_to_helper_function_returns_the_translation()
59 | {
60 | $this->copyTranslations();
61 |
62 | $translation = transB('home.welcome');
63 |
64 | $this->assertEquals('Welcome', $translation);
65 | }
66 |
67 | /**
68 | * @test
69 | */
70 | public function parameters_can_be_sent_through_app_instance()
71 | {
72 | $this->copyStubs('bundle5');
73 |
74 | $this->copyTranslations();
75 |
76 | $translations = app(LangBundler::class)->trans(
77 | 'bundles.bundle5',
78 | ['user' => 'Bob', 'sender' => 'Sally']
79 | );
80 |
81 | $expected = [
82 | 'welcome_user' => 'Welcome Bob',
83 | 'message_from' => 'You have a message from Sally',
84 | ];
85 |
86 | $this->assertEquals($expected, $translations->all());
87 | }
88 |
89 | /**
90 | * @test
91 | */
92 | public function helper_function_accepts_parameters()
93 | {
94 | $this->copyStubs('bundle5');
95 |
96 | $this->copyTranslations();
97 |
98 | $translations = transB('bundles.bundle5', ['user' => 'Bob', 'sender' => 'Sally']);
99 |
100 | $expected = [
101 | 'welcome_user' => 'Welcome Bob',
102 | 'message_from' => 'You have a message from Sally',
103 | ];
104 |
105 | $this->assertEquals($expected, $translations->all());
106 | }
107 |
108 | /**
109 | * @test
110 | */
111 | public function helper_function_works_with_bundle_item_wrapper()
112 | {
113 | $this->copyStubs('bundle10');
114 |
115 | $this->copyTranslations();
116 |
117 | $translations = transB('bundle10')->take(4);
118 |
119 | $expected = $this->getExpected('bundle10');
120 |
121 | $this->assertEquals($expected, $translations->all());
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/tests/TestCase.php:
--------------------------------------------------------------------------------
1 | register(ServiceProvider::class);
38 |
39 | $app->make(Kernel::class)->bootstrap();
40 |
41 | return $app;
42 | }
43 |
44 | /**
45 | * Setup DB and test variables before each test.
46 | */
47 | protected function setUp()
48 | {
49 | $filesystem = new Filesystem();
50 |
51 | $configDir = __DIR__.'./../src/config.php';
52 |
53 | $configTarget = __DIR__.'./../vendor/laravel/laravel/config/lang-bundler.php';
54 |
55 | $filesystem->copy($configDir, $configTarget);
56 |
57 | parent::setUp();
58 |
59 | $this->bundleMap = new BundleMap();
60 |
61 | $this->translator = new Translator();
62 |
63 | if (!file_exists(resource_path('lang'))) {
64 | $filesystem->makeDirectory(resource_path('lang'));
65 | }
66 | }
67 |
68 | /**
69 | * Teardown after each class.
70 | */
71 | protected function tearDown()
72 | {
73 | $filesystem = new Filesystem();
74 |
75 | $filesystem->deleteDirectory(resource_path('lang'));
76 |
77 | $filesystem->delete(config_path('lang-bundler.php'));
78 |
79 | $filesystem->deleteDirectory(app_path('LangBundler'));
80 |
81 | parent::tearDown();
82 | }
83 |
84 | /**
85 | * Copy stubs to vendor Laravel app lang directory.
86 | *
87 | * @param string|array $stubs
88 | */
89 | protected function copyStubs($stubs)
90 | {
91 | if (!is_array($stubs)) {
92 | $stubs = [$stubs];
93 | }
94 |
95 | $filesystem = new Filesystem();
96 |
97 | $filesystem->makeDirectory(resource_path('lang/bundles/'));
98 |
99 | foreach ($stubs as $stub) {
100 | $stubPath = __DIR__.'/stubs/'.$stub;
101 |
102 | if (is_dir($stubPath)) {
103 | $filesystem->copyDirectory(
104 | $stubPath,
105 | resource_path('lang/bundles/'.$stub)
106 | );
107 | } else {
108 | $target = resource_path('lang/bundles/'.$stub.'.php');
109 |
110 | $stubPath = $stubPath.'.php';
111 |
112 | if (file_exists($stubPath)) {
113 | $filesystem->copy($stubPath, $target);
114 | }
115 | }
116 | }
117 | }
118 |
119 | /**
120 | * Copy translation files into vendor Laravel app.
121 | */
122 | protected function copyTranslations()
123 | {
124 | $filesystem = new Filesystem();
125 |
126 | if (!file_exists(resource_path('lang/en/'))) {
127 | $filesystem->makeDirectory(resource_path('lang/en/'));
128 | }
129 |
130 | if (!file_exists(resource_path('lang/ja/'))) {
131 | $filesystem->makeDirectory(resource_path('lang/ja/'));
132 | }
133 |
134 | $translations = [
135 | 'en' => __DIR__.'/stubs/en/',
136 | 'ja' => __DIR__.'/stubs/ja/',
137 | ];
138 |
139 | foreach ($translations as $name => $translation) {
140 | $target = resource_path('lang/'.$name);
141 |
142 | $filesystem->copyDirectory($translation, $target);
143 | }
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/src/Bundle/BundleMap.php:
--------------------------------------------------------------------------------
1 | bundleMap;
31 | }
32 |
33 | /**
34 | * Get auto-alias array.
35 | *
36 | * @return array
37 | */
38 | public function getAutoAliases()
39 | {
40 | return $this->autoAliases;
41 | }
42 |
43 | /**
44 | * Return true if bundleMap is empty.
45 | *
46 | * @return bool
47 | */
48 | public function bundleMapIsEmpty()
49 | {
50 | return empty($this->bundleMap);
51 | }
52 |
53 | /**
54 | * Get trans values for path keys.
55 | *
56 | * @param array $pathKeys
57 | *
58 | * @return Collection
59 | */
60 | public function getBundleValues(array $pathKeys)
61 | {
62 | $this->mapBundles();
63 |
64 | $temp = &$this->bundleMap;
65 |
66 | foreach ($pathKeys as $key) {
67 | $temp = &$temp[$key];
68 | }
69 |
70 | return collect($temp);
71 | }
72 |
73 | /**
74 | * Get all the lang bundle files from the bundles directory.
75 | *
76 | * @return array
77 | */
78 | public function mapBundles()
79 | {
80 | if (!empty($this->bundleMap)) {
81 | return $this->getBundleMap();
82 | }
83 |
84 | $pathCollection = $this->getPathCollection();
85 |
86 | foreach ($pathCollection as $path) {
87 | $content = include $path;
88 |
89 | $pathKeys = $this->getPathKeys($path);
90 |
91 | $this->registerAlias(collect($pathKeys));
92 |
93 | $this->mapContent($content, $pathKeys);
94 | }
95 |
96 | return $this->getBundleMap();
97 | }
98 |
99 | /**
100 | * Get paths to all bundle files.
101 | *
102 | * @return Collection
103 | */
104 | protected function getPathCollection()
105 | {
106 | $bundlePath = resource_path('lang/bundles');
107 |
108 | if (!file_exists($bundlePath)) {
109 | return collect([]);
110 | }
111 |
112 | $directory = new \RecursiveDirectoryIterator($bundlePath);
113 |
114 | $iterator = new \RecursiveIteratorIterator($directory);
115 |
116 | $paths = new \RegexIterator(
117 | $iterator,
118 | '/^.+\.php$/i',
119 | \RecursiveRegexIterator::GET_MATCH
120 | );
121 |
122 | return collect(iterator_to_array($paths))->flatten();
123 | }
124 |
125 | /**
126 | * Get array of keys describing file path.
127 | *
128 | * @param string $path
129 | *
130 | * @return array
131 | */
132 | protected function getPathKeys($path)
133 | {
134 | $key = str_replace('.php', '', explode(DIRECTORY_SEPARATOR.'bundles'.DIRECTORY_SEPARATOR, $path)[1]);
135 |
136 | return explode('/', $key);
137 | }
138 |
139 | /**
140 | * Register file paths as auto aliases.
141 | *
142 | * @param Collection $pathKeys
143 | */
144 | protected function registerAlias(Collection $pathKeys)
145 | {
146 | $className = $pathKeys->last();
147 |
148 | $path = $pathKeys->implode('.');
149 |
150 | $this->autoAliases[$path] = $className;
151 | }
152 |
153 | /**
154 | * Map content on bundleMap.
155 | *
156 | * @param array $content
157 | * @param array $pathKeys
158 | */
159 | protected function mapContent(array $content, array $pathKeys)
160 | {
161 | $temp = &$this->bundleMap;
162 |
163 | foreach ($pathKeys as $key) {
164 | $temp = &$temp[$key];
165 | }
166 |
167 | $temp = $content;
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/tests/Unit/BundleItemModTest.php:
--------------------------------------------------------------------------------
1 | copyStubs('bundle10');
21 |
22 | $bundle = new Bundle('bundle10', $this->bundleMap);
23 |
24 | foreach ($bundle->getValues() as $key => $value) {
25 | if ($key > 2) {
26 | break;
27 | }
28 |
29 | $this->assertInstanceOf(CallbackMod::class, $value);
30 | }
31 | }
32 |
33 | /**
34 | * @test
35 | */
36 | public function parameters_can_still_be_passed_to_transb()
37 | {
38 | extract($this->testMod(['user' => 'Bob']));
39 |
40 | $this->assertEquals('Welcome Bob', $values[0]);
41 |
42 | $this->assertEquals('YOU SENT A MESSAGE TO BOB', $values[1]);
43 |
44 | $this->assertEquals('You have an invite from Bob', $values[2]);
45 | }
46 |
47 | /**
48 | * @test
49 | */
50 | public function mod_callback_transforms_keys()
51 | {
52 | extract($this->testMod());
53 |
54 | $this->assertEquals('Welcome_user', $keys[0]);
55 |
56 | $this->assertEquals('message_to', $keys[1]);
57 |
58 | $this->assertEquals('InviteFrom', $keys[2]);
59 | }
60 |
61 | /**
62 | * @test
63 | */
64 | public function mod_callback_transforms_values()
65 | {
66 | extract($this->testMod());
67 |
68 | $this->assertEquals('Welcome :user', $values[0]);
69 |
70 | $this->assertEquals('YOU SENT A MESSAGE TO :USER', $values[1]);
71 |
72 | $this->assertEquals('You have an invite from :user', $values[2]);
73 | }
74 |
75 | /**
76 | * @test
77 | */
78 | public function mod_callback_transforms_both()
79 | {
80 | extract($this->testMod());
81 |
82 | $this->assertEquals('MESSAGE_TO', $keys[5]);
83 |
84 | $this->assertEquals('YOU SENT A MESSAGE TO :USER', $values[5]);
85 | }
86 |
87 | /**
88 | * @test
89 | */
90 | public function mods_can_be_read_from_app_directory()
91 | {
92 | Artisan::call('langb:mod', ['name' => 'test']);
93 |
94 | $path = app_path('LangBundler/Mods/Bin2hexMod.php');
95 |
96 | $stub = file_get_contents(__DIR__.'/../stubs/Bin2hexMod.php');
97 |
98 | file_put_contents($path, $stub);
99 |
100 | $this->copyStubs('bin2hex');
101 |
102 | $this->copyTranslations();
103 |
104 | $bundle = new Bundle('bin2hex', $this->bundleMap);
105 |
106 | $this->translator->translateBundle($bundle);
107 |
108 | $this->assertEquals(
109 | '77656c636f6d655f75736572',
110 | $bundle->getValues()[0]->getKey()
111 | );
112 | }
113 |
114 | /**
115 | * @test
116 | */
117 | public function mod_change_works()
118 | {
119 | extract($this->testMod());
120 |
121 | $this->assertEquals('newKey', $keys[3]);
122 | }
123 |
124 | /**
125 | * @test
126 | */
127 | public function mod_values_works()
128 | {
129 | extract($this->testMod());
130 |
131 | $expected = $this->getExpected('months');
132 |
133 | $this->assertEquals($expected, $values[4]);
134 | }
135 |
136 | /**
137 | * @test
138 | */
139 | public function mod_ucfirst_works()
140 | {
141 | extract($this->testMod());
142 |
143 | $this->assertEquals('Lowercase string', $values[6]);
144 | }
145 |
146 | /**
147 | * @test
148 | */
149 | public function mod_strtoupper_works()
150 | {
151 | extract($this->testMod());
152 |
153 | $this->assertEquals('LOWERCASE STRING', $values[7]);
154 | }
155 |
156 | /**
157 | * @test
158 | */
159 | public function mod_explode_works()
160 | {
161 | extract($this->testMod());
162 |
163 | $this->assertEquals(['lowercase', 'string'], $values[8]);
164 | }
165 |
166 | /**
167 | * @test
168 | */
169 | public function mod_strtolower_works()
170 | {
171 | extract($this->testMod());
172 |
173 | $this->assertEquals('uppersace string', $values[9]);
174 | }
175 |
176 | /**
177 | * Run the mod test and return keys and values.
178 | *
179 | * @return array
180 | */
181 | public function testMod($parameters = [])
182 | {
183 | $this->copyStubs('bundle10');
184 |
185 | $this->copyTranslations();
186 |
187 | $bundle = new Bundle('bundle10', $this->bundleMap);
188 |
189 | $this->translator->translateBundle($bundle, $parameters);
190 |
191 | $keys = $bundle->getValues()->map(function ($value) {
192 | return $value->getKey();
193 | });
194 |
195 | $values = $bundle->getValues()->map(function ($value) {
196 | return $value->getValue();
197 | });
198 |
199 | return ['keys' => $keys, 'values' => $values];
200 | }
201 | }
202 |
--------------------------------------------------------------------------------
/src/Bundle/Bundle.php:
--------------------------------------------------------------------------------
1 | id = $id;
61 | $this->path = $id;
62 |
63 | $this->bundleMap = $bundleMap;
64 |
65 | $this->getValuesFromMap();
66 | }
67 |
68 | /**
69 | * Get bundle namespace.
70 | *
71 | * @return string
72 | */
73 | public function getNamespace()
74 | {
75 | return $this->namespace;
76 | }
77 |
78 | /**
79 | * Get pathKeys array.
80 | *
81 | * @return array
82 | */
83 | public function getPathKeys()
84 | {
85 | return $this->pathKeys;
86 | }
87 |
88 | /**
89 | * Get path values collection.
90 | *
91 | * @return Collection
92 | */
93 | public function getValues()
94 | {
95 | return $this->values;
96 | }
97 |
98 | /**
99 | * Return array of values.
100 | *
101 | * @return array
102 | */
103 | public function getValuesArray()
104 | {
105 | return $this->values->all();
106 | }
107 |
108 | /**
109 | * Return true if bundle contains no trans values.
110 | *
111 | * @return bool
112 | */
113 | public function hasNoValues()
114 | {
115 | return $this->values->isEmpty();
116 | }
117 |
118 | /**
119 | * Return true if namespace is valid bundle namespace.
120 | *
121 | * @return bool
122 | */
123 | public function hasValidNamespace()
124 | {
125 | return $this->getNamespace() === 'bundles';
126 | }
127 |
128 | /**
129 | * Set the namespace on the object.
130 | *
131 | * @param string $namespace
132 | */
133 | protected function setNamespace($namespace)
134 | {
135 | $this->namespace = $namespace;
136 | }
137 |
138 | /**
139 | * Set pathKeys on object.
140 | *
141 | * @param array $pathKeys
142 | */
143 | protected function setPathKeys(array $pathKeys)
144 | {
145 | $this->pathKeys = $pathKeys;
146 | }
147 |
148 | /**
149 | * Set values collection on object.
150 | *
151 | * @param Collection $values
152 | *
153 | * @return Collection
154 | */
155 | protected function setValues(Collection $values)
156 | {
157 | return $this->values = $values->map(function ($value) {
158 | if (!$value instanceof BundleItem) {
159 | return ItemFactory::build($value);
160 | }
161 |
162 | return $value;
163 | });
164 | }
165 |
166 | /**
167 | * Get bundle values from bundle map.
168 | *
169 | * @return Collection
170 | */
171 | protected function getValuesFromMap()
172 | {
173 | if ($this->bundleMap->bundleMapIsEmpty()) {
174 | $this->bundleMap->mapBundles();
175 | }
176 |
177 | $this->buildKeys();
178 |
179 | if (!$this->hasValidNamespace()) {
180 | $this->setValues(collect([]));
181 | } else {
182 | $values = $this->bundleMap->getBundleValues($this->getPathKeys());
183 |
184 | $this->setValues($values);
185 | }
186 | }
187 |
188 | /**
189 | * Build pathKeys array and set namespace.
190 | */
191 | protected function buildKeys()
192 | {
193 | $pathKeys = $this->getKeysFromId();
194 |
195 | $this->setNamespace(array_shift($pathKeys));
196 |
197 | $this->setPathKeys($pathKeys);
198 | }
199 |
200 | /**
201 | * Get keys from id.
202 | *
203 | * @return array
204 | */
205 | protected function getKeysFromId()
206 | {
207 | $aliases = config('lang-bundler.aliases');
208 |
209 | $autoAliases = collect($this->bundleMap->getAutoAliases())
210 | ->filter(function ($value) {
211 | return $value === $this->id;
212 | });
213 |
214 | if (in_array($this->id, array_keys($aliases))) {
215 | $this->path = $aliases[$this->id];
216 | } elseif ($autoAliases->count() === 1) {
217 | $this->path = 'bundles.'.$autoAliases->keys()[0];
218 | }
219 |
220 | return explode('.', $this->path);
221 | }
222 | }
223 |
--------------------------------------------------------------------------------
/src/BundleItems/BundleItem.php:
--------------------------------------------------------------------------------
1 | setNamespace($id);
57 |
58 | $this->setKey($namespace);
59 |
60 | $this->setId($id);
61 | }
62 |
63 | /**
64 | * Return the value of choice. If not null, trans_choice will be called.
65 | *
66 | * @return int|Countable|null
67 | */
68 | public function hasChoice()
69 | {
70 | return $this->choice;
71 | }
72 |
73 | /**
74 | * Return the translation key for return array.
75 | *
76 | * @return string
77 | */
78 | public function getKey()
79 | {
80 | return $this->key;
81 | }
82 |
83 | /**
84 | * Get the Laravel lang id of translation.
85 | *
86 | * @return string
87 | */
88 | public function getId()
89 | {
90 | return $this->id;
91 | }
92 |
93 | /**
94 | * Return the namespace for the translation.
95 | *
96 | * @return string
97 | */
98 | public function getNamespace()
99 | {
100 | return $this->namespace;
101 | }
102 |
103 | /**
104 | * Return array of valid parameters.
105 | *
106 | * @return array
107 | */
108 | public function getParameters()
109 | {
110 | return $this->parameters->all();
111 | }
112 |
113 | /**
114 | * Return the final key/value pair array.
115 | *
116 | * @return array
117 | */
118 | public function getReturnArray()
119 | {
120 | return [$this->getKey() => $this->getValue()];
121 | }
122 |
123 | /**
124 | * Return the value.
125 | *
126 | * @return mixed
127 | */
128 | public function getValue()
129 | {
130 | return $this->value;
131 | }
132 |
133 | /**
134 | * Set choice value on object.
135 | *
136 | * @param int|Countable $value
137 | */
138 | public function setChoice($value)
139 | {
140 | $this->choice = $value;
141 | }
142 |
143 | /**
144 | * Set only valid parameters. If namespaced, only parameters with
145 | * translation namespace will be set.
146 | *
147 | * @param array $parameters
148 | */
149 | public function setParameters($parameters)
150 | {
151 | $this->parameters = collect($parameters)->mapWithKeys(function ($value, $key) {
152 | if (!$key = $this->getNamespacedKey($key)) {
153 | return [];
154 | }
155 |
156 | if ($key === 'choice') {
157 | $this->setChoice($value);
158 | }
159 |
160 | return [$key => $value];
161 | });
162 | }
163 |
164 | /**
165 | * Get only global and keys with this item's namespace.
166 | *
167 | * @param string $key
168 | *
169 | * @return string|null
170 | */
171 | protected function getNamespacedKey($key)
172 | {
173 | $keyArray = explode('.', $key);
174 |
175 | if (count($keyArray) !== 2) {
176 | return $key;
177 | } elseif ($keyArray[0] === $this->getNamespace()) {
178 | return $keyArray[1];
179 | }
180 | }
181 |
182 | /**
183 | * Set the lang value on the object.
184 | *
185 | * @param mixed $value
186 | */
187 | public function setValue($value)
188 | {
189 | $this->value = $value;
190 |
191 | return $this;
192 | }
193 |
194 | /**
195 | * Set the translation namespace on the object.
196 | */
197 | protected function setNamespace($id)
198 | {
199 | return $this->namespace = collect(explode('.', $id))->last();
200 | }
201 |
202 | /**
203 | * Get key for translation value.
204 | *
205 | * @return string
206 | */
207 | protected function setKey($namespace)
208 | {
209 | $transformMethod = config('lang-bundler.key_transform');
210 |
211 | if ($transformMethod === 'none') {
212 | return $this->key = $namespace;
213 | }
214 |
215 | return $this->key = $transformMethod($namespace);
216 | }
217 |
218 | /**
219 | * Prefix the translation id with global_key_namespace, if set.
220 | *
221 | * @param string $id
222 | *
223 | * @return string
224 | */
225 | protected function setId($id)
226 | {
227 | $prefix = config('lang-bundler.global_key_namespace');
228 |
229 | if (!empty($prefix)) {
230 | $id = $prefix.'.'.$id;
231 | }
232 |
233 | $this->id = $id;
234 | }
235 | }
236 |
--------------------------------------------------------------------------------
/tests/Integration/TranslatorTest.php:
--------------------------------------------------------------------------------
1 | copyStubs('bundle2');
19 |
20 | $this->copyTranslations();
21 |
22 | $bundle = new Bundle('bundles.bundle2.component1', $this->bundleMap);
23 |
24 | $translations = $this->translator->translateBundle($bundle);
25 |
26 | $expected = $this->getExpected(['homeEn', 'navEn']);
27 |
28 | $this->assertEquals($expected, $translations->all());
29 | }
30 |
31 | /**
32 | * @test
33 | */
34 | public function it_translates_bundle_values_with_set_locale()
35 | {
36 | $this->copyStubs('bundle2');
37 |
38 | $this->copyTranslations();
39 |
40 | app()->setLocale('ja');
41 |
42 | $bundle = new Bundle('bundles.bundle2.component1', $this->bundleMap);
43 |
44 | $translations = $this->translator->translateBundle($bundle);
45 |
46 | $expected = $this->getExpected(['homeJa', 'navJa']);
47 |
48 | $this->assertEquals($expected, $translations->all());
49 | }
50 |
51 | /**
52 | * @test
53 | */
54 | public function it_accepts_parameters()
55 | {
56 | $this->copyStubs('bundle5');
57 |
58 | $this->copyTranslations();
59 |
60 | $bundle = new Bundle('bundles.bundle5', $this->bundleMap);
61 |
62 | $translations = $this->translator->translateBundle(
63 | $bundle,
64 | ['user' => 'Bob', 'sender' => 'Sally']
65 | );
66 |
67 | $expected = [
68 | 'welcome_user' => 'Welcome Bob',
69 | 'message_from' => 'You have a message from Sally',
70 | ];
71 |
72 | $this->assertEquals($expected, $translations->all());
73 | }
74 |
75 | /**
76 | * @test
77 | */
78 | public function parameters_can_be_namespaced()
79 | {
80 | $this->copyStubs('bundle8');
81 |
82 | $this->copyTranslations();
83 |
84 | $bundle = new Bundle('bundles.bundle8', $this->bundleMap);
85 |
86 | $translations = $this->translator->translateBundle($bundle, [
87 | 'welcome_user.user' => 'Bob',
88 | 'message_to.user' => 'Sally',
89 | 'invite_from.user' => 'George',
90 | ]);
91 |
92 | $expected = [
93 | 'welcome_user' => 'Welcome Bob',
94 | 'message_to' => 'You sent a message to Sally',
95 | 'invite_from' => 'You have an invite from George',
96 | ];
97 |
98 | $this->assertArraySubset($expected, $translations->all());
99 | }
100 |
101 | /**
102 | * @test
103 | */
104 | public function it_transforms_keys_to_study_case()
105 | {
106 | $expected = [
107 | 'WelcomeUser' => 'Welcome Bob',
108 | 'MessageFrom' => 'You have a message from Sally',
109 | ];
110 |
111 | $this->transformTest('studly_case', $expected);
112 | }
113 |
114 | /**
115 | * @test
116 | */
117 | public function it_transforms_keys_to_camel_case()
118 | {
119 | $expected = [
120 | 'welcomeUser' => 'Welcome Bob',
121 | 'messageFrom' => 'You have a message from Sally',
122 | ];
123 |
124 | $this->transformTest('camel_case', $expected);
125 | }
126 |
127 | /**
128 | * @test
129 | */
130 | public function it_transforms_keys_to_snake_case()
131 | {
132 | $expected = [
133 | 'welcome_user' => 'Welcome Bob',
134 | 'message_from' => 'You have a message from Sally',
135 | ];
136 |
137 | $this->transformTest('snake_case', $expected, 'bundle6');
138 | }
139 |
140 | /**
141 | * @test
142 | */
143 | public function it_adds_a_key_prefix()
144 | {
145 | $this->copyStubs('bundle7');
146 |
147 | $this->copyTranslations();
148 |
149 | app()['config']->set('lang-bundler.global_key_namespace', 'translations');
150 |
151 | $bundle = new Bundle('bundles.bundle7', $this->bundleMap);
152 |
153 | $translations = $this->translator->translateBundle($bundle);
154 |
155 | $expected = $this->getExpected('bundle7');
156 |
157 | $this->assertEquals($expected, $translations->all());
158 | }
159 |
160 | /**
161 | * Perform key transformation test.
162 | *
163 | * @param string $case
164 | * @param array $expected
165 | * @param string $bundle
166 | */
167 | protected function transformTest($case, $expected, $bundleName = 'bundle5')
168 | {
169 | $this->copyStubs($bundleName);
170 |
171 | $this->copyTranslations();
172 |
173 | app()['config']->set('lang-bundler.key_transform', $case);
174 |
175 | $bundle = new Bundle('bundles.'.$bundleName, $this->bundleMap);
176 |
177 | $translations = $this->translator->translateBundle(
178 | $bundle,
179 | ['user' => 'Bob', 'sender' => 'Sally']
180 | );
181 |
182 | $this->assertEquals($expected, $translations->all());
183 | }
184 |
185 | /**
186 | * @test
187 | */
188 | public function if_choice_is_not_null_trans_choice_is_run()
189 | {
190 | $this->copyStubs('bundle8');
191 |
192 | $this->copyTranslations();
193 |
194 | $bundle = new Bundle('bundles.bundle8', $this->bundleMap);
195 |
196 | $translations = $this->translator->translateBundle(
197 | $bundle,
198 | ['user' => 'Bob', 'inbox_status.choice' => 3]
199 | );
200 |
201 | $this->assertEquals('You have new messages', $translations['inbox_status']);
202 | }
203 | }
204 |
--------------------------------------------------------------------------------
/tests/Unit/BundleMapTest.php:
--------------------------------------------------------------------------------
1 | bundleMap->mapBundles();
19 |
20 | $this->assertEquals([], $map);
21 | }
22 |
23 | /**
24 | * @test
25 | */
26 | public function it_maps_a_single_dimension_array()
27 | {
28 | $this->copyStubs('bundle1');
29 |
30 | $map = $this->bundleMap->mapBundles();
31 |
32 | $expected = $this->getExpected('bundle1');
33 |
34 | $this->assertEquals($expected, $map);
35 | }
36 |
37 | /**
38 | * @test
39 | */
40 | public function it_maps_a_multidimensional_array()
41 | {
42 | $this->copyStubs('bundle2');
43 |
44 | $map = $this->bundleMap->mapBundles();
45 |
46 | $expected = $this->getExpected('bundle2');
47 |
48 | $this->assertEquals($expected, $map);
49 | }
50 |
51 | /**
52 | * @test
53 | */
54 | public function it_maps_multiple_files()
55 | {
56 | $bundles = ['bundle1', 'bundle2'];
57 |
58 | $this->copyStubs($bundles);
59 |
60 | $map = $this->bundleMap->mapBundles();
61 |
62 | $expected = $this->getExpected($bundles);
63 |
64 | $this->assertEquals($expected, $map);
65 | }
66 |
67 | /**
68 | * @test
69 | */
70 | public function it_maps_layered_directories()
71 | {
72 | $this->copyStubs('components');
73 |
74 | $map = $this->bundleMap->mapBundles();
75 |
76 | $expected = [
77 | 'components' => [
78 | 'sub-components' => $this->getExpected('bundle4'),
79 | 'bundle3' => $this->getExpected('bundle3')['bundle3'],
80 | ],
81 | ];
82 |
83 | $this->assertEquals($expected, $map);
84 | }
85 |
86 | /**
87 | * @test
88 | */
89 | public function it_gets_values_for_a_single_dimension_array()
90 | {
91 | $this->copyStubs('bundle1');
92 |
93 | $bundle = new Bundle('bundles.bundle1', $this->bundleMap);
94 |
95 | $values = $this->bundleMap->getBundleValues($bundle->getPathKeys())->all();
96 |
97 | $expected = $this->getExpected('bundle1', true);
98 |
99 | $this->assertEquals($expected, $values);
100 | }
101 |
102 | /**
103 | * @test
104 | */
105 | public function it_gets_values_for_a_multidimensional_array()
106 | {
107 | $this->copyStubs('bundle2');
108 |
109 | $bundle = new Bundle('bundles.bundle2.component2', $this->bundleMap);
110 |
111 | $values = $this->bundleMap->getBundleValues($bundle->getPathKeys())->all();
112 |
113 | $expected = $this->getExpected('bundle2', true)['component2'];
114 |
115 | $this->assertEquals($expected, $values);
116 | }
117 |
118 | /**
119 | * @test
120 | */
121 | public function it_gets_values_when_multiple_files_present()
122 | {
123 | $this->copyStubs(['bundle1', 'bundle2']);
124 |
125 | $bundle = new Bundle('bundles.bundle2.component1', $this->bundleMap);
126 |
127 | $values = $this->bundleMap->getBundleValues($bundle->getPathKeys())->all();
128 |
129 | $expected = $this->getExpected('bundle2', true)['component1'];
130 |
131 | $this->assertEquals($expected, $values);
132 | }
133 |
134 | /**
135 | * @test
136 | */
137 | public function it_gets_values_from_within_directories()
138 | {
139 | $this->copyStubs('components');
140 |
141 | $bundle = new Bundle('bundles.components.bundle3.forum.component3', $this->bundleMap);
142 |
143 | $values = $this->bundleMap->getBundleValues($bundle->getPathKeys())->all();
144 |
145 | $expected = $this->getExpected('bundle3', true)['forum']['component3'];
146 |
147 | $this->assertEquals($expected, $values);
148 | }
149 |
150 | /**
151 | * @test
152 | */
153 | public function it_gets_values_from_within_layed_directories()
154 | {
155 | $this->copyStubs('components');
156 |
157 | $bundle = new Bundle('bundles.components.sub-components.bundle4', $this->bundleMap);
158 |
159 | $values = $this->bundleMap->getBundleValues($bundle->getPathKeys())->all();
160 |
161 | $expected = $this->getExpected('bundle4', true);
162 |
163 | $this->assertEquals($expected, $values);
164 | }
165 |
166 | /**
167 | * @test
168 | */
169 | public function invalid_bundle_name_returns_empty_array()
170 | {
171 | $this->copyStubs('components');
172 |
173 | $bundle = new Bundle('bundles.components.none', $this->bundleMap);
174 |
175 | $values = $this->bundleMap->getBundleValues($bundle->getPathKeys())->all();
176 |
177 | $this->assertEquals([], $values);
178 | }
179 |
180 | /**
181 | * @test
182 | */
183 | public function it_finds_bundles_with_registered_alias()
184 | {
185 | $this->copyStubs('bundle2');
186 |
187 | app()['config']->set('lang-bundler.aliases', [
188 | 'test' => 'bundles.bundle2.component1',
189 | ]);
190 |
191 | $bundle = new Bundle('test', $this->bundleMap);
192 |
193 | $values = $this->bundleMap->getBundleValues($bundle->getPathKeys())->all();
194 |
195 | $expected = $this->getExpected('bundle2', true)['component1'];
196 |
197 | $this->assertEquals($expected, $values);
198 | }
199 |
200 | /**
201 | * @test
202 | */
203 | public function it_finds_bundles_from_auto_registered_alias()
204 | {
205 | $this->copyStubs('components');
206 |
207 | $bundle = new Bundle('bundle4', $this->bundleMap);
208 |
209 | $values = $this->bundleMap->getBundleValues($bundle->getPathKeys())->all();
210 |
211 | $expected = $this->getExpected('bundle4', true);
212 |
213 | $this->assertEquals($expected, $values);
214 | }
215 | }
216 |
--------------------------------------------------------------------------------
/tests/stubs/ExpectedResults.php:
--------------------------------------------------------------------------------
1 | {$bundles}()[$bundles];
18 | }
19 |
20 | if (!is_array($bundles)) {
21 | $bundles = [$bundles];
22 | }
23 |
24 | return $this->mergeBundles($bundles);
25 | }
26 |
27 | /**
28 | * Merge bundles into single array.
29 | *
30 | * @param array $bundles
31 | *
32 | * @return array
33 | */
34 | private function mergeBundles(array $bundles)
35 | {
36 | $expected = [];
37 |
38 | foreach ($bundles as $bundle) {
39 | $expected = array_merge($expected, $this->{$bundle}());
40 | }
41 |
42 | return $expected;
43 | }
44 |
45 | /**
46 | * Expected results for bundle1 stub.
47 | *
48 | * @return array
49 | */
50 | private function bundle1()
51 | {
52 | return [
53 | 'bundle1' => [
54 | 'home.welcome',
55 | 'home.signup',
56 | 'home.login',
57 | 'nav.home',
58 | 'nav.top',
59 | ],
60 | ];
61 | }
62 |
63 | /**
64 | * Expected results for bundle2 stub.
65 | *
66 | * @return array
67 | */
68 | private function bundle2()
69 | {
70 | return [
71 | 'bundle2' => [
72 | 'component1' => [
73 | 'home.welcome',
74 | 'home.signup',
75 | 'home.login',
76 | 'nav.home',
77 | 'nav.top',
78 | ],
79 |
80 | 'component2' => [
81 | 'home.welcome',
82 | 'home.signup',
83 | 'home.login',
84 | 'nav.home',
85 | 'nav.top',
86 | ],
87 | ],
88 | ];
89 | }
90 |
91 | /**
92 | * Expected results for bundle3 stub.
93 | *
94 | * @return array
95 | */
96 | private function bundle3()
97 | {
98 | return [
99 | 'bundle3' => [
100 | 'component1' => [
101 | 'home.welcome',
102 | 'home.signup',
103 | 'home.login',
104 | 'nav.home',
105 | 'nav.top',
106 | ],
107 |
108 | 'forum' => [
109 | 'component2' => [
110 | 'home.welcome',
111 | 'home.signup',
112 | 'home.login',
113 | 'nav.home',
114 | 'nav.top',
115 | ],
116 |
117 | 'component3' => [
118 | 'payment.creditcard',
119 | 'payment.date',
120 | 'payment.submit',
121 | ],
122 | ],
123 | ],
124 | ];
125 | }
126 |
127 | /**
128 | * Expected results for bundle4 stub.
129 | *
130 | * @return array
131 | */
132 | private function bundle4()
133 | {
134 | return [
135 | 'bundle4' => [
136 | 'home.welcome',
137 | 'home.signup',
138 | 'home.login',
139 | 'nav.home',
140 | 'nav.top',
141 | ],
142 | ];
143 | }
144 |
145 | /**
146 | * Expected results for English home translations.
147 | *
148 | * @return array
149 | */
150 | private function homeEn()
151 | {
152 | return [
153 | 'welcome' => 'Welcome',
154 | 'signup' => 'Signup',
155 | 'login' => 'Login',
156 | ];
157 | }
158 |
159 | /**
160 | * Expected results for English nav translations.
161 | *
162 | * @return array
163 | */
164 | private function navEn()
165 | {
166 | return [
167 | 'home' => 'Home',
168 | 'top' => 'Top',
169 | ];
170 | }
171 |
172 | /**
173 | * Expected results for English home translations.
174 | *
175 | * @return array
176 | */
177 | private function homeJa()
178 | {
179 | return [
180 | 'welcome' => 'ようこそ',
181 | 'signup' => 'サインアップ',
182 | 'login' => 'ログイン',
183 | ];
184 | }
185 |
186 | /**
187 | * Expected results for English nav translations.
188 | *
189 | * @return array
190 | */
191 | private function navJa()
192 | {
193 | return [
194 | 'home' => 'ホーム',
195 | 'top' => 'トップ',
196 | ];
197 | }
198 |
199 | /**
200 | * Expected results for bundle7 translations.
201 | *
202 | * @return array
203 | */
204 | private function bundle7()
205 | {
206 | return [
207 | 'welcome' => 'Welcome',
208 | 'signup' => 'Signup',
209 | 'login' => 'Login',
210 | 'home' => 'Home',
211 | 'top' => 'Top',
212 | ];
213 | }
214 |
215 | /**
216 | * Expected results for bundle10 translations.
217 | *
218 | * @return array
219 | */
220 | private function bundle10()
221 | {
222 | return [
223 | 'Welcome_user' => 'Welcome :user',
224 | 'message_to' => 'YOU SENT A MESSAGE TO :USER',
225 | 'InviteFrom' => 'You have an invite from :user',
226 | 'newKey' => 'You have an invite from :user',
227 | ];
228 | }
229 |
230 | /**
231 | * Expected results for months translations.
232 | *
233 | * @return array
234 | */
235 | private function months()
236 | {
237 | return array_values([
238 | 'january' => 'Jan',
239 | 'february' => 'Feb',
240 | 'march' => 'March',
241 | 'april' => 'April',
242 | 'may' => 'May',
243 | 'june' => 'June',
244 | 'july' => 'July',
245 | 'august' => 'Aug',
246 | 'september' => 'Sept',
247 | 'october' => 'Oct',
248 | 'november' => 'Nov',
249 | 'december' => 'Dec',
250 | ]);
251 | }
252 | }
253 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Laravel Lang Bundler
2 | [](//packagist.org/packages/zachleigh/laravel-lang-bundler)
3 | [](//packagist.org/packages/zachleigh/laravel-lang-bundler)
4 | [](https://travis-ci.org/zachleigh/laravel-lang-bundler)
5 | [](https://scrutinizer-ci.com/g/zachleigh/laravel-lang-bundler/)
6 | [](https://styleci.io/repos/72352058)
7 | [](https://packagist.org/packages/zachleigh/laravel-lang-bundler)
8 |
9 | ##### Make bundles of translation values.
10 |
11 | ### Contents
12 | - [Why](#why)
13 | - [Upgrade Information](#upgrade-information)
14 | - [Install](#install)
15 | - [Usage](#usage)
16 | - [Advanced Usage](#advanced-usage)
17 | - [Commands](#commands)
18 | - [Configuration](#configuration)
19 | - [Limitations](#limitations)
20 | - [Testing](#testing)
21 | - [Contributing](#contributing)
22 |
23 | ### Why
24 | Why use this package? Because this sucks:
25 | ```html
26 |
35 | ```
36 | And this is so much better:
37 | ```html
38 | toJson() }}
40 | >
41 | ```
42 |
43 | ### Upgrade Information
44 | ##### Version 1.0.* to Version 1.1.*
45 | Version 1.1.0 drops support for PHP versions lower than 7.1.
46 |
47 | ##### Version 0.9.* to Version 1.0.0
48 | Version 1.0.0 is more a confimation of the current api and usage than anything else. Adds support for Laravel 5.4. If using Laravel 5.3, please use [Version 0.9.11](https://github.com/zachleigh/laravel-lang-bundler/tree/v0.9.11):
49 | ```
50 | composer require zachleigh/laravel-lang-bundler:0.9.*
51 | ```
52 |
53 | ### Install
54 | ##### 1. Install through composer
55 | ```
56 | composer require zachleigh/laravel-lang-bundler
57 | ```
58 |
59 | ##### 2. Register the service provider
60 | In Laravel's config/app.php file, add the service provider to the array with the 'providers' key.
61 | ```
62 | LaravelLangBundler\ServiceProvider::class
63 | ```
64 |
65 | ##### 3. Publish the config file:
66 | ```
67 | php artisan vendor:publish --tag=config
68 | ```
69 |
70 | ##### 4. Create a 'bundles' directory in resources/lang/.
71 | Do it manually or use the command:
72 | ```
73 | php artisan langb:start
74 | ```
75 |
76 | ### Usage
77 | ##### 1. Make a bundle.
78 | Imagine we have two lang files, one called 'home.php' and one called 'user.php'.
79 |
80 | home.php
81 | ```php
82 | 'welcome' => 'Welcome!',
83 | 'login' => 'Login',
84 | 'signup' => 'Signup',
85 | ```
86 |
87 | user.php
88 | ```php
89 | 'profile' => 'Your Profile',
90 | 'friends' => 'Your Friends',
91 | 'body' => 'Enter body below',
92 | ```
93 | We want all of these values in one bundle.
94 |
95 | Simply register your bundle as an array anywhere in the bundles directory. For example, in the bundles directory, you could create a folder called 'components' and in it a file called 'bundle_name' that looks like this:
96 | ```php
97 | return [
98 | 'home.welcome',
99 | 'home.login',
100 | 'home.signup',
101 | 'user.profile',
102 | 'user.friends',
103 | 'user.body'
104 | ];
105 | ```
106 | Obviously, 'bundle_name' is the name of the bundle. The other values represent keys found in the above lang files.
107 |
108 | Like in other lang folders, any file/folder in the bundles directory is treated as a level in an array. So in the above example, our file path looks like this:
109 |
110 | lang/bundles/components/bundle_name.php
111 |
112 | The path for the 'bundle_name' bundle would be 'bundles.components.bundle_name'. It is also possible to create multiple named bundles within a single file, but this is not recommended because you can not use auto-aliasing for multi-bundle files.
113 |
114 | ##### 2. Get the bundle using the transB() helper function.
115 | Get your translated bundle by passing the bundle path to the transB() helper function.
116 | ```php
117 | transB('bundles.components.bundle_name');
118 | ```
119 | Or use the auto-aliased name:
120 | ```php
121 | transB('bundle_name');
122 | ```
123 | transB() returns a collection of translated values keyed by the original translation key. Continuing the example above, transB() would give us a collection that contains the following array:
124 | ```php
125 | [
126 | 'welcome' => 'Welcome!',
127 | 'login' => 'Login',
128 | 'signup' => 'Signup',
129 | 'profile' => 'Your Profile',
130 | 'friends' => 'Your Friends',
131 | 'body' => 'Enter body below',
132 | ];
133 | ```
134 |
135 | ##### 3. Pass parameters to your bundle.
136 | Like with the standard trans() function, you may pass parameters to the transB() function as the second argument.
137 | ```php
138 | transB('bundle_name', ['parameterName' => $value]);
139 | ```
140 | If your bundle has conflicting parameter names, you can namespace them. In this example, three values require a `user` parameter.
141 |
142 | user.php translation file:
143 | ```php
144 | return [
145 | 'welcome_user' => 'Welcome :user',
146 | 'message_to' => 'You sent a message to :user',
147 | 'invite_from' => 'You have an invite from :user'
148 | ];
149 | ```
150 | Bundle file:
151 | ```php
152 | return [
153 | 'user.welcome_user',
154 | 'user.message_to',
155 | 'user.invite_from'
156 | ];
157 | ```
158 | Avoid the naming conflict by namespacing the parameters when passing them to transB():
159 | ```php
160 | transB('bundle_name', [
161 | 'welcome_user.user' => 'Bob',
162 | 'message_to.user' => 'Sally',
163 | 'invite_from.user' => 'George'
164 | ]);
165 | ```
166 |
167 | ##### 4. Pluralize values
168 | It is possible to pluralize lang items by passing a namespaced 'choice' parameter in the transB() function parameters. For example, if our lang file value looked like this:
169 | ```php
170 | 'inbox_status' => 'You have a new message.|You have new messages'
171 | ```
172 | We could register it in our bundle normally:
173 | ```php
174 | 'home.inbox_status'
175 | ```
176 | And then when calling transB(), pass a parameter called 'inbox_status.choice' with the desired choice value:
177 | ```php
178 | transB('bundle_name', ['inbox_status.choice' => 3]);
179 | ```
180 | The result will look be the pluralized string "You have new messages".
181 |
182 | ### Advanced Usage
183 | #### Modify return keys and values
184 | To modify the key and value in the returned translation array, use the bundle_item() helper on a specific bundle item.
185 | ```php
186 | bundle_item($id, $type, $parameters = []);
187 | ```
188 | $id is the lang key. $type must be in the following format: 'target_type'. 'target' declares what item is to be affected by the modification and can be set to either 'value', 'key', or 'both'. 'type' declares the type of modification (callback, change etc.). $parameters is an array of parameters to be sent to the class that performs the modification.
189 |
190 | If using the same example as above we wanted to convert the 'welcome_user' value to all caps, we could accomplish it by using the bundle_item() helper function in the bundle file.
191 | user.php translation file:
192 | ```php
193 | return [
194 | 'welcome_user' => 'Welcome :user',
195 | 'message_to' => 'You sent a message to :user',
196 | 'invite_from' => 'You have an invite from :user'
197 | ];
198 | ```
199 | Bundle file:
200 | ```php
201 | return [
202 | bundle_item('user.welcome_user', 'value_strtoupper'),
203 | 'user.message_to',
204 | 'user.invite_from'
205 | ];
206 | ```
207 | Wrap the bundle key 'user.welcome_user' in the bundle_item() global function and pass the translation key ($id) plus the type (perform a 'strtoupper' on the returned 'value'). This returns the following values (assuming a non-namespaced user variable with the value 'Bob'):
208 | ```
209 | [
210 | 'welcome_user' => 'WELCOME BOB',
211 | 'message_to' => 'You sent a message to Bob',
212 | 'invite_from' => 'You have an invite from Bob'
213 | ];
214 | ```
215 |
216 | If we wanted to do the same to the key, we could do this:
217 | ```php
218 | return [
219 | bundle_item('user.welcome_user', 'key_strtoupper'),
220 | 'user.message_to',
221 | 'user.invite_from'
222 | ];
223 | ```
224 |
225 | Or, if we wanted to perform the modification on both the key and the value:
226 | ```php
227 | return [
228 | bundle_item('user.welcome_user', 'both_strtoupper'),
229 | 'user.message_to',
230 | 'user.invite_from'
231 | ];
232 | ```
233 |
234 | ##### Available modifiers
235 | ###### callback
236 | Perform a callback on a key or value. Requires a 'callback' parameter.
237 | ```php
238 | bundle_item('user.welcome_user', 'value_callback', [
239 | 'callback' => 'function_name'
240 | ]),
241 | ```
242 |
243 | ###### change
244 | Change a key to a new value. Does nothing to values. Requires 'new' parameter.
245 | ```php
246 | bundle_item('user.invite_from', 'key_change', [
247 | 'new' => 'newKey'
248 | ]),
249 | ```
250 | ###### explode
251 | Explode by given delimiter. Does nothing to key. Requires 'delimiter' parameter.
252 | ```php
253 | bundle_item('user.invite_from', 'value_explode', [
254 | 'delimiter' => ' '
255 | ]),
256 | ```
257 |
258 | ###### strtolower
259 | Lowercase entrire string.
260 | ```php
261 | bundle_item('home.invite_from', 'value_strtolower')
262 | ```
263 |
264 | ###### strtoupper
265 | Capitalize entire string.
266 | ```php
267 | bundle_item('home.invite_from', 'value_strtoupper')
268 | ```
269 |
270 | ###### ucfirst
271 | Make first character in string capitalized.
272 | ```php
273 | bundle_item('home.invite_from', 'value_ucfirst')
274 | ```
275 |
276 | ###### values
277 | If translation value is an array, run array_values() on array and return only values keyed by integers. Does nothing to keys.
278 | ```php
279 | bundle_item('home.months', 'value_values')
280 | ```
281 |
282 | ##### Creating your own modifier
283 | Use the 'mod' command to create a new mod class in App/LangBundler/Mods:
284 | ```
285 | langb:mod {name}
286 | ```
287 |
288 | There are two abstract methods that must be implemented in your class:
289 | ```php
290 | /**
291 | * Alter key and return.
292 | *
293 | * @param string $key
294 | *
295 | * @return string
296 | */
297 | abstract public function key($key);
298 |
299 | /**
300 | * Alter value and return.
301 | *
302 | * @param mixed $value
303 | *
304 | * @return mixed
305 | */
306 | abstract public function value($value);
307 | ```
308 | The same class is used to modify both the value and key. Define your modification and return the desired key/value.
309 |
310 | ### Commands
311 | ##### php artisan langb:start
312 | Get started by creating a bundles directory in your lang folder.
313 |
314 | ##### php artisan langb:new {path}
315 | Create a new bundle file located at path. For example:
316 | ```
317 | php artisan langb:new components.user.profile
318 | ```
319 | This would create the file lang/bundles/components/user/profile.php with an empty returned array.
320 |
321 | ##### php artisan langb:mod {name}
322 | Create an empty mod template in App/LangBundler/Mods.
323 |
324 | ### Configuration
325 | ##### aliases
326 | To shorten the name of bundles, you can register aliases in config.
327 | ```php
328 | 'aliases' [
329 | 'alias' => 'full.path.to.bundle'
330 | ];
331 | ```
332 | And then simply use the alias istead of the path in transB():
333 | ```php
334 | transB('alias');
335 | ```
336 |
337 | ##### key_transform
338 | If you wish to transform lang file keys to snake_case, StudlyCase, or camelCase, set `key_transform` to 'snake_case', 'studly_case', or 'camel_case'. Default value is 'none'.
339 | For example, this bundle contains snake cased variables:
340 | ```php
341 | return [
342 | 'user.welcome_user',
343 | 'user.message_to',
344 | 'user.invite_from'
345 | ];
346 | ```
347 | But in your javascript, you want to use came cased variables, set `key_transform` to 'camel_case' to get this bundle:
348 | ```php
349 | return [
350 | 'welcomeUser' => 'Welcome user!',
351 | 'messageTo' => 'Message to user',
352 | 'inviteFrom' => 'You have an invitation from user!',
353 | ];
354 | ```
355 | Many other simple string functions (ucfirst, strtoupper, etc.) also work.
356 |
357 | key_transform is global and will transform all keys in your project. If you wish to transform a single key, see [modify return keys and values](#modify-return-keys-and-values).
358 |
359 | ##### global_key_namespace
360 | If you keep all your translations in a single file, you can set `global_key_namespace` to the name of the file to save yourself some typing. For example, if all your translations are in a file called 'translations.php', you would have to register a bundle like this:
361 | ```php
362 | return [
363 | 'bundle_name' => [
364 | 'translations.home',
365 | 'translations.navigation',
366 | 'translations.menu',
367 | 'translations.login'
368 | ];
369 | ];
370 | ```
371 | However, if you set `global_key_namespace` to 'translations', you could register it like this:
372 | ```php
373 | return [
374 | 'bundle_name' => [
375 | 'home',
376 | 'navigation',
377 | 'menu',
378 | 'login'
379 | ];
380 | ];
381 | ```
382 |
383 | ### Testing
384 | ```
385 | composer test
386 | ```
387 |
388 | ### Contributing
389 | Contributions are more than welcome. Fork, improve and make a pull request. For bugs, ideas for improvement or other, please create an [issue](https://github.com/zachleigh/laravel-lang-bundler/issues).
390 |
--------------------------------------------------------------------------------