Skip to content

Commit ce7384e

Browse files
committed
Optimize setCode, enhance has, and minor cleanup
- Prevent calling setCode if the code hasn’t changed. - Added $checkDefault argument to the has method in the Localizer class. - Code cleanup and minor tweaks across files.
1 parent 41131f5 commit ce7384e

File tree

5 files changed

+46
-98
lines changed

5 files changed

+46
-98
lines changed

.phpunit.result.cache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"version":1,"defects":{"ArrayBasedTranslators::testForDefaultTranslation":3,"ArrayBasedTranslators::testForDifferentTranslator":3,"ClassBasedTranslators::testForDefaultTranslation":3,"ClassBasedTranslators::testForDifferentTranslator":3,"ArrayBasedTranslatorsTest::testRandom":3},"times":{"ArrayBasedTranslators::testForGet":0.007,"ArrayBasedTranslators::testForDefaultTranslation":0.001,"ArrayBasedTranslators::testForDifferentTranslator":0,"ClassBasedTranslators::testDynamicMessage":0.156,"ClassBasedTranslators::testForGet":0.005,"ClassBasedTranslators::testForDefaultTranslation":0,"ClassBasedTranslators::testForDifferentTranslator":0,"ArrayBasedTranslatorsTest::testForGet":0.006,"ArrayBasedTranslatorsTest::testForDefaultTranslation":0,"ArrayBasedTranslatorsTest::testForDifferentTranslator":0.001,"ArrayBasedTranslatorsTest::testRandom":0,"ClassBasedTranslatorsTest::testForGet":0.013,"ClassBasedTranslatorsTest::testForDefaultTranslation":0.001,"ClassBasedTranslatorsTest::testForDifferentTranslator":0.001,"ClassBasedTranslatorsTest::testRandom":0}}
1+
{"version":1,"defects":{"ArrayBasedTranslators::testForDefaultTranslation":3,"ArrayBasedTranslators::testForDifferentTranslator":3,"ClassBasedTranslators::testForDefaultTranslation":3,"ClassBasedTranslators::testForDifferentTranslator":3,"ArrayBasedTranslatorsTest::testRandom":3},"times":{"ArrayBasedTranslators::testForGet":0.007,"ArrayBasedTranslators::testForDefaultTranslation":0.001,"ArrayBasedTranslators::testForDifferentTranslator":0,"ClassBasedTranslators::testDynamicMessage":0.156,"ClassBasedTranslators::testForGet":0.005,"ClassBasedTranslators::testForDefaultTranslation":0,"ClassBasedTranslators::testForDifferentTranslator":0,"ArrayBasedTranslatorsTest::testForGet":0.012,"ArrayBasedTranslatorsTest::testForDefaultTranslation":0.002,"ArrayBasedTranslatorsTest::testForDifferentTranslator":0.001,"ArrayBasedTranslatorsTest::testRandom":0,"ClassBasedTranslatorsTest::testForGet":0.005,"ClassBasedTranslatorsTest::testForDefaultTranslation":0,"ClassBasedTranslatorsTest::testForDifferentTranslator":0,"ClassBasedTranslatorsTest::testRandom":0}}

README.md

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,15 @@ composer require nabeghe/light-localization
1515
### 📁 Localization Directory
1616

1717
- Create a directory for localization.
18-
- In this directory, create new folders, each of these folders actually represent Localization codes.
18+
- In this directory, create new folders, each of these folders actually represent localization codes.
1919
They can be language codes or anything else.
2020
- Inside each code directory, php files will be placed, each of these files has the role of a translator.
21-
2221
- These files can return an array or an object that inheritance from `Nabeghe\LightLocalization\Translator` class.
2322
- If it's an array, each key is a translation key & it will represent a value,
24-
but if it's an object, each field or method is a translation key.
25-
The priority is with the method & it must return a value.
26-
- With the method, you can have dynamic localization!
23+
but if it's an object, each field or method is a translation key.
24+
The priority is with the method & it must return a value.
2725
- Objects can implement the `ArrayAccess` interface in addition to inheriting from the mentioned class.
2826

29-
### Examples
30-
31-
Check the examples folder in the repositiry.
32-
3327
```php
3428
use Nabeghe\LightLocalization\Localizer;
3529

@@ -55,19 +49,20 @@ echo $localizer->get('hello', 'messages');
5549
```
5650

5751
**Notice:** The localization code can be specified in the constructor method.
58-
Of course, it's possible to change it later via method `recode`.
52+
Of course, it's possible to change it later via method `setCode`.
5953

60-
**Notice:** "For each localizer, a default localizer can be specified in the constructor.
61-
Additionally, instead of specifying a default localizer, a string can be designated as the default translation."
54+
**Notice:** For each localizer, a default localizer can be specified in the constructor.
55+
Additionally, instead of specifying a default localizer, a string can be designated as the default translation.
6256

6357
## 🧩 Features
6458

6559
- Get the value (translation) using the key.
60+
- Fetch random translations from keys with array of strings using the `rnd` method instead of `get`.
6661
- Localization code (the second parameter of Localizer constructor).
6762
- Default translation that can be a string or another localizer.
6863
(the third parameter of Localizer constructor).
69-
- Create different translators in different files.
70-
- Dynamic translations using methods in the class-based translation files.
64+
- Create different translators in different files and array-based or class-based translations.
65+
- Dynamic translations.
7166
- Reload the translator.
7267
- Remove the loaded translator.
7368
- Refreshing translators and reloading them.

src/Localizer.php

Lines changed: 24 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,8 @@ class Localizer implements LocalizerInterface
2020

2121
/**
2222
* Default translation that can be a string or another localizer.
23-
* If the key is not found in the translation, the default will be used.
24-
* If the default is a string, the string itself will be returned instead of the default translation,
25-
* but if it's a localizer object, it's `get` method will be used to retrieve the translation.
26-
* @see self::get()
2723
* @var Localizer|string
24+
* @see self::get()
2825
*/
2926
protected $defaultTranslation;
3027

@@ -34,30 +31,24 @@ class Localizer implements LocalizerInterface
3431
*/
3532
protected array $translators = [];
3633

37-
/**
38-
* Retrieves the root path.
39-
*/
4034
public function getPath(): string
4135
{
4236
return $this->path;
4337
}
4438

45-
/**
46-
* Retrieves the current language code.
47-
*/
4839
public function getCode(): string
4940
{
5041
return $this->code;
5142
}
5243

53-
/**
54-
* Changes the localization code.
55-
* @param string $code New code.
56-
* @param bool $refresh Optional. After changing the code, should it reload the loaded translators or remove all of them from the loaded state? Default false.
57-
*/
5844
public function setCode(string $code, bool $refresh = false): void
5945
{
46+
if ($this->code == $code) {
47+
return;
48+
}
49+
6050
$this->code = $code;
51+
6152
if ($refresh) {
6253
$this->refresh();
6354
} else {
@@ -73,18 +64,11 @@ public function recode(string $code, bool $refresh = false): void
7364
$this->setCode($code, $refresh);
7465
}
7566

76-
/**
77-
* Retrieves the default translation.
78-
*/
7967
public function getDefaultTranslation()
8068
{
8169
return $this->defaultTranslation;
8270
}
8371

84-
/**
85-
* Retrieves the list of loaded translators.
86-
* @return array
87-
*/
8872
public function getTranslators(): array
8973
{
9074
return $this->translators;
@@ -94,7 +78,7 @@ public function getTranslators(): array
9478
* Constructor.
9579
* @param string $path The root path where the directories related to the codes are located.
9680
* @param string $code Optional. Localization code. Default `generic`.
97-
* @param Localizer|string $defaultTranslation Optional. Default translation. Default is empty string.
81+
* @param Localizer|string $defaultTranslation Optional. Default translation. Default value is an emoty string.
9882
*/
9983
public function __construct(string $path, string $code = self::DEFAULT_CODE, $defaultTranslation = '')
10084
{
@@ -103,60 +87,40 @@ public function __construct(string $path, string $code = self::DEFAULT_CODE, $de
10387
$this->defaultTranslation = $defaultTranslation;
10488
}
10589

106-
/**
107-
* Retrieves the file path of a translator.
108-
* @param string $translator Optional. The translator file name without `.php` extension. Default `main`.
109-
* @return string
110-
*/
11190
public function getTranslatorPath(string $translator = self::DEFAULT_TRANSLATOR): string
11291
{
11392
return "$this->path/$this->code/$translator.php";
11493
}
11594

116-
/**
117-
* Checks whether the translator exists or not.
118-
* @param string $translator Translator Translator file name.
119-
* @return bool
120-
*/
12195
public function translatorExists(string $translator = self::DEFAULT_TRANSLATOR): bool
12296
{
12397
return file_exists($this->getTranslatorPath($translator));
12498
}
12599

126-
/**
127-
* Checks if a translator is loaded before or not.
128-
* @param string $translator Translator file name.
129-
* @return bool
130-
*/
131100
public function isLoaded(string $translator): bool
132101
{
133102
return isset($this->translators[$translator]);
134103
}
135104

136-
/**
137-
* Loads a translator even if it is already loaded.
138-
* @param string $translator Translator file name.
139-
* @return bool
140-
*/
141105
public function load($translator = self::DEFAULT_TRANSLATOR): bool
142106
{
143107
$success = false;
144-
$branch_path = $this->getTranslatorPath($translator);
145-
if (file_exists($branch_path)) {
146-
$new_data = include $branch_path;
147-
if (!$new_data) {
108+
109+
$translator_path = $this->getTranslatorPath($translator);
110+
if (file_exists($translator_path)) {
111+
$new_data = include $translator_path;
112+
if (!is_array($new_data)) {
148113
$new_data = [];
149114
} else {
150115
$success = true;
151116
}
152117
}
118+
153119
$this->translators[$translator] = $new_data ?? [];
120+
154121
return $success;
155122
}
156123

157-
/**
158-
* Loads all loaded translators from the beginning.
159-
*/
160124
public function refresh(): void
161125
{
162126
$translators_names = array_keys($this->translators);
@@ -165,73 +129,58 @@ public function refresh(): void
165129
}
166130
}
167131

168-
/**
169-
* Removes a translator from loaded state.
170-
* @param string $translator Translator file name.
171-
* @return bool
172-
*/
173132
public function unload(string $translator = self::DEFAULT_TRANSLATOR): bool
174133
{
175134
if (isset($this->translators[$translator])) {
176135
unset($this->translators[$translator]);
177136
return true;
178137
}
138+
179139
return false;
180140
}
181141

182-
/**
183-
* Checks whether a key exists in a translator or not.
184-
* @param string $key
185-
* @param string $translator Translator file name.
186-
* @return bool
187-
*/
188-
public function has(string $key, $translator = self::DEFAULT_TRANSLATOR)
142+
public function has(string $key, $translator = self::DEFAULT_TRANSLATOR, bool $checkDefault = true): bool
189143
{
190144
if (!isset($this->translators[$translator])) {
191145
$this->load($translator);
192146
}
147+
193148
return isset($this->translators[$translator][$key])
194-
|| (!is_string($this->defaultTranslation) && $this->defaultTranslation->has($key, $translator));
149+
|| ($checkDefault && !is_string($this->defaultTranslation) && $this->defaultTranslation->has($key, $translator, $checkDefault));
195150
}
196151

197-
/**
198-
* Retrieves a string or translation using its key.
199-
* @param string $key The key is in the translator.
200-
* @param string $translator Translator file name.
201-
* @return string|mixed
202-
*/
203152
public function get(string $key, string $translator = self::DEFAULT_TRANSLATOR)
204153
{
205154
if (!isset($this->translators[$translator])) {
206155
$this->load($translator);
207156
}
157+
208158
if (isset($this->translators[$translator][$key])) {
209159
return $this->translators[$translator][$key];
210160
}
161+
211162
if (is_string($this->defaultTranslation)) {
212163
return $this->defaultTranslation;
213164
}
165+
214166
return $this->defaultTranslation->get($key, $translator);
215167
}
216168

217-
/**
218-
* It's's similar to the {@see self::get()} method, with the difference that if the output is an array, it randomly returns one of the values within it.
219-
* @param string $key
220-
* @param string $translator
221-
* @return mixed|Localizer|string
222-
*/
223169
public function rnd(string $key, string $translator = self::DEFAULT_TRANSLATOR)
224170
{
225171
$text = $this->get($key, $translator);
226172
if (!is_array($text)) {
227173
return $text;
228174
}
175+
229176
if ($text) {
230177
return $text[array_rand($text)];
231178
}
179+
232180
if (is_string($this->defaultTranslation)) {
233181
return $this->defaultTranslation;
234182
}
183+
235184
return $this->defaultTranslation->get($key, $translator);
236185
}
237186
}

src/LocalizerInterface.php

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,19 @@ public function getCode();
3434
public function setCode(string $code, bool $refresh = false);
3535

3636
/**
37-
* Retrieves the default translation.
37+
* Returns the default translation.
38+
* @return Localizer|string
3839
*/
3940
public function getDefaultTranslation();
4041

4142
/**
42-
* Retrieves the list of loaded translators.
43+
* Returns the list of loaded translators.
4344
* @return array
4445
*/
4546
public function getTranslators(): array;
4647

4748
/**
48-
* Retrieves the file path of a translator.
49+
* Returns the file path of a translator.
4950
* @param string $translator Optional. The translator file name without `.php` extension. Default `main`.
5051
* @return string
5152
*/
@@ -85,23 +86,24 @@ public function refresh();
8586
public function unload(string $translator = self::DEFAULT_TRANSLATOR);
8687

8788
/**
88-
* Checks whether a key exists in a translator or not.
89+
* Checks whether a key exists in a translator or not.<br>
8990
* @param string $key
9091
* @param string $translator Translator file name.
92+
* @param bool $checkDefault Should the default translation also be checked if it is a Localizer? Default true.
9193
* @return bool
9294
*/
93-
public function has(string $key, $translator = self::DEFAULT_TRANSLATOR);
95+
public function has(string $key, $translator = self::DEFAULT_TRANSLATOR, bool $checkDefault = true): bool;
9496

9597
/**
96-
* Retrieves a string or translation using its key.
98+
* Returns a string or translation using its key.
9799
* @param string $key The key is in the translator.
98100
* @param string $translator Translator file name.
99101
* @return string|mixed
100102
*/
101103
public function get(string $key, string $translator = self::DEFAULT_TRANSLATOR);
102104

103105
/**
104-
* It's's similar to the {@see self::get()} method, with the difference that if the output is an array, it randomly returns one of the values within it.
106+
* It's similar to the {@see self::get()} method, with the difference that if the output is an array, it randomly returns one of the values within it.
105107
* @param string $key
106108
* @param string $translator
107109
* @return mixed|Localizer|string

tests/LocalizerCase.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php declare(strict_types=1);
22

3-
use Nabeghe\LightLocalization\Localizer;
43
use PHPUnit\Framework\TestCase;
4+
use Nabeghe\LightLocalization\Localizer;
55

66
abstract class LocalizerCase extends TestCase
77
{
@@ -16,6 +16,7 @@ public function __construct(?string $name = null, array $data = [], $dataName =
1616
'fa',
1717
new Localizer(__DIR__.'/data/'.$this->getTranslatorsDirectoryName(), 'en'),
1818
);
19+
1920
parent::__construct($name, $data, $dataName);
2021
}
2122

@@ -37,6 +38,7 @@ public function testForDifferentTranslator(): void
3738
{
3839
$expected = 'Hadi Akbarzadeh';
3940
$translated = $this->localizer->get('name', 'developer'); // from `developer.php` file.
41+
4042
$this->assertSame($expected, $translated);
4143
}
4244

0 commit comments

Comments
 (0)