Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make module Translator usable on Storybook #809

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
->setUsingCache(true)
->getFinder()
->in(__DIR__)
->exclude('vendor');
->exclude('vendor')
->exclude('node_modules');

return $config;
5 changes: 4 additions & 1 deletion autoupgrade.php
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,10 @@ public function trans($id, array $parameters = [], $domain = null, $locale = nul
{
require_once _PS_ROOT_DIR_ . '/modules/autoupgrade/classes/UpgradeTools/Translator.php';

$translator = new \PrestaShop\Module\AutoUpgrade\UpgradeTools\Translator();
$translator = new \PrestaShop\Module\AutoUpgrade\UpgradeTools\Translator(
_PS_ROOT_DIR_ . 'modules' . DIRECTORY_SEPARATOR . 'autoupgrade' . DIRECTORY_SEPARATOR . 'translations' . DIRECTORY_SEPARATOR,
\Context::getContext()->language->iso_code
);

return $translator->trans($id, $parameters);
}
Expand Down
11 changes: 10 additions & 1 deletion classes/UpgradeContainer.php
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,16 @@ public function getTranslationAdapter(): Translation

public function getTranslator(): Translator
{
return new Translator();
$locale = null;
// @phpstan-ignore booleanAnd.rightAlwaysTrue (If PrestaShop core is not instantiated properly, do not try to translate)
if (method_exists('\Context', 'getContext') && \Context::getContext()->language) {
$locale = \Context::getContext()->language->iso_code;
}

return new Translator(
$this->getProperty(self::PS_ROOT_PATH) . DIRECTORY_SEPARATOR . 'modules' . DIRECTORY_SEPARATOR . 'autoupgrade' . DIRECTORY_SEPARATOR . 'translations' . DIRECTORY_SEPARATOR,
$locale
);
}

/**
Expand Down
31 changes: 19 additions & 12 deletions classes/UpgradeTools/Translator.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,28 @@

class Translator
{
const DEFAULT_LANGUAGE = 'en';
/**
* @var array<string,string>
*/
private $translations = [];

/** @var string */
private $locale;

/** @var string */
private $translationsFilesPath;

/**
* @param string $translationsFilesPath
* @param string $locale
*/
public function __construct($translationsFilesPath, $locale = self::DEFAULT_LANGUAGE)
{
$this->locale = $locale;
$this->translationsFilesPath = $translationsFilesPath;
}

/**
* Load translations from XLF files.
*
Expand All @@ -20,13 +37,8 @@ class Translator
*/
private function loadTranslations()
{
$language = \Context::getContext()->language->iso_code;

// Adjust the path to your XLF files as necessary
$basePath = _PS_MODULE_DIR_ . 'autoupgrade/translations/ModulesAutoupgradeAdmin';

// use generic language file (e.g., fr)
$path = $basePath . '.' . $language . '.xlf';
$path = $this->translationsFilesPath . "ModulesAutoupgradeAdmin.{$this->locale}.xlf";
if (file_exists($path)) {
$this->loadXlfFile($path);
}
Expand Down Expand Up @@ -63,11 +75,6 @@ private function loadXlfFile($filePath)
*/
public function trans($id, array $parameters = [], $domain = null, $locale = null)
{
// If PrestaShop core is not instantiated properly, do not try to translate
if (!method_exists('\Context', 'getContext') || null === \Context::getContext()->language) {
return $this->applyParameters($id, $parameters);
}

if (empty($this->translations)) {
try {
$this->loadTranslations();
Expand Down Expand Up @@ -111,6 +118,6 @@ public function applyParameters($id, array $parameters = [])
*/
public function getLocale()
{
return \Context::getContext()->language->locale;
return $this->locale;
}
}
4 changes: 4 additions & 0 deletions storybook/.storybook/global.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/**
* List all the available locales in the translations/ folder
*/
declare const TRANSLATION_LOCALES: string[];
20 changes: 20 additions & 0 deletions storybook/.storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
*/

import type { StorybookConfig } from "@sensiolabs/storybook-symfony-webpack5";
import webpack from "webpack";
import fs from 'fs';
import path from 'path';

const config: StorybookConfig = {
stories: ["../stories/**/*.stories.[tj]s", "../stories/**/*.mdx"],
Expand All @@ -45,6 +48,23 @@ const config: StorybookConfig = {
},
},
},
webpackFinal: async (config) => {
// List translations files on compilation to fill language selection list
const newPlugin = new webpack.DefinePlugin({
TRANSLATION_LOCALES: JSON.stringify(
fs.readdirSync(path.resolve(__dirname, '../../translations'))
.map((file) => new RegExp("^ModulesAutoupgradeAdmin.([a-z]+).xlf$", "i").exec(file)?.[1])
.filter((locale) => !!locale)
),
});
if (config.plugins?.length) {
config.plugins.push(newPlugin);
} else {
config.plugins = [newPlugin];
}

return config;
},
docs: {
autodocs: "tag",
},
Expand Down
18 changes: 18 additions & 0 deletions storybook/.storybook/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,24 @@ const preview: Preview = {
})),
},
},
_locale: {
description: 'Internationalization locale',
defaultValue: 'en',
toolbar: {
icon: 'globe',
items: TRANSLATION_LOCALES.map((languageLocale) => ({
value: languageLocale,
title: new Intl.DisplayNames(
[navigator.language || 'en'],
{type: 'language'},
).of(languageLocale),
right: String.fromCodePoint(...({'en': 'gb', 'cs': 'cz'}[languageLocale] || languageLocale)
.toUpperCase()
.split('')
.map(char => 127397 + char.charCodeAt())),
})),
},
},
},
decorators: [
(story, context) => {
Expand Down
24 changes: 24 additions & 0 deletions storybook/config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,34 @@ services:
autowire: true
autoconfigure: true

PrestaShop\Module\AutoUpgrade\:
resource: '../../classes'
exclude: '../../classes/**/index.php'

# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/'
exclude:
- '../src/DependencyInjection/'
- '../src/Entity/'
- '../src/Kernel.php'

App\EventListener\LocaleListener:
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: 50 }

PrestaShop\Module\AutoUpgrade\UpgradeTools\Translator:
factory: ['App\Translation\TranslatorFactory', 'createTranslator']
arguments:
- '%kernel.project_dir%/../translations/'
- '@request_stack'

twig.extension.trans:
class: Symfony\Bridge\Twig\Extension\TranslationExtension
arguments: ['@App\Translation\TranslatorBridge']
tags:
- { name: twig.extension }

# add more service definitions when explicit configuration is needed
# please note that last definitions always *replace* previous ones
24 changes: 24 additions & 0 deletions storybook/src/EventListener/LocaleListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace App\EventListener;

use Symfony\Component\HttpKernel\Event\RequestEvent;

class LocaleListener
{
/**
* @param RequestEvent $event
*
* @return void
*/
public function onKernelRequest(RequestEvent $event): void
{
$request = $event->getRequest();

if (isset($event->getRequest()->getPayload()->all('args')['_locale'])) {
$request->setLocale(
$request->getPayload()->all('args')['_locale']
);
}
}
}
27 changes: 27 additions & 0 deletions storybook/src/Translation/TranslatorBridge.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace App\Translation;

use PrestaShop\Module\AutoUpgrade\UpgradeTools\Translator;
use Symfony\Contracts\Translation\TranslatorInterface;

class TranslatorBridge implements TranslatorInterface
{
/** @var Translator */
private $translator;

public function __construct(Translator $translator)
{
$this->translator = $translator;
}

public function trans(string $id, array $parameters = [], ?string $domain = null, ?string $locale = null): string
{
return $this->translator->trans($id, $parameters, $domain, $locale);
}

public function getLocale(): string
{
return $this->translator->getLocale();
}
}
17 changes: 17 additions & 0 deletions storybook/src/Translation/TranslatorFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace App\Translation;

use PrestaShop\Module\AutoUpgrade\UpgradeTools\Translator;
use Symfony\Component\HttpFoundation\RequestStack;

class TranslatorFactory
{
public static function createTranslator(string $translationsFilesPath, RequestStack $request): Translator
{
return new Translator(
$translationsFilesPath,
$request->getCurrentRequest() ? $request->getCurrentRequest()->getLocale() : null
);
}
}
1 change: 1 addition & 0 deletions storybook/stories/Main.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export const Default = {
translationDomain: "Modules.Autoupgrade.Admin",
jsParams: "tata",
backupOptions: "",
PS_AUTOUP_BACKUP: true,
upgradeOptions: "",
currentIndex: "index.php?controller=AdminSelfUpgrade",
token: "64e10c9ef64f54c44d510fe41bcf4328",
Expand Down
12 changes: 12 additions & 0 deletions tests/fixtures/ModulesAutoupgradeAdmin.fr.xlf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file original="classes/Task/AbstractTask.php" source-language="en" target-language="fr" datatype="plaintext">
<body>
<trans-unit id="435d516735dbf7f622c7d14585f66840" approved="yes">
<source>Action %s skipped</source>
<target state="final">L'action %s a été ignorée</target>
<note>Line: 143</note>
</trans-unit>
</body>
</file>
</xliff>
26 changes: 20 additions & 6 deletions tests/unit/UpgradeTools/Translator/TranslatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,34 @@
*/
class TranslatorTest extends TestCase
{
protected $translator;

protected function setUp()
public function testTranslationInFrench()
{
parent::setUp();
$this->translator = new Translator();
$translator = new Translator(
__DIR__ . '/../../../fixtures/',
'fr'
);

$source = 'Action %s skipped';
$parameters = ['Wololo'];

$expected = 'L\'action Wololo a été ignorée';

$this->assertSame(
$expected,
$translator->trans($source, $parameters)
);
}

/**
* @dataProvider translationsTestCaseProvider
*/
public function testTranslationWithoutParams($origin, $parameters, $expected)
{
$this->assertSame($expected, $this->translator->applyParameters($origin, $parameters));
$translator = new Translator(
__DIR__ . '/../../../../translations/',
'en'
);
$this->assertSame($expected, $translator->applyParameters($origin, $parameters));
}

public function translationsTestCaseProvider()
Expand Down