first commit
This commit is contained in:
245
class/Query/Translation.php
Normal file
245
class/Query/Translation.php
Normal 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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user