Skip to content
This repository has been archived by the owner on Apr 28, 2024. It is now read-only.

Feature rewrite #14

Merged
merged 29 commits into from
Nov 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
897ec45
PHP7-ize translation
lcharette Aug 31, 2019
18d02ae
Added test data
lcharette Oct 16, 2019
b2236a1
Added Locale Class
lcharette Oct 16, 2019
b12ff67
Fix styling
lcharette Oct 16, 2019
58ee1a6
Added first draft of the Dictionary
lcharette Oct 18, 2019
38dbab4
Saving progress in Dictionary
lcharette Oct 22, 2019
77e50cb
Improved `filterDictionaryFiles`
lcharette Oct 22, 2019
57a1368
Changes to Locale:
lcharette Oct 24, 2019
3bd1f98
Added dependent dictionnary load
lcharette Oct 24, 2019
bd56a7c
Skip the constructor in interface
lcharette Oct 24, 2019
5208c96
Changed `new X` to `new self`
lcharette Oct 24, 2019
9023611
Fix `getDependentLocalesIdentifier`
lcharette Oct 24, 2019
42b2695
Added `getLocale` to Dictionary
lcharette Oct 25, 2019
3c22e8b
Finished DictionaryTest
lcharette Oct 28, 2019
e27cddc
Reworked dictionary tests & data
lcharette Oct 30, 2019
e8e0924
Adapted Translator to new dictionary
lcharette Oct 30, 2019
b330067
Try to avoid `Undefined index: parents`
lcharette Oct 30, 2019
f4e4b92
Started moving Repository extension from Translator to Dictionary class
lcharette Nov 2, 2019
03482fe
Make all param from the config file optional
lcharette Nov 5, 2019
f39241a
Added missing test for getLocalizedName
lcharette Nov 5, 2019
5a7fdec
Make Dictionary uses Support methods
lcharette Nov 5, 2019
aba43d5
Satisfy StyleCI
lcharette Nov 5, 2019
107dafd
Added API docs
lcharette Nov 5, 2019
de2acd2
Updated Readme [ci skip]
lcharette Nov 9, 2019
7f98af6
Updated Changelog [ci skip]
lcharette Nov 9, 2019
e92a3b3
Added `getDictionary` & `getLocale` to translator.
lcharette Nov 9, 2019
bb7933d
Making StyleCI happy
lcharette Nov 9, 2019
b24d47e
['options']['plural'] => ['plural_rule']
lcharette Nov 9, 2019
9d517f2
Making StyleCI Happy
lcharette Nov 9, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ composer.lock
*.komodoproject
.php_cs.cache
_meta
.serenata
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,27 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [4.4.0]
Complete rewrite of the Translator.

Instead of `LocalePathBuilder -> MessageTranslator`, the new translator introduce the concept of `Locale`, `Dictionary` and `Translator`. So now you create a locale, which enables you to create a dictionary for that locale, which finally allows you to create a translator which will used that dictionary.

Instead of loading multiple locale on top of each other, a locale can depend on other locale using the configuration file (ie. `locale.yaml`). See the updated doc for more information.

Plural rule are now defined in the locale configuration file instead of the special `@PLURAL_RULE` key.

All methods of the `Translator` are the same for backward compatibility. The only change is the constructor, which now requires a `DictionaryInterface` instance.

**Detailed changes** :
- `MessageTranslator` is now `Translator`.
- `Translator` requires a `DictionaryInterface` as some constructor argument instead of paths.
- `LocalePathBuilder` removed.
- `DictionaryInterface` now extends `UserFrosting\Support\Repository\Repository` instead of the `Translator`. The raw data can be accessed using the Dictionary methods.
- `@PLURAL_RULE` special key removed. Use the Locale configuration file (`locale.yaml`) `plural_rule` attribute instead.
- Translator can't load multiple locale anymore. Use the Locale configuration file `parents` attribute instead.

See updated [documentation](README.md) for more details on how to use the new Translator, Locale and Dictionary.

## [4.3.0]
- Dropping support for PHP 5.6 & 7.0
- Updated Twig to 2.x
Expand Down Expand Up @@ -36,6 +57,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
## 4.0.0
- Initial release

[4.4.0]: https://github.com/userfrosting/i18n/compare/4.3.0...4.4.0
[4.3.0]: https://github.com/userfrosting/i18n/compare/4.2.1...4.3.0
[4.2.1]: https://github.com/userfrosting/i18n/compare/4.2.0...4.2.1
[4.2.0]: https://github.com/userfrosting/i18n/compare/4.1.0...4.2.0
Expand Down
210 changes: 172 additions & 38 deletions README.md

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@
"require": {
"php": ">=7.1",
"twig/twig": "^2.11",
"userfrosting/support": "~4.3.0"
"userfrosting/support": "~4.3.1"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.13",
"phpunit/phpunit": "^7.5"
"mockery/mockery": "^1.2",
"phpunit/phpunit": "^7.5",
"victorjonsson/markdowndocs": "^1.3"
},
"autoload": {
"psr-4": {
Expand Down
5 changes: 5 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Building doc

```
vendor/bin/phpdoc-md generate src/ > docs/api.md
```
321 changes: 321 additions & 0 deletions docs/api.md

Large diffs are not rendered by default.

177 changes: 177 additions & 0 deletions src/Dictionary.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
<?php

/*
* UserFrosting i18n (http://www.userfrosting.com)
*
* @link https://github.com/userfrosting/i18n
* @copyright Copyright (c) 2013-2019 Alexander Weissman, Louis Charette
* @license https://github.com/userfrosting/i18n/blob/master/LICENSE.md (MIT License)
*/

namespace UserFrosting\I18n;

use UserFrosting\Support\Repository\Loader\ArrayFileLoader;
use UserFrosting\Support\Repository\Loader\FileRepositoryLoader;
use UserFrosting\Support\Repository\Repository;
use UserFrosting\UniformResourceLocator\ResourceLocatorInterface;

/**
* Locale Dictionary.
*
* Load all locale all "Key => translation" data matrix
*
* @author Louis Charette
*/
class Dictionary extends Repository implements DictionaryInterface
{
/**
* @var string Base URI for locator
*/
protected $uri = 'locale://';

/**
* @var LocaleInterface
*/
protected $locale;

/**
* @var ResourceLocatorInterface
*/
protected $locator;

/**
* @var FileRepositoryLoader
*/
protected $fileLoader;

/**
* @var array Locale "Key => translation" data matrix cache
*/
protected $items = [];

/**
* @param LocaleInterface $locale
* @param ResourceLocatorInterface $locator
* @param FileRepositoryLoader $fileLoader File loader used to load each dictionnay files (default to Array Loader)
*/
public function __construct(LocaleInterface $locale, ResourceLocatorInterface $locator, FileRepositoryLoader $fileLoader = null)
{
$this->locale = $locale;
$this->locator = $locator;
$this->fileLoader = is_null($fileLoader) ? new ArrayFileLoader([]) : $fileLoader;
}

/**
* Returns all loaded locale Key => Translation data dictionary.
* Won't load the whole thing twice if already loaded in the class.
*
* @return string[] The locale dictionary
*/
public function getDictionary(): array
{
if (empty($this->items)) {
$this->items = $this->loadDictionary();
}

return $this->items;
}

/**
* Set the locator base URI (default 'locale://').
*
* @param string $uri
*/
public function setUri(string $uri): void
{
$this->uri = $uri;
}

/**
* Return the associate locale.
*
* @return LocaleInterface
*/
public function getLocale(): LocaleInterface
{
return $this->locale;
}

/**
* Return the file repository loader used to load.
*
* @return FileRepositoryLoader
*/
public function getFileLoader(): FileRepositoryLoader
{
return $this->fileLoader;
}

/**
* Load the dictionary from file.
*
* @return (string|array)[] The locale dictionary
*/
protected function loadDictionary(): array
{
$dictionary = [];

// List of loaded locales
$loadedLocale = [$this->locale->getIndentifier()];

// Get list of files to load
$files = $this->getFiles();
$files = $this->filterDictionaryFiles($files);

// Load all files content if files are present
if (!empty($files)) {
$loader = $this->getFileLoader();
$loader->setPaths($files);

$dictionary = $loader->load();
}

// Now load dependent dictionnaries
foreach ($this->locale->getDependentLocales() as $locale) {

// Stop if locale already loaded to prevent recursion
$localesToLoad = array_merge([$locale->getIndentifier()], $locale->getDependentLocalesIdentifier());
$intersection = array_intersect($localesToLoad, $loadedLocale);
if (!empty($intersection)) {
throw new \LogicException("Can't load dictionary. Dependencies recursion detected : ".implode(', ', $intersection));
}

$dependentDictionary = new self($locale, $this->locator, $this->fileLoader);
$dictionary = array_replace_recursive($dependentDictionary->getDictionary(), $dictionary);

$loadedLocale[] = $locale->getIndentifier();
}

return $dictionary;
}

/**
* Remove config files from locator results and convert ResourceInterface to path/string.
*
* @param \UserFrosting\UniformResourceLocator\ResourceInterface[] $files
*
* @return string[]
*/
protected function filterDictionaryFiles(array $files): array
{
return array_filter($files, function ($file) {
if ($file->getExtension() == 'php') {
return (string) $file;
}
});
}

/**
* List all files for a given locale using the locator.
*
* @return \UserFrosting\UniformResourceLocator\ResourceInterface[]
*/
protected function getFiles(): array
{
return $this->locator->listResources($this->uri.$this->locale->getIndentifier(), true);
}
}
39 changes: 39 additions & 0 deletions src/DictionaryInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

/*
* UserFrosting i18n (http://www.userfrosting.com)
*
* @link https://github.com/userfrosting/i18n
* @copyright Copyright (c) 2013-2019 Alexander Weissman, Louis Charette
* @license https://github.com/userfrosting/i18n/blob/master/LICENSE.md (MIT License)
*/

namespace UserFrosting\I18n;

use Illuminate\Contracts\Config\Repository;

/**
* Locale Dictionary.
*
* Used to return all "Key => translation" data matrix
* Extend the Config repository to have acess to all the standard `has`, `get`,
* etc. public methods on the dictionnay array
*
* @author Louis Charette
*/
interface DictionaryInterface extends Repository
{
/**
* Returns all loaded locale Key => Translation data dictionary.
*
* @return string[] The locale dictionary
*/
public function getDictionary(): array;

/**
* Return the associate locale.
*
* @return LocaleInterface
*/
public function getLocale(): LocaleInterface;
}
Loading