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

246 lines
7.9 KiB
PHP

<?php
use Doctrine\DBAL\Query\QueryBuilder;
use KupShop\CatalogBundle\Section\SectionTree;
use KupShop\I18nBundle\Util\TranslationsMenuUtil;
use KupShop\KupShopBundle\Context\LanguageContext;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\Export\CustomWriterEntityFactory;
use Query\Translation;
$main_class = 'ExportTranslations';
class ExportTranslations extends Frame
{
protected $template = 'window/export_translations.tpl';
protected $listType;
/** @var string currently selected source language id */
protected $sourceLanguage;
/** @var string currently selected target language id */
protected $language;
protected $translation;
protected $translateList;
/** @var array selected filter options */
protected $filters = [];
/** @var TranslationsMenuUtil */
private $translationsMenuService;
private $sourceLanguages;
private $languages;
public function __construct()
{
$this->translationsMenuService = ServiceContainer::getService(TranslationsMenuUtil::class);
}
public function get_vars()
{
$vars = parent::get_vars();
$vars['ID'] = $this->getID();
$vars['sourceLanguage'] = getVal('sourceLanguage');
$vars['language'] = getVal('language');
$result = sqlQueryBuilder()->select('*')->from('languages')->orderBy('id')->execute()->fetchAll();
$languageContext = ServiceContainer::getService(LanguageContext::class);
foreach ($result as $lang) {
if ($lang['id'] != $languageContext->getDefaultId()) {
// exclude default language
if (findRight('TRANSLATE_'.$lang['id'])) {
$this->languages[$lang['id']] = mb_strtoupper($lang['id']).' - '.$lang['name'];
}
} else {
$this->sourceLanguages[$lang['id']] = mb_strtoupper($lang['id']).' - '.$lang['name'];
}
}
$vars['sourceLanguages'] = $this->sourceLanguages;
$vars['languages'] = $this->languages;
// Translated filter
$this->filters['translated']['selected'] = $this->parseTriState('translated');
$translate_menu = $this->translationsMenuService->getTranslationsMenu();
$vars['translate_menu'] = $translate_menu;
if ($this->getID() == 'translateProducts') {
$vars['categories'] = ServiceContainer::getService(SectionTree::class)->getTree();
$this->filters['productsFilter'] = getVal('filter', $_GET, []);
}
$vars['filters'] = $this->filters;
return $vars;
}
public function handle()
{
if (getVal('Submit')) {
$this->sourceLanguage = getVal('sourceLanguage');
$this->language = getVal('language');
$translations_list = getVal('translations_list');
$sheets = null;
$translations = $this->translationsMenuService->getTranslationsServices();
foreach ($translations_list as $listType) {
$this->listType = $listType;
$className = str_replace('translate', '', $this->listType).'Translation';
$className = $translations[$className];
$this->translation = ServiceContainer::getService($className);
$className = ucfirst($this->listType).'List';
$classPath = loadBundlesAdmin('lists/'.$className.'.php');
$this->translateList = null;
if (file_exists($classPath)) {
include $classPath;
if (!empty($main_class)) {
$this->translateList = new $main_class();
}
}
$sheets[$this->listType] = $this->getData();
}
$this->getFile($sheets);
}
}
protected function getData()
{
if ($this->translateList) {
$qb = $this->translateList->getQuery()['qb'];
if ($this->listType == 'translateBlocks') {
$tableAlias = $this->translation->getTableAlias();
$qb->andWhere('NOT ('.$tableAlias.'.id_root IS NULL
AND '.$tableAlias.'.id_parent IS NULL
AND '.$tableAlias.'.content IS NULL)');
}
} else {
$qb = $this->createQueryBuilder();
}
$data = '';
$fields = $this->getFields();
// k produktum pridavam kod, aby byl produkt lehce dohledatelny
if ($this->listType === 'translateProducts') {
$fields = ['code' => ['alias' => 'code']] + $fields;
}
// u bloku skipnu json_content
if ($this->listType === 'translateBlocks') {
unset($fields['json_content']);
unset($fields["{$this->language}_json_content"]);
}
$fields['data'] = ['cokoli'];
$SQL = $qb->execute();
return $this->generateData($fields, $SQL, $data);
}
public function generateData($fields, $SQL, $data)
{
yield $fields_names = array_keys($fields);
foreach ($SQL as $row) {
$r = [];
$row['data'] = $data;
foreach ($fields_names as $name) {
$r[$name] = substr($row[$name] ?? '', 0, 32767); // Max 32,767 chars in Excel
}
yield $r;
}
}
public function getFields()
{
$columns = $this->translation->getColumns();
$fields['id'] = ['alias' => 'ID'];
$lang = $this->language;
if ($lang) {
foreach ($columns as $key => $column) {
// Skip custom data field
if (!($column['alias'] ?? false)) {
continue;
}
$fields[$key] = $column;
$column['alias'] = strtoupper($lang).' '.$column['alias'];
$fields[$lang.'_'.$key] = $column;
}
}
return $fields;
}
public function getHeader($array = null)
{
if (!$array) {
$array = $this->getFields();
}
$fields = [];
foreach ($array as $key => $field) {
$fields[$key] = $field['alias'];
}
return $fields;
}
public function getFile($sheets = null)
{
if (!$sheets) {
$this->returnError('no data');
}
while (ob_get_level()) {
ob_end_clean();
}
ini_set('memory_limit', '1024M');
ini_set('max_execution_time', '600');
$writer = CustomWriterEntityFactory::createXLSXSimpleWriter();
$writer->openToFile('php://output');
$filename = 'Translations-'.strtoupper($this->language).'-'.date('Y-m-d').'.xls';
header('Content-type: application/xls');
header('Content-Disposition: attachment; filename="'.$filename.'"');
$i = 0;
foreach ($sheets as $key => $sheet) {
$newSheet = ($i == 0 ? $writer->getCurrentSheet() : $writer->addNewSheetAndMakeItCurrent());
$i++;
$newSheet->setName($key);
foreach ($sheet as $row) {
$writer->addRow(\Box\Spout\Writer\Common\Creator\WriterEntityFactory::createRowFromArray($row));
}
}
$writer->close();
writeDownActivity("Export překladů: {$filename}");
exit;
}
protected function createQueryBuilder(): QueryBuilder
{
$tableAlias = $this->translation->getTableAlias();
$qb = sqlQueryBuilder()->select($tableAlias.'.*')
->from($this->translation->getTableName(), $tableAlias)
->andWhere(
Translation::withTranslatedFields([$this->language], $this->translation)
);
return $qb;
}
public function parseTriState($name, $data = null, array $possibleValues = [0, 1, 2], $default = 0)
{
$value = getVal($name, $data);
if (in_array($value, $possibleValues)) {
return $value;
}
return $default;
}
}