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

[TASK] Streamline factory process from glossary build function #332

Closed
wants to merge 1 commit into from
Closed
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
265 changes: 76 additions & 189 deletions Classes/Domain/Repository/GlossaryRepository.php

Large diffs are not rendered by default.

184 changes: 184 additions & 0 deletions Classes/Factory/GlossaryFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
<?php

declare(strict_types=1);

namespace WebVision\WvDeepltranslate\Factory;

use Doctrine\DBAL\Driver\Exception;
use TYPO3\CMS\Backend\Configuration\TranslationConfigurationProvider;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Exception\SiteNotFoundException;
use TYPO3\CMS\Core\Information\Typo3Version;
use TYPO3\CMS\Core\Site\SiteFinder;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use WebVision\WvDeepltranslate\Domain\Repository\GlossaryRepository;
use WebVision\WvDeepltranslate\Service\DeeplGlossaryService;

/**
* Factory object to create DeepL glossary information from TYPO3 Record/Structure
* Only glossaries language combination that are supported by the DeepL-API through "/glossary-language-pairs" are created
*/
class GlossaryFactory
{
private SiteFinder $siteFinder;

private GlossaryRepository $glossaryRepository;

private DeeplGlossaryService $deeplGlossaryService;

public function __construct(
SiteFinder $siteFinder,
GlossaryRepository $glossaryRepository,
DeeplGlossaryService $deeplGlossaryService
) {
$this->siteFinder = $siteFinder;
$this->glossaryRepository = $glossaryRepository;
$this->deeplGlossaryService = $deeplGlossaryService;
}

/**
* @param int $pageId
* @return array<int, array{
* glossary_name: string,
* uid: int,
* glossary_id: string,
* source_lang: string,
* target_lang: string,
* entries: array<int, array{source: string, target: string}>
* }>
*
* @throws Exception
* @throws \Doctrine\DBAL\Exception
* @throws SiteNotFoundException
*/
public function createGlossaryInformation(int $pageId): array
{
$glossaries = [];
$localizationArray = [];

$page = BackendUtility::getRecord('pages', $pageId, '*');
if ($page['module'] !== 'glossary') {
throw new \RuntimeException('', 1716556217634);
}

$availableLanguagePairs = $this->deeplGlossaryService->getPossibleGlossaryLanguageConfig();
$sourceLangIsoCode = $this->getDefaultLanguageCode($pageId);

$entries = $this->glossaryRepository->getOriginalEntries($pageId);

$localizationArray[$sourceLangIsoCode] = $entries;

$localizationLanguageIds = $this->getAvailableLocalizations($pageId);
// fetch all language information available for building all glossaries
foreach ($localizationLanguageIds as $localizationLanguageId) {
$localizedEntries = $this->glossaryRepository->getLocalizedEntries($pageId, $localizationLanguageId);
$targetLanguageIsoCode = $this->getTargetLanguageCode($pageId, $localizationLanguageId);
$localizationArray[$targetLanguageIsoCode] = $localizedEntries;
}

foreach ($availableLanguagePairs as $sourceLang => $availableTargets) {
// no entry to possible source in the current page
if (!isset($localizationArray[$sourceLang])) {
continue;
}

foreach ($availableTargets as $targetLang) {
// target isn't configured in the current page
if (!isset($localizationArray[$targetLang])) {
continue;
}

// target is site default, continue
if ($targetLang === $sourceLangIsoCode) {
continue;
}

$glossaryInformation = $this->glossaryRepository->getGlossaryBySourceAndTargetForSync(
$sourceLang,
$targetLang,
$page
);
$glossaryInformation['source_lang'] = $sourceLang;
$glossaryInformation['target_lang'] = $targetLang;

$entries = [];
foreach ($localizationArray[$sourceLang] as $entryId => $sourceEntry) {
// no source target pair, next
if (!isset($localizationArray[$targetLang][$entryId])) {
continue;
}
$entries[] = [
'source' => $sourceEntry['term'],
'target' => $localizationArray[$targetLang][$entryId]['term'],
];
}
// no pairs detected
if (count($entries) == 0) {
continue;
}

// remove duplicates
$sources = [];
foreach ($entries as $position => $entry) {
if (in_array($entry['source'], $sources)) {
unset($entries[$position]);
continue;
}
$sources[] = $entry['source'];
}

// reset entries keys
$glossaryInformation['entries'] = array_values($entries);
$glossaries[] = $glossaryInformation;
}
}

return $glossaries;
}

/**
* @return array<int, mixed>
*/
private function getAvailableLocalizations(int $pageId): array
{
$translations = GeneralUtility::makeInstance(TranslationConfigurationProvider::class)
->translationInfo('pages', $pageId);

// Error string given, if not matching. Return an empty array then
if (!is_array($translations)) {
return [];
}

$availableTranslations = [];
foreach ($translations['translations'] as $translation) {
$availableTranslations[] = $translation['sys_language_uid'];
}

return $availableTranslations;
}

protected function getTargetLanguageCode(int $pageId, int $languageId): string
{
$site = $this->siteFinder->getSiteByPageId($pageId);
$typo3Version = new Typo3Version();
if ($typo3Version->getMajorVersion() < 12) {
$targetLangIsoCode = $site->getLanguageById($languageId)->getTwoLetterIsoCode();
} else {
$targetLangIsoCode = $site->getLanguageById($languageId)->getLocale()->getLanguageCode();
}

return $targetLangIsoCode;
}

private function getDefaultLanguageCode(int $pageId): string
{
$site = $this->siteFinder->getSiteByPageId($pageId);
$typo3Version = new Typo3Version();
if ($typo3Version->getMajorVersion() < 12) {
$sourceLangIsoCode = $site->getDefaultLanguage()->getTwoLetterIsoCode();
} else {
$sourceLangIsoCode = $site->getDefaultLanguage()->getLocale()->getLanguageCode();
}
return $sourceLangIsoCode;
}
}
8 changes: 8 additions & 0 deletions Configuration/Services.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@
use WebVision\WvDeepltranslate\Command\GlossarySyncCommand;
use WebVision\WvDeepltranslate\Controller\Backend\AjaxController;
use WebVision\WvDeepltranslate\Controller\GlossarySyncController;
use WebVision\WvDeepltranslate\Domain\Repository\GlossaryRepository;
use WebVision\WvDeepltranslate\Event\Listener\GlossarySyncButtonProvider;
use WebVision\WvDeepltranslate\Event\Listener\UsageToolBarEventListener;
use WebVision\WvDeepltranslate\Factory\GlossaryFactory;
use WebVision\WvDeepltranslate\Form\Item\SiteConfigSupportedLanguageItemsProcFunc;
use WebVision\WvDeepltranslate\Hooks\Glossary\UpdatedGlossaryEntryTermHook;
use WebVision\WvDeepltranslate\Hooks\TranslateHook;
Expand Down Expand Up @@ -107,6 +109,12 @@
$services
->set(GlossarySyncController::class)
->public();
$services
->set(GlossaryRepository::class)
->public();
$services
->set(GlossaryFactory::class)
->public();

$services->alias(ClientInterface::class, Client::class);

Expand Down
3 changes: 3 additions & 0 deletions Tests/Functional/Factory/Fixtures/BackendUser.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
be_users,,,,,
,uid,pid,username,password,admin
,2,0,"Deepl-Functional-Test BeUser","123",1
18 changes: 18 additions & 0 deletions Tests/Functional/Factory/Fixtures/Glossary.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
pages,,,,,,,,
,uid,pid,is_siteroot,doktype,title,module,sys_language_uid,l10n_parent
,5,1,1,245,"DeepL-Glossary","glossary",0,0
,6,1,1,245,"DeepL-Glossary Deutsch","glossary",1,5
,7,1,1,245,"DeepL-Glossary Polish","glossary",2,5
,8,1,1,245,"DeepL-Glossary Spanish","glossary",3,5
,9,1,1,245,"DeepL-Glossary French","glossary",4,5
,10,1,1,245,"DeepL-Glossary Italian","glossary",5,5
,11,1,1,245,"DeepL-Glossary Dutch","glossary",6,5
tx_wvdeepltranslate_glossaryentry,,,,,
,uid,pid,hidden,term,sys_language_uid,l10n_parent
,1,5,0,"Hello World Default",0,0
,2,5,0,"Hallo Welt Deutsch",1,1
,3,5,0,"Hello World Polish",2,1
,4,5,0,"Hello World Spanish",3,1
,5,5,0,"Hello World French",4,1
,6,5,0,"Hello World Italian",5,1
,7,5,0,"Hello World Dutch",6,1
3 changes: 3 additions & 0 deletions Tests/Functional/Factory/Fixtures/Pages.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pages,,,,,
,uid,pid,is_siteroot,doktype,title,
,1,0,1,1,"DeepL-Functional-Tests"
Loading
Loading