Require gettext/translator
This commit is contained in:
parent
cbdedfc7f4
commit
dd41b890e3
20 changed files with 1079 additions and 5 deletions
|
@ -6,7 +6,8 @@
|
|||
"embed/embed": "^4.3",
|
||||
"grandel/include-directory": "^0.2.2",
|
||||
"qferr/mjml-php": "^1.1",
|
||||
"gettext/gettext": "^5.6"
|
||||
"gettext/gettext": "^5.6",
|
||||
"gettext/translator": "^1.1"
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
|
|
76
composer.lock
generated
76
composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "4c60c00f536a20de82f5546d4c604eb5",
|
||||
"content-hash": "a1fb82d56813359d39e2e661463e8dd0",
|
||||
"packages": [
|
||||
{
|
||||
"name": "composer/ca-bundle",
|
||||
|
@ -319,6 +319,80 @@
|
|||
],
|
||||
"time": "2021-11-11T17:30:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "gettext/translator",
|
||||
"version": "v1.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-gettext/Translator.git",
|
||||
"reference": "b18ff33e8203de623854561f5e47e992fc5c50bb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-gettext/Translator/zipball/b18ff33e8203de623854561f5e47e992fc5c50bb",
|
||||
"reference": "b18ff33e8203de623854561f5e47e992fc5c50bb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^2.15",
|
||||
"gettext/gettext": "^5.0.0",
|
||||
"oscarotero/php-cs-fixer-config": "^1.0",
|
||||
"phpunit/phpunit": "^8.0",
|
||||
"squizlabs/php_codesniffer": "^3.0"
|
||||
},
|
||||
"suggest": {
|
||||
"gettext/gettext": "Is necessary to load and generate array files used by the translator"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Gettext\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Oscar Otero",
|
||||
"email": "oom@oscarotero.com",
|
||||
"homepage": "http://oscarotero.com",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Gettext translator functions",
|
||||
"homepage": "https://github.com/php-gettext/Translator",
|
||||
"keywords": [
|
||||
"gettext",
|
||||
"i18n",
|
||||
"php",
|
||||
"translator"
|
||||
],
|
||||
"support": {
|
||||
"email": "oom@oscarotero.com",
|
||||
"issues": "https://github.com/php-gettext/Translator/issues",
|
||||
"source": "https://github.com/php-gettext/Translator/tree/v1.1.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://paypal.me/oscarotero",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/oscarotero",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://www.patreon.com/misteroom",
|
||||
"type": "patreon"
|
||||
}
|
||||
],
|
||||
"time": "2022-02-23T20:29:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "grandel/include-directory",
|
||||
"version": "v0.2.2",
|
||||
|
|
2
vendor/composer/autoload_psr4.php
vendored
2
vendor/composer/autoload_psr4.php
vendored
|
@ -18,7 +18,7 @@ return array(
|
|||
'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'),
|
||||
'Grandel\\' => array($vendorDir . '/grandel/include-directory/src'),
|
||||
'Gettext\\Languages\\' => array($vendorDir . '/gettext/languages/src'),
|
||||
'Gettext\\' => array($vendorDir . '/gettext/gettext/src'),
|
||||
'Gettext\\' => array($vendorDir . '/gettext/gettext/src', $vendorDir . '/gettext/translator/src'),
|
||||
'Embed\\' => array($vendorDir . '/embed/embed/src'),
|
||||
'Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\' => array($vendorDir . '/dealerdirect/phpcodesniffer-composer-installer/src'),
|
||||
'Composer\\CaBundle\\' => array($vendorDir . '/composer/ca-bundle/src'),
|
||||
|
|
1
vendor/composer/autoload_static.php
vendored
1
vendor/composer/autoload_static.php
vendored
|
@ -114,6 +114,7 @@ class ComposerStaticInit5f3db9fc1d0cf1dd6a77a1d84501b4b1
|
|||
'Gettext\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/gettext/gettext/src',
|
||||
1 => __DIR__ . '/..' . '/gettext/translator/src',
|
||||
),
|
||||
'Embed\\' =>
|
||||
array (
|
||||
|
|
77
vendor/composer/installed.json
vendored
77
vendor/composer/installed.json
vendored
|
@ -403,6 +403,83 @@
|
|||
],
|
||||
"install-path": "../gettext/languages"
|
||||
},
|
||||
{
|
||||
"name": "gettext/translator",
|
||||
"version": "v1.1.1",
|
||||
"version_normalized": "1.1.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-gettext/Translator.git",
|
||||
"reference": "b18ff33e8203de623854561f5e47e992fc5c50bb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-gettext/Translator/zipball/b18ff33e8203de623854561f5e47e992fc5c50bb",
|
||||
"reference": "b18ff33e8203de623854561f5e47e992fc5c50bb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^2.15",
|
||||
"gettext/gettext": "^5.0.0",
|
||||
"oscarotero/php-cs-fixer-config": "^1.0",
|
||||
"phpunit/phpunit": "^8.0",
|
||||
"squizlabs/php_codesniffer": "^3.0"
|
||||
},
|
||||
"suggest": {
|
||||
"gettext/gettext": "Is necessary to load and generate array files used by the translator"
|
||||
},
|
||||
"time": "2022-02-23T20:29:40+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Gettext\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Oscar Otero",
|
||||
"email": "oom@oscarotero.com",
|
||||
"homepage": "http://oscarotero.com",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Gettext translator functions",
|
||||
"homepage": "https://github.com/php-gettext/Translator",
|
||||
"keywords": [
|
||||
"gettext",
|
||||
"i18n",
|
||||
"php",
|
||||
"translator"
|
||||
],
|
||||
"support": {
|
||||
"email": "oom@oscarotero.com",
|
||||
"issues": "https://github.com/php-gettext/Translator/issues",
|
||||
"source": "https://github.com/php-gettext/Translator/tree/v1.1.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://paypal.me/oscarotero",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/oscarotero",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://www.patreon.com/misteroom",
|
||||
"type": "patreon"
|
||||
}
|
||||
],
|
||||
"install-path": "../gettext/translator"
|
||||
},
|
||||
{
|
||||
"name": "grandel/include-directory",
|
||||
"version": "v0.2.2",
|
||||
|
|
13
vendor/composer/installed.php
vendored
13
vendor/composer/installed.php
vendored
|
@ -5,7 +5,7 @@
|
|||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
'reference' => '1676940e47329dfd87e34a4928446ce52a8725aa',
|
||||
'reference' => 'cbdedfc7f48f7851b8bf5411f75a9df9f2ceae94',
|
||||
'name' => '__root__',
|
||||
'dev' => true,
|
||||
),
|
||||
|
@ -16,7 +16,7 @@
|
|||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
'reference' => '1676940e47329dfd87e34a4928446ce52a8725aa',
|
||||
'reference' => 'cbdedfc7f48f7851b8bf5411f75a9df9f2ceae94',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'composer/ca-bundle' => array(
|
||||
|
@ -64,6 +64,15 @@
|
|||
'reference' => 'ed56dd2c7f4024cc953ed180d25f02f2640e3ffa',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'gettext/translator' => array(
|
||||
'pretty_version' => 'v1.1.1',
|
||||
'version' => '1.1.1.0',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../gettext/translator',
|
||||
'aliases' => array(),
|
||||
'reference' => 'b18ff33e8203de623854561f5e47e992fc5c50bb',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'grandel/include-directory' => array(
|
||||
'pretty_version' => 'v0.2.2',
|
||||
'version' => '0.2.2.0',
|
||||
|
|
31
vendor/gettext/translator/CHANGELOG.md
vendored
Normal file
31
vendor/gettext/translator/CHANGELOG.md
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
# Change Log
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## [1.1.1] - 2022-02-23
|
||||
### Security
|
||||
- Updated the plural form conversion to accept a limited character set [#5]
|
||||
|
||||
## [1.1.0] - 2022-02-23
|
||||
### Added
|
||||
- Option to include empty translations in the `ArrayGenerator` [#3]
|
||||
|
||||
## [1.0.1] - 2020-12-01
|
||||
### Fixed
|
||||
- Added PHP 8 to composer.json
|
||||
- Define functions only if they are undefined [#1]
|
||||
|
||||
## [1.0.0] - 2019-11-05
|
||||
First version
|
||||
|
||||
[#1]: https://github.com/php-gettext/Translator/issues/1
|
||||
[#3]: https://github.com/php-gettext/Translator/issues/3
|
||||
[#5]: https://github.com/php-gettext/Translator/issues/5
|
||||
|
||||
[1.1.1]: https://github.com/php-gettext/Translator/compare/v1.1.0...v1.1.1
|
||||
[1.1.0]: https://github.com/php-gettext/Translator/compare/v1.0.1...v1.1.0
|
||||
[1.0.1]: https://github.com/php-gettext/Translator/compare/v1.0.0...v1.0.1
|
||||
[1.0.0]: https://github.com/php-gettext/Translator/releases/tag/v1.0.0
|
17
vendor/gettext/translator/CONTRIBUTING.md
vendored
Normal file
17
vendor/gettext/translator/CONTRIBUTING.md
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
Contributing to Gettext
|
||||
=======================
|
||||
|
||||
Looking to contribute something to this library? Here's how you can help.
|
||||
|
||||
## Bugs
|
||||
|
||||
A bug is a demonstrable problem that is caused by the code in the repository. Good bug reports are extremely helpful – thank you!
|
||||
|
||||
Please try to be as detailed as possible in your report. Include specific information about the environment – version of PHP, version of gettext, etc, and steps required to reproduce the issue.
|
||||
|
||||
## Pull Requests
|
||||
|
||||
Good pull requests – patches, improvements, new features – are a fantastic help. New extractors or generator are welcome. Before create a pull request, please follow these instructions:
|
||||
|
||||
* The code must be PSR-2 compliant
|
||||
* Write some tests
|
21
vendor/gettext/translator/LICENSE
vendored
Normal file
21
vendor/gettext/translator/LICENSE
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2019 Oscar Otero Marzoa
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
92
vendor/gettext/translator/README.md
vendored
Normal file
92
vendor/gettext/translator/README.md
vendored
Normal file
|
@ -0,0 +1,92 @@
|
|||
# Translator
|
||||
|
||||
[![Latest Version on Packagist][ico-version]][link-packagist]
|
||||
[![Software License][ico-license]](LICENSE)
|
||||
[![Total Downloads][ico-downloads]][link-downloads]
|
||||
|
||||
Created by Oscar Otero <http://oscarotero.com> <oom@oscarotero.com> (MIT License)
|
||||
|
||||
Translator functions to use with [gettext/gettext](https://github.com/php-gettext/Gettext). Useful if you don't have the native gettext extension for php or want to avoid problems with it.
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
composer require gettext/translator
|
||||
```
|
||||
|
||||
## Translator
|
||||
|
||||
```php
|
||||
use Gettext\Translator;
|
||||
|
||||
//Create a new instance of the translator
|
||||
$t = new Translator();
|
||||
|
||||
//Load the translations from php files (generated by Gettext\Extractors\PhpArray)
|
||||
$t->loadTranslations(
|
||||
'locales/gl/domain1.php',
|
||||
'locales/gl/domain2.php',
|
||||
'locales/gl/domain3.php',
|
||||
);
|
||||
|
||||
//Now you can use it in your templates
|
||||
echo $t->gettext('apple');
|
||||
```
|
||||
|
||||
## GettextTranslator
|
||||
|
||||
The class `Gettext\GettextTranslator` uses the gettext extension. It's useful because combines the performance of using real gettext functions but with the same API than `Translator` class, so you can switch to one or other translator without change code of your app.
|
||||
|
||||
```php
|
||||
use Gettext\GettextTranslator;
|
||||
|
||||
//Create a new instance
|
||||
$t = new GettextTranslator();
|
||||
|
||||
//It detects the environment variables to set the locale, but you can change it:
|
||||
$t->setLanguage('gl');
|
||||
|
||||
//Load the domains:
|
||||
$t->loadDomain('messages', 'project/Locale');
|
||||
//this means you have the file "project/Locale/gl/LC_MESSAGES/messages.po"
|
||||
|
||||
//Now you can use it in your templates
|
||||
echo $t->gettext('apple');
|
||||
```
|
||||
|
||||
## Translator functions
|
||||
|
||||
To ease the use of translations in your php templates, you can use the provided functions:
|
||||
|
||||
```php
|
||||
use Gettext\TranslatorFunctions;
|
||||
|
||||
//Register the translator to use the global functions
|
||||
TranslatorFunctions::register($t);
|
||||
|
||||
echo __('apple'); // it's the same than $t->gettext('apple');
|
||||
```
|
||||
|
||||
You can scan the php files containing these functions and extract the values with the PhpCode extractor:
|
||||
|
||||
```html
|
||||
<!-- index.php -->
|
||||
<html>
|
||||
<body>
|
||||
<?= __('Hello world'); ?>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Please see [CHANGELOG](CHANGELOG.md) for more information about recent changes and [CONTRIBUTING](CONTRIBUTING.md) for contributing details.
|
||||
|
||||
The MIT License (MIT). Please see [LICENSE](LICENSE) for more information.
|
||||
|
||||
[ico-version]: https://img.shields.io/packagist/v/gettext/translator.svg?style=flat-square
|
||||
[ico-license]: https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square
|
||||
[ico-downloads]: https://img.shields.io/packagist/dt/gettext/translator.svg?style=flat-square
|
||||
|
||||
[link-packagist]: https://packagist.org/packages/gettext/translator
|
||||
[link-downloads]: https://packagist.org/packages/gettext/translator
|
50
vendor/gettext/translator/composer.json
vendored
Normal file
50
vendor/gettext/translator/composer.json
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
"name": "gettext/translator",
|
||||
"type": "library",
|
||||
"description": "Gettext translator functions",
|
||||
"keywords": ["php", "gettext", "i18n", "translator"],
|
||||
"homepage": "https://github.com/php-gettext/Translator",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Oscar Otero",
|
||||
"email": "oom@oscarotero.com",
|
||||
"homepage": "http://oscarotero.com",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"email": "oom@oscarotero.com",
|
||||
"issues": "https://github.com/php-gettext/Translator/issues"
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^8.0",
|
||||
"gettext/gettext": "^5.0.0",
|
||||
"squizlabs/php_codesniffer": "^3.0",
|
||||
"oscarotero/php-cs-fixer-config": "^1.0",
|
||||
"friendsofphp/php-cs-fixer": "^2.15"
|
||||
},
|
||||
"suggest": {
|
||||
"gettext/gettext": "Is necessary to load and generate array files used by the translator"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Gettext\\": "src"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Gettext\\Tests\\": "tests"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"test": [
|
||||
"phpunit",
|
||||
"phpcs"
|
||||
],
|
||||
"cs-fix": "php-cs-fixer fix"
|
||||
}
|
||||
}
|
16
vendor/gettext/translator/src/Formatter.php
vendored
Normal file
16
vendor/gettext/translator/src/Formatter.php
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Gettext;
|
||||
|
||||
class Formatter implements FormatterInterface
|
||||
{
|
||||
public function format(string $text, array $args): string
|
||||
{
|
||||
if (empty($args)) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
return is_array($args[0]) ? strtr($text, $args[0]) : vsprintf($text, $args);
|
||||
}
|
||||
}
|
12
vendor/gettext/translator/src/FormatterInterface.php
vendored
Normal file
12
vendor/gettext/translator/src/FormatterInterface.php
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Gettext;
|
||||
|
||||
/**
|
||||
* Interface used by formatters.
|
||||
*/
|
||||
interface FormatterInterface
|
||||
{
|
||||
public function format(string $text, array $args): string;
|
||||
}
|
69
vendor/gettext/translator/src/Generator/ArrayGenerator.php
vendored
Normal file
69
vendor/gettext/translator/src/Generator/ArrayGenerator.php
vendored
Normal file
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Gettext\Generator;
|
||||
|
||||
use Gettext\Headers;
|
||||
use Gettext\Translation;
|
||||
use Gettext\Translations;
|
||||
|
||||
final class ArrayGenerator extends Generator
|
||||
{
|
||||
private $includeEmpty;
|
||||
|
||||
/**
|
||||
* Constructs a new ArrayGenerator
|
||||
* @param array|null $options
|
||||
*
|
||||
* bool includeEmpty Controls whether empty translations should be included (default: false)
|
||||
*/
|
||||
public function __construct(?array $options = null)
|
||||
{
|
||||
$this->includeEmpty = (bool) ($options['includeEmpty'] ?? false);
|
||||
}
|
||||
|
||||
public function generateString(Translations $translations): string
|
||||
{
|
||||
$array = $this->generateArray($translations);
|
||||
|
||||
return sprintf('<?php return %s;', var_export($array, true));
|
||||
}
|
||||
|
||||
public function generateArray(Translations $translations): array
|
||||
{
|
||||
$pluralForm = $translations->getHeaders()->getPluralForm();
|
||||
$pluralSize = is_array($pluralForm) ? ($pluralForm[0] - 1) : null;
|
||||
$messages = [];
|
||||
|
||||
foreach ($translations as $translation) {
|
||||
if ((!$this->includeEmpty && !$translation->getTranslation()) || $translation->isDisabled()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$context = $translation->getContext() ?: '';
|
||||
$original = $translation->getOriginal();
|
||||
|
||||
if (!isset($messages[$context])) {
|
||||
$messages[$context] = [];
|
||||
}
|
||||
|
||||
if (self::hasPluralTranslations($translation)) {
|
||||
$messages[$context][$original] = $translation->getPluralTranslations($pluralSize);
|
||||
array_unshift($messages[$context][$original], $translation->getTranslation());
|
||||
} else {
|
||||
$messages[$context][$original] = $translation->getTranslation();
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'domain' => $translations->getDomain(),
|
||||
'plural-forms' => $translations->getHeaders()->get(Headers::HEADER_PLURAL),
|
||||
'messages' => $messages,
|
||||
];
|
||||
}
|
||||
|
||||
private static function hasPluralTranslations(Translation $translation): bool
|
||||
{
|
||||
return implode('', $translation->getPluralTranslations()) !== '';
|
||||
}
|
||||
}
|
116
vendor/gettext/translator/src/GettextTranslator.php
vendored
Normal file
116
vendor/gettext/translator/src/GettextTranslator.php
vendored
Normal file
|
@ -0,0 +1,116 @@
|
|||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Gettext;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
class GettextTranslator implements TranslatorInterface
|
||||
{
|
||||
/**
|
||||
* Detects the current language using the environment variables.
|
||||
*/
|
||||
public function __construct(string $language = null)
|
||||
{
|
||||
if (!function_exists('gettext')) {
|
||||
throw new RuntimeException('This class require the gettext extension for PHP');
|
||||
}
|
||||
|
||||
//detects the language environment respecting the priority order
|
||||
//http://php.net/manual/en/function.gettext.php#114062
|
||||
if (empty($language)) {
|
||||
$language = getenv('LANGUAGE') ?: getenv('LC_ALL') ?: getenv('LC_MESSAGES') ?: getenv('LANG');
|
||||
}
|
||||
|
||||
if (!empty($language)) {
|
||||
$this->setLanguage($language);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the current locale.
|
||||
*/
|
||||
public function setLanguage(string $language, int $category = null): self
|
||||
{
|
||||
if ($category === null) {
|
||||
$category = defined('LC_MESSAGES') ? LC_MESSAGES : LC_ALL;
|
||||
}
|
||||
|
||||
setlocale($category, $language);
|
||||
putenv('LANGUAGE='.$language);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a gettext domain.
|
||||
*/
|
||||
public function loadDomain(string $domain, string $path = null, bool $default = true): self
|
||||
{
|
||||
bindtextdomain($domain, $path);
|
||||
bind_textdomain_codeset($domain, 'UTF-8');
|
||||
|
||||
if ($default) {
|
||||
textdomain($domain);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function noop(string $original): string
|
||||
{
|
||||
return $original;
|
||||
}
|
||||
|
||||
public function gettext(string $original): string
|
||||
{
|
||||
return gettext($original);
|
||||
}
|
||||
|
||||
public function ngettext(string $original, string $plural, int $value): string
|
||||
{
|
||||
return ngettext($original, $plural, $value);
|
||||
}
|
||||
|
||||
public function dngettext(string $domain, string $original, string $plural, int $value): string
|
||||
{
|
||||
return dngettext($domain, $original, $plural, $value);
|
||||
}
|
||||
|
||||
public function npgettext(string $context, string $original, string $plural, int $value): string
|
||||
{
|
||||
$message = $context."\x04".$original;
|
||||
$translation = ngettext($message, $plural, $value);
|
||||
|
||||
return ($translation === $message) ? $original : $translation;
|
||||
}
|
||||
|
||||
public function pgettext(string $context, string $original): string
|
||||
{
|
||||
$message = $context."\x04".$original;
|
||||
$translation = gettext($message);
|
||||
|
||||
return ($translation === $message) ? $original : $translation;
|
||||
}
|
||||
|
||||
public function dgettext(string $domain, string $original): string
|
||||
{
|
||||
return dgettext($domain, $original);
|
||||
}
|
||||
|
||||
public function dpgettext(string $domain, string $context, string $original): string
|
||||
{
|
||||
$message = $context."\x04".$original;
|
||||
$translation = dgettext($domain, $message);
|
||||
|
||||
return ($translation === $message) ? $original : $translation;
|
||||
}
|
||||
|
||||
public function dnpgettext(string $domain, string $context, string $original, string $plural, int $value): string
|
||||
{
|
||||
$message = $context."\x04".$original;
|
||||
$translation = dngettext($domain, $message, $plural, $value);
|
||||
|
||||
return ($translation === $message) ? $original : $translation;
|
||||
}
|
||||
}
|
72
vendor/gettext/translator/src/Loader/ArrayLoader.php
vendored
Normal file
72
vendor/gettext/translator/src/Loader/ArrayLoader.php
vendored
Normal file
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Gettext\Loader;
|
||||
|
||||
use BadMethodCallException;
|
||||
use Gettext\Headers;
|
||||
use Gettext\Translations;
|
||||
|
||||
/**
|
||||
* Class to load a array file
|
||||
*/
|
||||
final class ArrayLoader extends Loader
|
||||
{
|
||||
public function loadFile(string $filename, Translations $translations = null): Translations
|
||||
{
|
||||
$array = self::includeSafe($filename);
|
||||
|
||||
return $this->loadArray($array, $translations);
|
||||
}
|
||||
|
||||
public function loadString(string $string, Translations $translations = null): Translations
|
||||
{
|
||||
throw new BadMethodCallException('Arrays cannot be loaded from string. Use ArrayLoader::loadFile() instead');
|
||||
}
|
||||
|
||||
private static function includeSafe($filename): array
|
||||
{
|
||||
return include $filename;
|
||||
}
|
||||
|
||||
public function loadArray(array $array, Translations $translations = null): Translations
|
||||
{
|
||||
if (!$translations) {
|
||||
$translations = $this->createTranslations();
|
||||
}
|
||||
|
||||
$messages = $array['messages'] ?? [];
|
||||
|
||||
foreach ($messages as $context => $contextTranslations) {
|
||||
if ($context === '') {
|
||||
$context = null;
|
||||
}
|
||||
|
||||
foreach ($contextTranslations as $original => $value) {
|
||||
if ($original === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$translation = $this->createTranslation($context, $original);
|
||||
$translations->add($translation);
|
||||
|
||||
if (is_array($value)) {
|
||||
$translation->translate(array_shift($value));
|
||||
$translation->translatePlural(...$value);
|
||||
} else {
|
||||
$translation->translate($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($array['domain'])) {
|
||||
$translations->setDomain($array['domain']);
|
||||
}
|
||||
|
||||
if (!empty($array['plural-forms'])) {
|
||||
$translations->getHeaders()->set(Headers::HEADER_PLURAL, $array['plural-forms']);
|
||||
}
|
||||
|
||||
return $translations;
|
||||
}
|
||||
}
|
231
vendor/gettext/translator/src/Translator.php
vendored
Normal file
231
vendor/gettext/translator/src/Translator.php
vendored
Normal file
|
@ -0,0 +1,231 @@
|
|||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Gettext;
|
||||
|
||||
use Gettext\Generator\ArrayGenerator;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class Translator implements TranslatorInterface
|
||||
{
|
||||
protected $domain;
|
||||
protected $dictionary = [];
|
||||
protected $plurals = [];
|
||||
|
||||
public static function createFromTranslations(Translations ...$allTranslations): Translator
|
||||
{
|
||||
$translator = new static();
|
||||
$arrayGenerator = new ArrayGenerator();
|
||||
|
||||
foreach ($allTranslations as $translations) {
|
||||
$translator->addTranslations(
|
||||
$arrayGenerator->generateArray($translations)
|
||||
);
|
||||
}
|
||||
|
||||
return $translator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load new translations from php files
|
||||
*/
|
||||
public function loadTranslations(string ...$files): self
|
||||
{
|
||||
foreach ($files as $file) {
|
||||
$translations = include $file;
|
||||
|
||||
if (!is_array($translations)) {
|
||||
throw new InvalidArgumentException('Invalid translations file: it must return an array');
|
||||
}
|
||||
|
||||
$this->addTranslations($translations);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new translations to the dictionary.
|
||||
*/
|
||||
public function addTranslations(array $translations): self
|
||||
{
|
||||
$domain = $translations['domain'] ?? '';
|
||||
|
||||
//Set the first domain loaded as default domain
|
||||
if ($this->domain === null) {
|
||||
$this->domain = $domain;
|
||||
}
|
||||
|
||||
if (isset($this->dictionary[$domain])) {
|
||||
$this->dictionary[$domain] = array_replace_recursive($this->dictionary[$domain], $translations['messages']);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
if (!empty($translations['plural-forms'])) {
|
||||
list($count, $code) = array_map('trim', explode(';', $translations['plural-forms'], 2));
|
||||
|
||||
// extract just the expression turn 'n' into a php variable '$n'.
|
||||
// Slap on a return keyword and semicolon at the end.
|
||||
$this->plurals[$domain] = [
|
||||
'count' => (int) str_replace('nplurals=', '', $count),
|
||||
'code' => 'return ' . static::fixTerseIfs(rtrim(str_replace('plural=', '', $code), ';')) . ';',
|
||||
];
|
||||
}
|
||||
|
||||
$this->dictionary[$domain] = $translations['messages'];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default domain.
|
||||
*/
|
||||
public function defaultDomain(string $domain): self
|
||||
{
|
||||
$this->domain = $domain;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function noop(string $original): string
|
||||
{
|
||||
return $original;
|
||||
}
|
||||
|
||||
public function gettext(string $original): string
|
||||
{
|
||||
return $this->translate(null, null, $original);
|
||||
}
|
||||
|
||||
public function ngettext(string $original, string $plural, int $value): string
|
||||
{
|
||||
return $this->translatePlural(null, null, $original, $plural, $value);
|
||||
}
|
||||
|
||||
public function dngettext(string $domain, string $original, string $plural, int $value): string
|
||||
{
|
||||
return $this->translatePlural($domain, null, $original, $plural, $value);
|
||||
}
|
||||
|
||||
public function npgettext(string $context, string $original, string $plural, int $value): string
|
||||
{
|
||||
return $this->translatePlural(null, $context, $original, $plural, $value);
|
||||
}
|
||||
|
||||
public function pgettext(string $context, string $original): string
|
||||
{
|
||||
return $this->translate(null, $context, $original);
|
||||
}
|
||||
|
||||
public function dgettext(string $domain, string $original): string
|
||||
{
|
||||
return $this->translate($domain, null, $original);
|
||||
}
|
||||
|
||||
public function dpgettext(string $domain, string $context, string $original): string
|
||||
{
|
||||
return $this->translate($domain, $context, $original);
|
||||
}
|
||||
|
||||
public function dnpgettext(string $domain, string $context, string $original, string $plural, int $value): string
|
||||
{
|
||||
return $this->translatePlural($domain, $context, $original, $plural, $value);
|
||||
}
|
||||
|
||||
protected function translate(?string $domain, ?string $context, string $original): string
|
||||
{
|
||||
$translation = $this->getTranslation($domain, $context, $original);
|
||||
|
||||
if (isset($translation[0]) && $translation[0] !== '') {
|
||||
return $translation[0];
|
||||
}
|
||||
|
||||
return $original;
|
||||
}
|
||||
|
||||
protected function translatePlural(
|
||||
?string $domain,
|
||||
?string $context,
|
||||
string $original,
|
||||
string $plural,
|
||||
int $value
|
||||
): string {
|
||||
$translation = $this->getTranslation($domain, $context, $original);
|
||||
$key = $this->getPluralIndex($domain, $value, $translation === null);
|
||||
|
||||
if (isset($translation[$key]) && $translation[$key] !== '') {
|
||||
return $translation[$key];
|
||||
}
|
||||
|
||||
return ($key === 0) ? $original : $plural;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search and returns a translation.
|
||||
*/
|
||||
protected function getTranslation(?string $domain, ?string $context, string $original): ?array
|
||||
{
|
||||
if ($domain === null) {
|
||||
$domain = $this->domain;
|
||||
}
|
||||
|
||||
if ($context === null) {
|
||||
$context = '';
|
||||
}
|
||||
|
||||
$translation = $this->dictionary[$domain][$context][$original] ?? null;
|
||||
|
||||
return $translation === null ? $translation : (array) $translation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the plural decision code given the number to decide which
|
||||
* plural version to take.
|
||||
*/
|
||||
protected function getPluralIndex(?string $domain, int $n, bool $fallback): int
|
||||
{
|
||||
if ($domain === null) {
|
||||
$domain = $this->domain;
|
||||
}
|
||||
|
||||
//Not loaded domain or translation, use a fallback
|
||||
if (!isset($this->plurals[$domain]) || $fallback === true) {
|
||||
return $n == 1 ? 0 : 1;
|
||||
}
|
||||
|
||||
if (!isset($this->plurals[$domain]['function'])) {
|
||||
$code = $this->plurals[$domain]['code'];
|
||||
$this->plurals[$domain]['function'] = eval("return function (\$n) { $code };");
|
||||
}
|
||||
|
||||
if ($this->plurals[$domain]['count'] <= 2) {
|
||||
return call_user_func($this->plurals[$domain]['function'], $n) ? 1 : 0;
|
||||
}
|
||||
|
||||
return call_user_func($this->plurals[$domain]['function'], $n);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function prepares the gettext plural form expression to be evaluated by PHP
|
||||
*
|
||||
* Nested ternary IFs will be enclosed by parenthesis and the variable "n" will be prefixed by "$".
|
||||
*
|
||||
* $n==1 ? 0 : $n%10>=2 && $n%10<=4 && ($n%100<10 || $n%100>=20) ? 1 : 2
|
||||
* becomes
|
||||
* $n==1 ? 0 : ($n%10>=2 && $n%10<=4 && ($n%100<10 || $n%100>=20) ? 1 : 2)
|
||||
*/
|
||||
private static function fixTerseIfs(string $pluralForms): string
|
||||
{
|
||||
if (preg_match('/[^<>|%&!?:=n()\d\s]/', $pluralForms)) {
|
||||
throw new InvalidArgumentException('Invalid plural form expression');
|
||||
}
|
||||
$pieces = explode(':', str_replace('n', '$n', $pluralForms));
|
||||
$last = array_pop($pieces);
|
||||
$pluralForms = '';
|
||||
foreach ($pieces as $piece) {
|
||||
$pluralForms .= "$piece:(";
|
||||
}
|
||||
return $pluralForms . $last . str_repeat(')', count($pieces));
|
||||
}
|
||||
}
|
28
vendor/gettext/translator/src/TranslatorFunctions.php
vendored
Normal file
28
vendor/gettext/translator/src/TranslatorFunctions.php
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Gettext;
|
||||
|
||||
abstract class TranslatorFunctions
|
||||
{
|
||||
private static $translator;
|
||||
private static $formatter;
|
||||
|
||||
public static function register(TranslatorInterface $translator, FormatterInterface $formatter = null): void
|
||||
{
|
||||
self::$translator = $translator;
|
||||
self::$formatter = $formatter ?: new Formatter();
|
||||
|
||||
include_once __DIR__.'/functions.php';
|
||||
}
|
||||
|
||||
public static function getTranslator(): TranslatorInterface
|
||||
{
|
||||
return self::$translator;
|
||||
}
|
||||
|
||||
public static function getFormatter(): FormatterInterface
|
||||
{
|
||||
return self::$formatter;
|
||||
}
|
||||
}
|
55
vendor/gettext/translator/src/TranslatorInterface.php
vendored
Normal file
55
vendor/gettext/translator/src/TranslatorInterface.php
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Gettext;
|
||||
|
||||
/**
|
||||
* Interface used by all translators.
|
||||
*/
|
||||
interface TranslatorInterface
|
||||
{
|
||||
/**
|
||||
* Noop, marks the string for translation but returns it unchanged.
|
||||
*/
|
||||
public function noop(string $original): string;
|
||||
|
||||
/**
|
||||
* Gets a translation using the original string.
|
||||
*/
|
||||
public function gettext(string $original): string;
|
||||
|
||||
/**
|
||||
* Gets a translation checking the plural form.
|
||||
*/
|
||||
public function ngettext(string $original, string $plural, int $value): string;
|
||||
|
||||
/**
|
||||
* Gets a translation checking the domain and the plural form.
|
||||
*/
|
||||
public function dngettext(string $domain, string $original, string $plural, int $value): string;
|
||||
|
||||
/**
|
||||
* Gets a translation checking the context and the plural form.
|
||||
*/
|
||||
public function npgettext(string $context, string $original, string $plural, int $value): string;
|
||||
|
||||
/**
|
||||
* Gets a translation checking the context.
|
||||
*/
|
||||
public function pgettext(string $context, string $original): string;
|
||||
|
||||
/**
|
||||
* Gets a translation checking the domain.
|
||||
*/
|
||||
public function dgettext(string $domain, string $original): string;
|
||||
|
||||
/**
|
||||
* Gets a translation checking the domain and context.
|
||||
*/
|
||||
public function dpgettext(string $domain, string $context, string $original): string;
|
||||
|
||||
/**
|
||||
* Gets a translation checking the domain, the context and the plural form.
|
||||
*/
|
||||
public function dnpgettext(string $domain, string $context, string $original, string $plural, int $value);
|
||||
}
|
102
vendor/gettext/translator/src/functions.php
vendored
Normal file
102
vendor/gettext/translator/src/functions.php
vendored
Normal file
|
@ -0,0 +1,102 @@
|
|||
<?php
|
||||
|
||||
use Gettext\TranslatorFunctions as Translator;
|
||||
|
||||
if (!function_exists('__')) {
|
||||
/**
|
||||
* Returns the translation of a string.
|
||||
*/
|
||||
function __(string $original, ...$args): string
|
||||
{
|
||||
$text = Translator::getTranslator()->gettext($original);
|
||||
return Translator::getFormatter()->format($text, $args);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('noop__')) {
|
||||
/**
|
||||
* Noop, marks the string for translation but returns it unchanged.
|
||||
*/
|
||||
function noop__(string $original, ...$args): string
|
||||
{
|
||||
$text = Translator::getTranslator()->noop($original);
|
||||
return Translator::getFormatter()->format($text, $args);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('n__')) {
|
||||
/**
|
||||
* Returns the singular/plural translation of a string.
|
||||
*/
|
||||
function n__(string $original, string $plural, int $value, ...$args): string
|
||||
{
|
||||
$text = Translator::getTranslator()->ngettext($original, $plural, $value);
|
||||
return Translator::getFormatter()->format($text, $args);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('p__')) {
|
||||
/**
|
||||
* Returns the translation of a string in a specific context.
|
||||
*/
|
||||
function p__(string $context, string $original, ...$args): string
|
||||
{
|
||||
$text = Translator::getTranslator()->pgettext($context, $original);
|
||||
return Translator::getFormatter()->format($text, $args);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('d__')) {
|
||||
/**
|
||||
* Returns the translation of a string in a specific domain.
|
||||
*/
|
||||
function d__(string $domain, string $original, ...$args): string
|
||||
{
|
||||
$text = Translator::getTranslator()->dgettext($domain, $original);
|
||||
return Translator::getFormatter()->format($text, $args);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('dp__')) {
|
||||
/**
|
||||
* Returns the translation of a string in a specific domain and context.
|
||||
*/
|
||||
function dp__(string $domain, string $context, string $original, ...$args): string
|
||||
{
|
||||
$text = Translator::getTranslator()->dpgettext($domain, $context, $original);
|
||||
return Translator::getFormatter()->format($text, $args);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('dn__')) {
|
||||
/**
|
||||
* Returns the singular/plural translation of a string in a specific domain.
|
||||
*/
|
||||
function dn__(string $domain, string $original, string $plural, int $value, ...$args): string
|
||||
{
|
||||
$text = Translator::getTranslator()->dngettext($domain, $original, $plural, $value);
|
||||
return Translator::getFormatter()->format($text, $args);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('np__')) {
|
||||
/**
|
||||
* Returns the singular/plural translation of a string in a specific context.
|
||||
*/
|
||||
function np__(string $context, string $original, string $plural, int $value, ...$args): string
|
||||
{
|
||||
$text = Translator::getTranslator()->npgettext($context, $original, $plural, $value);
|
||||
return Translator::getFormatter()->format($text, $args);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('dnp__')) {
|
||||
/**
|
||||
* Returns the singular/plural translation of a string in a specific domain and context.
|
||||
*/
|
||||
function dnp__(string $domain, string $context, string $original, string $plural, int $value, ...$args): string
|
||||
{
|
||||
$text = Translator::getTranslator()->dnpgettext($domain, $context, $original, $plural, $value);
|
||||
return Translator::getFormatter()->format($text, $args);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue