Skip to content

Commit 57e54cf

Browse files
committed
[TASK] implement Symfony Translation Loader concept
solves: #15
1 parent 180ba28 commit 57e54cf

File tree

6 files changed

+122
-81
lines changed

6 files changed

+122
-81
lines changed

.github/workflows/release.yml

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
name: release
22

33
on:
4-
push:
5-
tags:
6-
- "**"
4+
push:
5+
tags:
6+
- "**"
77

88
jobs:
9-
terUpload:
10-
runs-on: ubuntu-latest
11-
steps:
12-
- uses: actions/checkout@v4
13-
- uses: tomasnorre/typo3-upload-ter@v2.0.7
14-
with:
15-
api-token: ${{ secrets.TYPO3_API_TOKEN }}
9+
terUpload:
10+
runs-on: ubuntu-latest
11+
steps:
12+
-
13+
uses: actions/checkout@v4
14+
-
15+
uses: tomasnorre/typo3-upload-ter@v2.0.7
16+
with:
17+
api-token: ${{ secrets.TYPO3_API_TOKEN }}

Classes/Localization/CsvLocalizationParser.php

Lines changed: 0 additions & 57 deletions
This file was deleted.
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
declare(strict_types=1);
3+
namespace Sitegeist\CsvLabels\Translation\Loader;
4+
5+
use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;
6+
use Symfony\Component\Translation\Exception\InvalidResourceException;
7+
use Symfony\Component\Translation\Exception\NotFoundResourceException;
8+
use Symfony\Component\Translation\Loader\LoaderInterface;
9+
use Symfony\Component\Translation\MessageCatalogue;
10+
use TYPO3\CMS\Core\Localization\Locales;
11+
use TYPO3\CMS\Core\Utility\GeneralUtility;
12+
13+
#[Autoconfigure(tags: [['name' => 'translation.loader', 'format' => 'csv']])]
14+
class CsvLoader implements LoaderInterface
15+
{
16+
private ?Locales $locales = null;
17+
18+
public function load(mixed $resource, string $locale, string $domain = 'messages'): MessageCatalogue
19+
{
20+
if (!file_exists($resource)) {
21+
throw new NotFoundResourceException(\sprintf('File "%s" not found.', $resource), 1612282091);
22+
}
23+
24+
try {
25+
$file = new \SplFileObject($resource, 'r');
26+
$file->setFlags(\SplFileObject::READ_CSV | \SplFileObject::SKIP_EMPTY);
27+
} catch (\RuntimeException $e) {
28+
throw new InvalidResourceException(\sprintf('File "%s" could not be opened.', $resource), 1767019766, $e);
29+
}
30+
31+
if (!$file->valid()) {
32+
throw new InvalidResourceException(\sprintf('File "%s" has invalid CSV content.', $resource), 1767623886);
33+
}
34+
35+
$csvHeader = $file->current();
36+
if ($csvHeader === false) {
37+
return new MessageCatalogue($locale);
38+
}
39+
40+
$this->locales = GeneralUtility::makeInstance(Locales::class);
41+
$localeColumnIndex = $this->searchLocaleColumnIndex($csvHeader, $locale);
42+
if ($localeColumnIndex === false) {
43+
return new MessageCatalogue($locale);
44+
}
45+
46+
foreach ($file as $lineNumber => $translation) {
47+
if ($lineNumber === 0 || empty($translation[0])) {
48+
continue;
49+
}
50+
$identifier = $translation[0];
51+
if (isset($translation[$localeColumnIndex]) && $translation[$localeColumnIndex] !== '') {
52+
$messages[$identifier] = $translation[$localeColumnIndex];
53+
}
54+
}
55+
56+
return new MessageCatalogue($locale, [$domain => $messages]);
57+
}
58+
59+
private function searchLocaleColumnIndex(array $csvHeader, string $locale): int|false
60+
{
61+
$localeChain = $this->buildLocaleFallbackChain($locale, $this->locales);
62+
63+
foreach ($localeChain as $currentLocale) {
64+
$index = array_search($currentLocale, $csvHeader, true);
65+
if ($index !== false) {
66+
return $index;
67+
}
68+
}
69+
70+
return false;
71+
}
72+
73+
private function buildLocaleFallbackChain(string $locale, Locales $locales): array
74+
{
75+
$chain = [$locale];
76+
77+
// e.g. de-DE -> de
78+
if (str_contains($locale, '-')) {
79+
[$baseLanguage] = explode('-', $locale, 2);
80+
$chain[] = $baseLanguage;
81+
} elseif (str_contains($locale, '_')) {
82+
[$baseLanguage] = explode('_', $locale, 2);
83+
$chain[] = $baseLanguage;
84+
}
85+
86+
$chain = array_merge($chain, $this->locales->getLocaleDependencies($locale));
87+
88+
$chain[] = 'default';
89+
90+
return array_unique($chain);
91+
}
92+
}

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"issues": "https://github.com/sitegeist/csv-labels/issues"
1919
},
2020
"require": {
21-
"typo3/cms-core": "^13.1 || ^12.2 || ^11.5 || ^10.4 || ^9.5"
21+
"typo3/cms-core": "^14"
2222
},
2323
"require-dev": {
2424
"squizlabs/php_codesniffer": "^3.0",

ext_emconf.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
'version' => '',
1313
'constraints' => [
1414
'depends' => [
15-
'typo3' => '9.5.0-13.9.99',
15+
'typo3' => '14.0.0-14.9.99',
1616
'php' => '7.4.0-8.9.99'
1717
],
1818
'conflicts' => [

ext_localconf.php

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
<?php
2+
declare(strict_types=1);
23

3-
call_user_func(function () {
4-
// Add csv files to language format priorities
5-
$languageFilePriority = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(
6-
',',
7-
$GLOBALS['TYPO3_CONF_VARS']['SYS']['lang']['format']['priority']
8-
);
9-
$languageFilePriority[] = 'csv';
10-
$GLOBALS['TYPO3_CONF_VARS']['SYS']['lang']['format']['priority'] = implode(',', $languageFilePriority);
11-
12-
// Register CSV parser for language files
13-
$GLOBALS['TYPO3_CONF_VARS']['SYS']['lang']['parser']['csv'] = \Sitegeist\CsvLabels\Localization\CsvLocalizationParser::class;
14-
});
4+
use Sitegeist\CsvLabels\Translation\Loader\CsvLoader;
5+
use TYPO3\CMS\Core\Utility\GeneralUtility;
6+
7+
defined('TYPO3') or die();
8+
9+
// Add csv files to language format priorities
10+
$languageFilePriority = GeneralUtility::trimExplode(
11+
',',
12+
$GLOBALS['TYPO3_CONF_VARS']['LANG']['format']['priority']
13+
);
14+
$languageFilePriority[] = 'csv';
15+
$GLOBALS['TYPO3_CONF_VARS']['LANG']['format']['priority'] = implode(',', $languageFilePriority);
16+
17+
// Register CSV loader for language files
18+
$GLOBALS['TYPO3_CONF_VARS']['LANG']['loader']['csv'] = CsvLoader::class;

0 commit comments

Comments
 (0)