first commit

This commit is contained in:
2025-08-02 16:30:27 +02:00
commit 23646bfcee
14851 changed files with 1750626 additions and 0 deletions

245
class/Query/Translation.php Normal file
View File

@@ -0,0 +1,245 @@
<?php
namespace Query;
use KupShop\I18nBundle\Translations\ITranslation;
use KupShop\KupShopBundle\Context\LanguageContext;
use KupShop\KupShopBundle\Util\ArrayUtil;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\Contexts;
class Translation
{
public const COALESCE_STYLE_INHERITANCE = 'inheritance';
public const COALESCE_STYLE_NONE = 'none';
/**
* @return \Closure
*/
public static function adminAlwaysVisible($spec)
{
if (!getAdminUser()) {
return $spec;
}
return function (QueryBuilder $qb) use ($spec) {
$dbcfg = \Settings::getDefault();
$tmp = $dbcfg->hide_not_translated_objects ?? null;
$dbcfg->hide_not_translated_objects = 'N';
$qb->andWhere($spec);
$dbcfg->hide_not_translated_objects = $tmp;
};
}
/**
* @param array|callable|null $columns list of column names ['name', 'title', ...]
*/
public static function withTranslatedFields(
array $languages,
ITranslation $translation,
$columns = null,
bool $frontend = false,
string $coalesceStyle = self::COALESCE_STYLE_NONE,
): callable {
// TODO: Hack
$first = false;
return self::joinTranslations($languages, $translation, function (QueryBuilder $qb, $columnName, $translatedColumn, $langID) use (&$first, $translation, $frontend, $coalesceStyle) {
$translationAlias = $translation->getTableAlias().'_'.$langID;
if (!$frontend && $coalesceStyle == self::COALESCE_STYLE_NONE) {
$qb->addSelect("{$translationAlias}.{$columnName} AS {$langID}_{$columnName}");
// TODO: Rozdelit na specku pouze pro admin
if ($first == false) {
$qb->leftJoin($translationAlias, 'admins', "{$translationAlias}_a", "{$translationAlias}_a.id = {$translationAlias}.id_admin");
$qb->addSelect("{$translationAlias}.created AS {$langID}_created")
->addSelect("{$translationAlias}.updated AS {$langID}_updated")
->addSelect("{$translationAlias}_a.id AS {$langID}_admin_id")
->addSelect("{$translationAlias}_a.email AS {$langID}_admin_email");
$first = true;
}
return false;
} elseif ($coalesceStyle == self::COALESCE_STYLE_INHERITANCE) {
$qb->addSelect("{$translatedColumn} AS {$langID}_{$columnName}");
return false;
}
}, $columns);
}
/**
* @param array|callable|null $columns list of column names ['name', 'title', ...]
*/
public static function joinTranslations(
array $languages,
ITranslation $translation,
callable $fieldsCallback,
$columns = null,
): callable {
return function (QueryBuilder $qb) use ($fieldsCallback, $languages, $translation, $columns) {
if (!findModule(\Modules::TRANSLATIONS)) {
return '1';
}
if (!$languages) {
return '1';
}
$tableAlias = $translation->getTableAlias();
$foreignKeyColumn = $translation->getForeignKeyColumn();
$keyColumn = $translation->getKeyColumn();
if (is_callable($columns)) {
$columnsToSelect = array_keys($translation->getColumns());
$columns = $columns(array_combine($columnsToSelect, $columnsToSelect));
}
if (!is_array($columns)) {
$columns = array_keys($translation->getColumns());
}
if (!ArrayUtil::isDictionary($columns)) {
// convert to assoc
$columns = array_combine($columns, $columns);
}
$inheritedLanguages = static::getInheritedLanguages($languages);
// Pokud je getJoinType join a máme více jazyků, tak použijeme leftJoin a následně použijeme inNotNul v proměnné $whereOr.
// Upraveno kvůli skrývání nepřeložených objektů
$useLeftJoin = count($inheritedLanguages) > 1 && $translation->getJoinType() == 'join';
$join = $useLeftJoin ? 'leftJoin' : $translation->getJoinType();
$whereOr = [];
// join translation tables
foreach ($inheritedLanguages as $langID) {
$translationAlias = $translation->getTableAlias().'_'.$langID;
$qb->setParameter("translation_language_{$langID}", $langID);
$qb->{$join}(
$tableAlias,
$translation->getTableName().'_translations',
$translationAlias,
"{$translationAlias}.{$foreignKeyColumn} = {$tableAlias}.{$keyColumn} AND {$translationAlias}.id_language = :translation_language_{$langID}"
);
$translation->customizeJoinQueryBuilder($qb, $langID);
if ($useLeftJoin) {
$whereOr[] = Operator::isNotNull("{$translationAlias}.{$foreignKeyColumn}");
}
}
if (!empty($whereOr)) {
$qb->andWhere(Operator::orX($whereOr));
}
// add columns
foreach ($languages as $langID) {
foreach ($columns as $columnName => $alias) {
$coalesce = [];
// add translation fields to $coalesce
foreach (static::getInheritedLanguages($langID) as $inheritedLanguageId) {
$translationAlias = $translation->getTableAlias().'_'.$inheritedLanguageId;
$coalesce[] = "{$translationAlias}.{$columnName}";
}
$coalesceField = Operator::coalesce(...$coalesce);
// add select with coalesce to default field
if ($fieldsCallback($qb, $columnName, $coalesceField, $langID) !== false) {
$qb->addSelect("COALESCE({$coalesceField}, {$tableAlias}.{$columnName}) as `{$alias}`");
}
}
}
return '1';
};
}
/**
* @param array|callable|null $columns list of column names ['name', 'title', ...]
*/
public static function coalesceTranslatedFields(
string $translationClass,
$columns = null,
?string $languageID = null,
) {
if (!findModule(\Modules::TRANSLATIONS)) {
if ($columns) {
// Emulate selected columns
$class = new $translationClass();
if (is_callable($columns)) {
$columnsToSelect = array_keys($class->getColumns());
$columns = $columns(array_combine($columnsToSelect, $columnsToSelect));
}
if (!ArrayUtil::isDictionary($columns)) {
// convert to assoc
$columns = array_combine($columns, $columns);
}
return function (QueryBuilder $qb) use ($columns, $class) {
foreach ($columns as $columnName => $translatedField) {
$qb->addSelect("{$class->getTableAlias()}.{$columnName} AS `{$translatedField}`");
}
return '1';
};
}
return '1';
}
/** @var $translation ITranslation */
$translation = ServiceContainer::getService($translationClass);
if (!isset($languageID)) {
$language = ServiceContainer::getService(LanguageContext::class)->getActive();
$languageID = $language->getId();
}
return self::withTranslatedFields([$languageID], $translation, $columns, true);
}
public static function joinTranslatedFields(
string $translationClass,
callable $fieldsCallback,
array $columns,
) {
if (!findModule(\Modules::TRANSLATIONS)) {
if (!ArrayUtil::isDictionary($columns)) {
// convert to assoc
$columns = array_combine($columns, $columns);
}
return function (QueryBuilder $qb) use ($columns, $fieldsCallback, $translationClass) {
$class = new $translationClass();
foreach ($columns as $columnName => $translatedField) {
if ($fieldsCallback($qb, $columnName, null, null) !== false) {
$qb->addSelect("{$class->getTableAlias()}.{$columnName} AS `{$translatedField}`");
}
}
};
}
$translation = ServiceContainer::getService($translationClass);
$language = ServiceContainer::getService(LanguageContext::class)->getActive();
return self::joinTranslations([$language->getId()], $translation, $fieldsCallback, $columns);
}
public static function getInheritedLanguages(array|string $languages): array
{
$languageContext = Contexts::get(LanguageContext::class);
if (is_string($languages)) {
$languages = [$languages];
}
$inheritedLanguages = [];
foreach ($languages as $language) {
$inheritedLanguages = array_unique(array_merge($inheritedLanguages, $languageContext->getInheritance($language)));
}
return $inheritedLanguages;
}
}