141 lines
4.4 KiB
PHP
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;
|
|
}
|
|
}
|