201 lines
5.4 KiB
PHP
201 lines
5.4 KiB
PHP
<?php
|
|
|
|
class stLanguageModelTranslator
|
|
{
|
|
const BASE_LANGUAGE = 'en_US';
|
|
|
|
/**
|
|
* Wersja językowa
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $language;
|
|
|
|
/**
|
|
* Temat graficzny
|
|
*
|
|
* @var Theme
|
|
*/
|
|
protected $theme;
|
|
|
|
public function __construct(string $language, ?Theme $theme = null)
|
|
{
|
|
$this->language = $language;
|
|
$this->theme = $theme;
|
|
}
|
|
|
|
public function getLastModifiedTime(): ?int
|
|
{
|
|
$translationFiles = $this->getTranslationFiles();
|
|
|
|
if (null === $translationFiles)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
$lastModifiedTime = [];
|
|
|
|
foreach ($translationFiles as $file)
|
|
{
|
|
$lastModifiedTime[] = filemtime($file);
|
|
}
|
|
|
|
return max($lastModifiedTime);
|
|
}
|
|
|
|
public function translate(string $language): bool
|
|
{
|
|
$translationFiles = $this->getTranslationFiles();
|
|
|
|
if (null === $translationFiles)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
$this->translateModels($language, $translationFiles);
|
|
|
|
return true;
|
|
}
|
|
|
|
protected function getTranslationFiles(): ?array
|
|
{
|
|
$translationFiles = $this->findTranslationFiles($this->language);
|
|
|
|
if (null === $translationFiles)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (null !== $this->theme)
|
|
{
|
|
$themeTranslationFiles = $this->findTranslationFiles($this->language, $this->theme->getTheme());
|
|
|
|
if (null !== $themeTranslationFiles)
|
|
{
|
|
$translationFiles = array_merge($translationFiles, $themeTranslationFiles);
|
|
}
|
|
}
|
|
|
|
return $translationFiles;
|
|
}
|
|
|
|
protected function findTranslationFiles(string $language, ?string $theme = null): ?array
|
|
{
|
|
$path = sfConfig::get('sf_data_dir') . '/translation/' . $language;
|
|
$path .= null !== $theme ? '/' . $theme : '/all';
|
|
|
|
if (!is_dir($path))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return glob($path . '/*yml');
|
|
}
|
|
|
|
protected function translateModels(string $language, array $translationFiles)
|
|
{
|
|
$logging = sfConfig::get('sf_logging_enabled');
|
|
// wyłączamy logowanie, aby nie przekroczyć dozwolonej pamięci przy tylu operacjach odczytu i zapisu
|
|
sfConfig::set('sf_logging_enabled', false);
|
|
|
|
foreach ($translationFiles as $file)
|
|
{
|
|
$modelClass = basename($file, '.yml');
|
|
$modelClassPeer = $modelClass . 'Peer';
|
|
$fieldTranslations = sfYaml::load($file);
|
|
|
|
if (!class_exists($modelClass))
|
|
{
|
|
throw new sfException(sprintf('Model class "%s" does not exist', $modelClass));
|
|
}
|
|
|
|
$offset = 0;
|
|
$count = $this->getFieldTranslationCount($fieldTranslations, $modelClassPeer);
|
|
$c = $this->getModelCriteria($modelClass);
|
|
|
|
do
|
|
{
|
|
$c->setOffset($offset);
|
|
$c->setLimit(20);
|
|
$models = call_user_func([$modelClassPeer, 'doSelectWithI18n'], $c, self::BASE_LANGUAGE);
|
|
|
|
foreach ($models as $model)
|
|
{
|
|
$update = false;
|
|
|
|
foreach ($fieldTranslations as $fieldName => $translations)
|
|
{
|
|
$phpName = sfInflector::camelize($fieldName);
|
|
$getter = 'get' . $phpName;
|
|
$setter = 'set' . $phpName;
|
|
$optGetter = 'getOpt' . $phpName;
|
|
|
|
$model->setCulture(self::BASE_LANGUAGE);
|
|
|
|
$value = $model->$getter();
|
|
|
|
$model->setCulture($language);
|
|
|
|
if (isset($translations[$value]) && (!method_exists($model, $optGetter) || $model->$getter() == $model->$optGetter()))
|
|
{
|
|
$model->$setter($translations[$value]);
|
|
$update = true;
|
|
}
|
|
}
|
|
|
|
if ($update)
|
|
{
|
|
$model->save();
|
|
}
|
|
}
|
|
|
|
$offset += count($models);
|
|
}
|
|
while($offset > 0 && $offset < $count);
|
|
}
|
|
|
|
sfConfig::set('sf_logging_enabled', $logging);
|
|
}
|
|
|
|
protected function getFieldTranslationCount(array $fieldTranslations, string $modelClassPeer): int
|
|
{
|
|
$count = [];
|
|
|
|
foreach ($fieldTranslations as $translations)
|
|
{
|
|
$count[] = count($translations);
|
|
}
|
|
|
|
$c = new Criteria();
|
|
$this->addThemeCriteria($modelClassPeer, $c);
|
|
|
|
$entityCount = call_user_func([$modelClassPeer, 'doCount'], $c);
|
|
|
|
return min(max($count), $entityCount);
|
|
}
|
|
|
|
protected function getModelCriteria(string $modelClass): Criteria
|
|
{
|
|
$c = new Criteria();
|
|
$entity = new $modelClass();
|
|
|
|
foreach ($entity->getPrimaryKeyFields(BasePeer::TYPE_COLNAME) as $column)
|
|
{
|
|
$c->addAscendingOrderByColumn($column);
|
|
}
|
|
|
|
$this->addThemeCriteria($modelClass . 'Peer', $c);
|
|
|
|
return $c;
|
|
}
|
|
|
|
protected function addThemeCriteria(string $modelClassPeer, Criteria $c)
|
|
{
|
|
$themeIdField = "{$modelClassPeer}::THEME_ID";
|
|
|
|
if (defined($themeIdField))
|
|
{
|
|
$c->add(constant($themeIdField), $this->theme->getId());
|
|
}
|
|
}
|
|
} |