Implemented domains in translations. Fix #116 and #177

This commit is contained in:
Franck Allimant
2014-04-20 16:31:06 +02:00
parent 9b29d510f2
commit a135a68e6c
23 changed files with 1262 additions and 938 deletions

View File

@@ -166,6 +166,7 @@ class Module extends BaseI18nLoop implements PropelSearchLoopInterface
public function parseResults(LoopResult $loopResult)
{
/** @var \Thelia\Model\Module $module */
foreach ($loopResult->getResultDataCollection() as $module) {
$loopResultRow = new LoopResultRow($module);
$loopResultRow->set("ID", $module->getId())
@@ -199,13 +200,13 @@ class Module extends BaseI18nLoop implements PropelSearchLoopInterface
/* if not ; test if it uses admin inclusion : module_configuration.html */
if (false === $hasConfigurationInterface) {
if (file_exists( sprintf("%s/AdminIncludes/%s.html", $module->getAbsoluteBaseDir(), "module_configuration"))) {
if (file_exists($module->getAbsoluteAdminIncludesPath() . DS . "module_configuration.html")) {
$hasConfigurationInterface = true;
}
}
} else {
// Make a quick and dirty test on the module's routing.xml file
$routing = @file_get_contents($module->getAbsoluteBaseDir() . DS . "Config" . DS . "routing.xml");
$routing = @file_get_contents($module->getAbsoluteConfigPath() . DS . "routing.xml");
if ($routing && strpos($routing, '/admin/module/') !== false) {
$hasConfigurationInterface = true;

View File

@@ -80,8 +80,8 @@ class AdminUtilities extends AbstractSmartyPlugin
<a href="{url path='/admin/configuration/currencies/positionDown' currency_id=$ID}"><i class="icon-arrow-down"></i></a>
*/
if ($permissions == null || $this->securityContext->isGranted(
"ADMIN",
if ($this->securityContext->isGranted(
array("ADMIN"),
$resource === null ? array() : array($resource),
$module === null ? array() : array($module),
array($access))

View File

@@ -63,13 +63,14 @@ class Module extends AbstractSmartyPlugin
$modules = ModuleQuery::getActivated();
/** @var \Thelia\Model\Module $module */
foreach ($modules as $module) {
if (null !== $moduleLimit && $moduleLimit != $module->getCode()) {
continue;
}
$file = sprintf("%s/AdminIncludes/%s.html", $module->getAbsoluteBaseDir(), $location);
$file = $module->getAbsoluteAdminIncludesPath() . DS . $location . '.html';
if (file_exists($file)) {

View File

@@ -19,41 +19,59 @@ use Symfony\Component\Translation\TranslatorInterface;
class Translation extends AbstractSmartyPlugin
{
protected $translator;
protected $defaultTranslationDomain = '';
public function __construct(TranslatorInterface $translator)
{
$this->translator = $translator;
}
/**
* Set the default translation domain
*
* @param array $params
* @param \Smarty_Internal_Template $smarty
* @return string
*/
public function setDefaultTranslationDomain($params, &$smarty)
{
$this->defaultTranslationDomain = $this->getParam($params, 'domain');
}
/**
* Process translate function
*
* @param unknown $params
* @param unknown $smarty
* @param array $params
* @param \Smarty_Internal_Template $smarty
* @return string
*/
public function translate($params, &$smarty)
{
// All parameters other than 'l' are supposed to be variables. Build an array of var => value pairs
// All parameters other than 'l' and 'd' are supposed to be variables. Build an array of var => value pairs
// and pass it to the translator
$vars = array();
foreach ($params as $name => $value) {
if ($name != 'l') $vars["%$name"] = $value;
if ($name != 'l' && $name != 'd') $vars["%$name"] = $value;
}
return $this->translator->trans($this->getParam($params, 'l'), $vars);
}
return $this->translator->trans(
$this->getParam($params, 'l'),
$vars,
$this->getParam($params, 'd', $this->defaultTranslationDomain)
);
}
/**
* Define the various smarty plugins hendled by this class
* Define the various smarty plugins handled by this class
*
* @return an array of smarty plugin descriptors
* @return SmartyPluginDescriptor[] an array of smarty plugin descriptors
*/
public function getPluginDescriptors()
{
return array(
new SmartyPluginDescriptor('function', 'intl', $this, 'translate'),
new SmartyPluginDescriptor('function', 'default_translation_domain', $this, 'setDefaultTranslationDomain'),
);
}
}

View File

@@ -46,6 +46,8 @@ class TemplateDefinition
*/
protected $type;
protected $translationDomainPrefix;
public function __construct($name, $type)
{
$this->name = $name;
@@ -54,22 +56,31 @@ class TemplateDefinition
switch ($type) {
case TemplateDefinition::FRONT_OFFICE:
$this->path = self::FRONT_OFFICE_SUBDIR . DS . $name;
$this->translationDomainPrefix = 'fo.';
break;
case TemplateDefinition::BACK_OFFICE:
$this->path = self::BACK_OFFICE_SUBDIR . DS . $name;
$this->translationDomainPrefix = 'bo.';
break;
case TemplateDefinition::PDF:
$this->path = self::PDF_SUBDIR . DS . $name;
$this->translationDomainPrefix = 'pdf.';
break;
case TemplateDefinition::EMAIL:
$this->path = self::EMAIL_SUBDIR . DS . $name;
$this->translationDomainPrefix = 'email.';
break;
default:
$this->path = $name;
$this->translationDomainPrefix = 'generic.';
break;
}
}
public function getTranslationDomain() {
return $this->translationDomainPrefix . strtolower($this->getName());
}
public function getName()
{
return $this->name;

View File

@@ -12,6 +12,7 @@
namespace Thelia\Core\Template;
use Symfony\Component\Filesystem\Filesystem;
use Thelia\Model\ConfigQuery;
use Thelia\Log\Tlog;
use Thelia\Core\Translation\Translator;
@@ -96,9 +97,10 @@ class TemplateHelper
* Return a list of existing templates for a given template type
*
* @param int $templateType the template type
* @return An array of \Thelia\Core\Template\TemplateDefinition
* @param string the template base (module or core, default to core).
* @return TemplateDefinition[] of \Thelia\Core\Template\TemplateDefinition
*/
public function getList($templateType)
public function getList($templateType, $base = THELIA_TEMPLATE_DIR)
{
$list = $exclude = array();
@@ -108,24 +110,29 @@ class TemplateHelper
if ($templateType == $type) {
$baseDir = THELIA_TEMPLATE_DIR.$subdir;
$baseDir = rtrim($base, DS).DS.$subdir;
// Every subdir of the basedir is supposed to be a template.
$di = new \DirectoryIterator($baseDir);
try {
// Every subdir of the basedir is supposed to be a template.
$di = new \DirectoryIterator($baseDir);
foreach ($di as $file) {
// Ignore 'dot' elements
if ($file->isDot() || ! $file->isDir()) continue;
foreach ($di as $file) {
// Ignore 'dot' elements
if ($file->isDot() || ! $file->isDir()) continue;
// Ignore reserved directory names
if (in_array($file->getFilename(), $exclude)) continue;
// Ignore reserved directory names
if (in_array($file->getFilename(), $exclude)) continue;
$list[] = new TemplateDefinition($file->getFilename(), $templateType);
$list[] = new TemplateDefinition($file->getFilename(), $templateType);
}
}
catch (\UnexpectedValueException $ex) {
// Ignore the exception and continue
}
return $list;
}
}
return $list;
}
protected function normalizePath($path)
@@ -152,11 +159,12 @@ class TemplateHelper
* @param string $walkMode type of file scanning: WALK_MODE_PHP or WALK_MODE_TEMPLATE
* @param \Thelia\Core\Translation\Translator $translator the current translator
* @param string $currentLocale the current locale
* @param string $domain the translation domain (fontoffice, backoffice, module, etc...)
* @param array $strings the list of strings
* @throws \InvalidArgumentException if $walkMode contains an invalid value
* @return number the total number of translatable texts
*/
public function walkDir($directory, $walkMode, Translator $translator, $currentLocale, &$strings)
public function walkDir($directory, $walkMode, Translator $translator, $currentLocale, $domain, &$strings)
{
$num_texts = 0;
@@ -165,7 +173,7 @@ class TemplateHelper
$allowed_exts = array('php');
} elseif ($walkMode == self::WALK_MODE_TEMPLATE) {
$prefix = '\{intl[\s]l=';
$prefix = "\\{intl(?:.*?)l=";
$allowed_exts = array('html', 'tpl', 'xml');
} else {
@@ -178,11 +186,12 @@ class TemplateHelper
Tlog::getInstance()->debug("Walking in $directory, in mode $walkMode");
/** @var \DirectoryIterator $fileInfo */
foreach (new \DirectoryIterator($directory) as $fileInfo) {
if ($fileInfo->isDot()) continue;
if ($fileInfo->isDir()) $num_texts += $this->walkDir($fileInfo->getPathName(), $walkMode, $translator, $currentLocale, $strings);
if ($fileInfo->isDir()) $num_texts += $this->walkDir($fileInfo->getPathName(), $walkMode, $translator, $currentLocale, $domain, $strings);
if ($fileInfo->isFile()) {
@@ -219,7 +228,7 @@ class TemplateHelper
$strings[$hash] = array(
'files' => array($short_path),
'text' => $match,
'translation' => $translator->trans($match, array(), 'messages', $currentLocale, false),
'translation' => $translator->trans($match, array(), $domain, $currentLocale, false),
'dollar' => strstr($match, '$') !== false
);
}
@@ -233,13 +242,24 @@ class TemplateHelper
return $num_texts;
} catch (\UnexpectedValueException $ex) {
echo $ex;
// Directory does not exists => ignore/
}
}
public function writeTranslation($file, $texts, $translations)
public function writeTranslation($file, $texts, $translations, $createIfNotExists = false)
{
$fs = new Filesystem();
if (! $fs->exists($file) && true === $createIfNotExists) {
$dir = dirname($file);
if (! $fs->exists($file)) {
$fs->mkdir($dir);
}
}
if ($fp = @fopen($file, 'w')) {
fwrite($fp, '<' . "?php\n\n");

View File

@@ -34,6 +34,7 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Config\DatabaseConfiguration;
use Thelia\Config\DefinePropel;
use Thelia\Core\Template\ParserInterface;
use Thelia\Core\Template\TemplateDefinition;
use Thelia\Core\DependencyInjection\Loader\XmlFileLoader;
@@ -43,6 +44,7 @@ use Propel\Runtime\Propel;
use Propel\Runtime\Connection\ConnectionManagerSingle;
use Thelia\Core\Template\TemplateHelper;
use Thelia\Log\Tlog;
use Thelia\Model\Module;
class Thelia extends Kernel
{
@@ -93,8 +95,8 @@ class Thelia extends Kernel
/**
* Add all module's standard templates to the parser environment
*
* @param TheliaParser $parser the parser
* @param Module $module the Module.
* @param ParserInterface $parser the parser
* @param Module $module the Module.
*/
protected function addStandardModuleTemplatesToParserEnvironment($parser, $module)
{
@@ -108,10 +110,10 @@ class Thelia extends Kernel
/**
* Add a module template directory to the parser environment
*
* @param TheliaParser $parser the parser
* @param Module $module the Module.
* @param string $templateType the template type (one of the TemplateDefinition type constants)
* @param string $templateSubdirName the template subdirectory name (one of the TemplateDefinition::XXX_SUBDIR constants)
* @param ParserInterface $parser the parser
* @param Module $module the Module.
* @param string $templateType the template type (one of the TemplateDefinition type constants)
* @param string $templateSubdirName the template subdirectory name (one of the TemplateDefinition::XXX_SUBDIR constants)
*/
protected function addModuleTemplateToParserEnvironment($parser, $module, $templateType, $templateSubdirName)
{
@@ -168,8 +170,11 @@ class Thelia extends Kernel
$modules = \Thelia\Model\ModuleQuery::getActivated();
$translationDirs = array();
/** @var ParserInterface $parser */
$parser = $container->getDefinition('thelia.parser');
/** @var Module $module */
foreach ($modules as $module) {
try {
@@ -190,14 +195,21 @@ class Thelia extends Kernel
} else {
$container->addCompilerPass($compiler);
}
}
$loader = new XmlFileLoader($container, new FileLocator($module->getAbsoluteConfigPath()));
$loader->load("config.xml");
$moduleDomain = strtolower($module->getCode());
// Core module translation
if (is_dir($dir = $module->getAbsoluteI18nPath())) {
$translationDirs[] = $dir;
$translationDirs[$module->getTranslationDomain()] = $dir;
}
// Admin includes translation
if (is_dir($dir = $module->getAbsoluteAdminIncludesI18nPath())) {
$translationDirs[$module->getAdminIncludesTranslationDomain()] = $dir;
}
$this->addStandardModuleTemplatesToParserEnvironment($parser, $module);
@@ -207,16 +219,16 @@ class Thelia extends Kernel
}
}
// Load translation from templates
// core translation
$translationDirs[] = THELIA_ROOT . "core/lib/Thelia/Config/I18n";
// Load core translation
$translationDirs['core'] = THELIA_ROOT . "core/lib/Thelia/Config/I18n";
// Standard templates (front, back, pdf, mail)
$th = TemplateHelper::getInstance();
/** @var TemplateDefinition $templateDefinition */
foreach ($th->getStandardTemplateDefinitions() as $templateDefinition) {
if (is_dir($dir = $templateDefinition->getAbsoluteI18nPath())) {
$translationDirs[] = $dir;
$translationDirs[$templateDefinition->getTranslationDomain()] = $dir;
}
}
@@ -230,14 +242,19 @@ class Thelia extends Kernel
{
$translator = $container->getDefinition('thelia.translator');
$finder = Finder::create()
->files()
->depth(0)
->in($dirs);
foreach ($dirs as $domain => $dir) {
foreach ($finder as $file) {
list($locale, $format) = explode('.', $file->getBaseName(), 2);
$translator->addMethodCall('addResource', array($format, (string) $file, $locale));
$finder = Finder::create()
->files()
->depth(0)
->in($dir);
/** @var \DirectoryIterator $file */
foreach ($finder as $file) {
list($locale, $format) = explode('.', $file->getBaseName(), 2);
$translator->addMethodCall('addResource', array($format, (string) $file, $locale, $domain));
}
}
}

View File

@@ -14,6 +14,7 @@ namespace Thelia\Core\Translation;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Translation\Translator as BaseTranslator;
use Thelia\Log\Tlog;
class Translator extends BaseTranslator
{
@@ -63,7 +64,7 @@ class Translator extends BaseTranslator
*
* @api
*/
public function trans($id, array $parameters = array(), $domain = 'messages', $locale = null, $return_default_if_not_available = true)
public function trans($id, array $parameters = array(), $domain = 'core', $locale = null, $return_default_if_not_available = true)
{
if (null === $locale) {
$locale = $this->getLocale();
@@ -73,11 +74,19 @@ class Translator extends BaseTranslator
$this->loadCatalogue($locale);
}
if ($this->catalogues[$locale]->has((string) $id, $domain))
if (! $this->catalogues[$locale]->has((string) $id, $domain)) {
}
if ($this->catalogues[$locale]->has((string) $id, $domain)) {
return parent::trans($id, $parameters, $domain, $locale);
else if ($return_default_if_not_available)
return strtr($id, $parameters);
else
return '';
} else {
Tlog::getInstance()->addWarning("Undefined translation: locale: $locale, domain: $domain, ID: $id");
if ($return_default_if_not_available)
return strtr($id, $parameters);
else
return '';
}
}
}