Files
kupshop/bundles/KupShop/I18nBundle/Util/TranslationUtil.php
2025-08-02 16:30:27 +02:00

141 lines
4.4 KiB
PHP

<?php
declare(strict_types=1);
namespace KupShop\I18nBundle\Util;
use KupShop\ContentBundle\View\RedirectView;
use KupShop\KupShopBundle\Context\LanguageContext;
use KupShop\KupShopBundle\Util\Contexts;
use Query\Operator;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class TranslationUtil
{
public const FIGURE_INDETERMINATE = 'indeterminate';
public function __construct(
private readonly TranslationLocator $translationLocator,
private readonly RedirectView $redirectView,
) {
$this->redirectView->setLinkPrefixChangeLanguage(false);
}
public function updateTranslationsFigure(string $translationClass, int $objectId, array $figureData, $figureField = 'figure'): bool
{
$translation = $this->translationLocator->getTranslation($translationClass);
foreach ($figureData as $langId => $value) {
$translation->saveSingleObject(
$langId,
$objectId,
[$figureField => $value === self::FIGURE_INDETERMINATE ? null : $value]
);
}
return true;
}
public function getTranslationsFigure(string $translationClass, mixed $objectIDs, $figureField = 'figure'): array
{
$objectId = $objectIDs;
if (!is_array($objectId)) {
$objectId = [$objectId];
}
$objectId = array_filter($objectId);
if (empty($objectId)) {
return [];
}
$translation = $this->translationLocator->getTranslation($translationClass);
$columnId = "t.{$translation->getForeignKeyColumn()}";
$qb = sqlQueryBuilder()
->select("{$columnId} as id", 't.id_language', "t.{$figureField} figure")
->from($translation->getTranslationTableName(), 't')
->where(Operator::inIntArray($objectId, $columnId))
->groupBy($columnId, 't.id_language');
$result = [];
foreach ($qb->execute() as $item) {
$result[$item['id']][$item['id_language']] = $item['figure'] !== null ? $item['figure'] : self::FIGURE_INDETERMINATE;
}
// doplnim chybejici jazyky (nemusi existovat radek s prekladem, ale ja potrebuju mit nastavenou INDETERMINATE hodnotu)
foreach ($objectId as $id) {
foreach ($this->getTranslationLanguages() as $langId) {
if (!isset($result[$id][$langId])) {
$result[$id][$langId] = self::FIGURE_INDETERMINATE;
}
}
}
if (!is_array($objectIDs)) {
return $result[$objectIDs] ?? [];
}
return $result;
}
public function getTranslationLanguages(): array
{
$languageContext = Contexts::get(LanguageContext::class);
return array_filter(array_map(fn ($x) => $x->getId(), $languageContext->getSupported()), fn ($x) => $x !== $languageContext->getDefaultId());
}
/**
* @return string translated link URL or <b>empty string on failure</b>
*/
public function translateLink(string $language, string $objectType, mixed $objectID): string
{
$this->redirectView
->setLang($language)
->setType($objectType)
->setId($objectID);
try {
return $this->redirectView->getUrl();
} catch (NotFoundHttpException) {
return '';
}
}
public function translateLinksInHTML(string $language, string $html, ?array &$errors = null): string
{
libxml_use_internal_errors(true);
$dom = new \DOMDocument();
$dom->loadHTML('<?xml encoding="UTF-8"><div content>'.$html.'</div>', LIBXML_HTML_NODEFDTD);
$xpath = new \DOMXPath($dom);
$nodeList = $xpath->query('//a[@data-id][@data-type]');
foreach ($nodeList ?: [] as $anchor) {
if (!($anchor instanceof \DOMElement)) {
continue;
}
$type = $anchor->getAttribute('data-type');
$id = $anchor->getAttribute('data-id');
$link = $this->translateLink($language, $type, $id);
$anchor->setAttribute('href', $link);
}
$innerHTML = '';
foreach ($xpath->query('//div[@content]')->item(0)->childNodes as $childNode) {
$innerHTML .= $dom->saveHTML($childNode);
}
$errors = libxml_get_errors();
libxml_use_internal_errors(false);
return $innerHTML;
}
}