Skip to content

Commit

Permalink
Add Translator::setLocale() method
Browse files Browse the repository at this point in the history
The Translator::setLocale() takes precedence over $GLOBALS['lang'].
This makes possible to deprecate the usage of the $GLOBALS['lang'].

Signed-off-by: Maurício Meneghini Fauth <[email protected]>
  • Loading branch information
MauricioFauth committed Nov 16, 2024
1 parent 0923ebf commit c1044be
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 10 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ LC_ALL=pl ./vendor/bin/lint-query --query "SELECT 1"
```php
require __DIR__ . '/vendor/autoload.php';

$GLOBALS['lang'] = 'pl';
PhpMyAdmin\SqlParser\Translator::setLocale('pl');

$query1 = 'select * from a';
$parser = new PhpMyAdmin\SqlParser\Parser($query1);
Expand Down
38 changes: 31 additions & 7 deletions src/Translator.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
namespace PhpMyAdmin\SqlParser;

use PhpMyAdmin\MoTranslator\Loader;
use PhpMyAdmin\MoTranslator\Translator as MoTranslator;
use RuntimeException;

use function assert;
use function class_exists;

/**
Expand All @@ -16,32 +19,42 @@ class Translator
/**
* The MoTranslator loader object.
*
* @var Loader
* @var Loader|null
*/
private static $loader;

/**
* The MoTranslator translator object.
*
* @var \PhpMyAdmin\MoTranslator\Translator
* @var MoTranslator|null
*/
private static $translator;

/** @var string */
private static $locale = '';

/**
* Loads translator.
*
* @internal This method is not covered by the backward compatibility promise for SQL-Parser
*
* @return void
*/
public static function load()
{
if (! class_exists(Loader::class)) {
throw new RuntimeException('The phpmyadmin/motranslator package is missing.');
}

if (self::$loader === null) {
// Create loader object
self::$loader = new Loader();

// Set locale
self::$loader->setlocale(
self::$loader->detectlocale()
);
if (self::$locale === '') {
self::$locale = self::$loader->detectlocale();
}

self::$loader->setlocale(self::$locale);

// Set default text domain
self::$loader->textdomain('sqlparser');
Expand All @@ -67,12 +80,23 @@ public static function load()
*/
public static function gettext($msgid)
{
if (! class_exists('\PhpMyAdmin\MoTranslator\Loader', true)) {
if (! class_exists(Loader::class)) {
return $msgid;
}

self::load();
assert(self::$translator instanceof MoTranslator);

return self::$translator->gettext($msgid);
}

public static function setLocale(string $locale): void
{
self::$locale = $locale;
}

public static function getLocale(): string
{
return self::$locale;
}
}
107 changes: 107 additions & 0 deletions tests/Misc/TranslatorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?php

declare(strict_types=1);

namespace PhpMyAdmin\SqlParser\Tests\Misc;

use PhpMyAdmin\MoTranslator\Loader;
use PhpMyAdmin\MoTranslator\Translator as MoTranslator;
use PhpMyAdmin\SqlParser\Translator;
use PHPUnit\Framework\TestCase;
use ReflectionClass;
use ReflectionProperty;

use function realpath;

/** @covers \PhpMyAdmin\SqlParser\Translator */
final class TranslatorTest extends TestCase
{
public static function tearDownAfterClass(): void
{
$loaderProperty = new ReflectionProperty(Translator::class, 'loader');
$loaderProperty->setAccessible(true);
$loaderProperty->setValue(null, null);
$translatorProperty = new ReflectionProperty(Translator::class, 'translator');
$translatorProperty->setAccessible(true);
$translatorProperty->setValue(null, null);
Translator::setLocale('en');
}

public function testLocale(): void
{
Translator::setLocale('en');
self::assertSame('en', Translator::getLocale());
Translator::setLocale('fr');
self::assertSame('fr', Translator::getLocale());
Translator::setLocale('');
self::assertSame('', Translator::getLocale());
}

/**
* @testWith [null, "en", "en"]
* [null, "fr", "fr"]
* ["en", "", "en"]
* ["fr", "", "fr"]
*/
public function testLoad(?string $globalLang, string $locale, string $expectedLocale): void
{
$loaderProperty = new ReflectionProperty(Translator::class, 'loader');
$loaderProperty->setAccessible(true);
$loaderProperty->setValue(null, null);
$translatorProperty = new ReflectionProperty(Translator::class, 'translator');
$translatorProperty->setAccessible(true);
$translatorProperty->setValue(null, null);
$GLOBALS['lang'] = $globalLang;
Translator::setLocale($locale);

Translator::load();

self::assertSame($expectedLocale, Translator::getLocale());
self::assertInstanceOf(MoTranslator::class, $translatorProperty->getValue());
$loader = $loaderProperty->getValue();
self::assertInstanceOf(Loader::class, $loader);
$loaderClass = new ReflectionClass(Loader::class);
$localeProperty = $loaderClass->getProperty('locale');
$localeProperty->setAccessible(true);
self::assertSame($expectedLocale, $localeProperty->getValue($loader));
// Compatibility with MoTranslator < 5
$defaultDomainProperty = $loaderClass->hasProperty('default_domain')
? $loaderClass->getProperty('default_domain')
: $loaderClass->getProperty('defaultDomain');
$defaultDomainProperty->setAccessible(true);
self::assertSame('sqlparser', $defaultDomainProperty->getValue($loader));
$pathsProperty = $loaderClass->getProperty('paths');
$pathsProperty->setAccessible(true);
self::assertSame(
['' => './', 'sqlparser' => realpath(__DIR__ . '/../../src/') . '/../locale/'],
$pathsProperty->getValue($loader)
);
}

public function testGettext(): void
{
$loaderProperty = new ReflectionProperty(Translator::class, 'loader');
$loaderProperty->setAccessible(true);
$loaderProperty->setValue(null, null);
$translatorProperty = new ReflectionProperty(Translator::class, 'translator');
$translatorProperty->setAccessible(true);
$translatorProperty->setValue(null, null);
Translator::setLocale('pt_BR');
self::assertSame(
'Início de declaração inesperado.',
Translator::gettext('Unexpected beginning of statement.')
);

$loaderProperty = new ReflectionProperty(Translator::class, 'loader');
$loaderProperty->setAccessible(true);
$loaderProperty->setValue(null, null);
$translatorProperty = new ReflectionProperty(Translator::class, 'translator');
$translatorProperty->setAccessible(true);
$translatorProperty->setValue(null, null);
Translator::setLocale('en');
self::assertSame(
'Unexpected beginning of statement.',
Translator::gettext('Unexpected beginning of statement.')
);
}
}
4 changes: 2 additions & 2 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use PhpMyAdmin\SqlParser\Token;
use PhpMyAdmin\SqlParser\TokensList;
use PhpMyAdmin\SqlParser\Tools\CustomJsonSerializer;
use PhpMyAdmin\SqlParser\Translator;
use PHPUnit\Framework\TestCase as BaseTestCase;

use function file_get_contents;
Expand All @@ -26,13 +27,12 @@ abstract class TestCase extends BaseTestCase
{
public function setUp(): void
{
global $lang;
// This line makes sure the test suite uses English so we can assert
// on the error messages, if it is not here you will need to use
// LC_ALL=C ./vendor/bin/phpunit
// Users can have French language as default on their OS
// That would make the assertions fail
$lang = 'en';
Translator::setLocale('en');
Context::load();
}

Expand Down

0 comments on commit c1044be

Please sign in to comment.