Fixed minor internationalizable string error in admin templates.

This commit is contained in:
Franck Allimant
2013-11-06 20:01:26 +01:00
parent 8d40605091
commit f8f68eb59b
37 changed files with 1440 additions and 1380 deletions

View File

@@ -1,26 +1,14 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
return array(
);
'Delivery module' => 'Delivery module',
'Quantity' => 'Quantity',
'Product' => 'Product',
'Unit. price' => 'Unit. price',
'Tax' => 'Tax',
'Unit taxed price' => 'Unit taxed price',
'Taxed total' => 'Taxed total',
'Payment module' => 'Payment module',
'Postage' => 'Postage',
'Total' => 'Total',
);

View File

@@ -1,26 +1,36 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
return array(
);
'Combination builder' => 'Combination builder',
'Title' => 'Title',
'City' => 'City',
'Zip code' => 'Zip code',
'Country' => 'Country',
'Phone' => 'Phone',
'Login' => 'Login',
'Password' => 'Password',
'Profile' => 'Profile',
'Postage' => 'Postage',
'Add to all product templates' => 'Add to all product templates',
'Quantity' => 'Quantity',
'Name' => 'Name',
'Value' => 'Value',
'Subject' => 'Subject',
'Company' => 'Company',
'Description' => 'Description',
'Language name' => 'Language name',
'ISO 639 Code' => 'ISO 639 Code',
'If a translation is missing or incomplete :' => 'If a translation is missing or incomplete :',
'Host' => 'Host',
'Port' => 'Port',
'Encryption' => 'Encryption',
'Username' => 'Username',
'Timeout' => 'Timeout',
'Source IP' => 'Source IP',
'Email address' => 'Email address',
'Firstname' => 'Firstname',
'Lastname' => 'Lastname',
'Additional address' => 'Additional address',
'Reference' => 'Reference',
'EAN Code' => 'EAN Code',
);

View File

@@ -32,6 +32,7 @@ use Thelia\Model\ConfigQuery;
use Thelia\Model\ModuleQuery;
use Thelia\Core\Template\TemplateHelper;
use Thelia\Core\Template\TemplateDefinition;
use Thelia\Tools\URL;
/**
* Class LangController
* @package Thelia\Controller\Admin
@@ -41,7 +42,6 @@ class TranslationsController extends BaseAdminController
{
protected function renderTemplate()
{
// Find modules
$modules = ModuleQuery::create()->joinI18n($this->getCurrentEditionLocale())->orderByPosition()->find();
@@ -58,24 +58,33 @@ class TranslationsController extends BaseAdminController
$template = $directory = $i18n_directory = false;
$mode = 'template';
$walkMode = TemplateHelper::WALK_MODE_TEMPLATE;
if (! empty($item_id)) {
$templateArguments = array(
'item_to_translate' => $item_to_translate,
'item_id' => $item_id,
'view_missing_traductions_only' => $this->getRequest()->get('view_missing_traductions_only', 0),
'max_input_vars_warning' => false,
);
// Find the i18n directory, and the directory to examine.
if (! empty($item_id) || $item_to_translate == 'co') {
switch($item_to_translate) {
case 'mo' :
if (null !== $module = ModuleQuery::create()->findPk($item_id)) {
$directory = THELIA_MODULE_DIR . $module->getBaseDir();
$i18n_directory = THELIA_TEMPLATE_DIR . $template->getI18nPath();
$mode = 'php';
$i18n_directory = THELIA_TEMPLATE_DIR . $module->getI18nPath();
$walkMode = TemplateHelper::WALK_MODE_PHP;
}
break;
case 'co' :
$directory = THELIA_ROOT . 'core/lib/Thelia';
$i18n_directory = THELIA_ROOT . 'core/lib/Thelia/Config/I18n';
$mode = 'php';
$walkMode = TemplateHelper::WALK_MODE_PHP;
break;
case 'fo' :
@@ -96,24 +105,58 @@ class TranslationsController extends BaseAdminController
$i18n_directory = THELIA_TEMPLATE_DIR . $template->getI18nPath();
}
// Load strings to translate
if ($directory) {
// Load strings
$this->walkDir($directory, $mode, $all_strings);
// Load translated strings
// Save the string set, if the form was submitted
if ($i18n_directory) {
$locale = $this->getCurrentEditionLocale();
$save_mode = $this->getRequest()->get('save_mode', false);
if ($save_mode !== false) {
$texts = $this->getRequest()->get('text', array());
if (! empty($texts)) {
$file = sprintf("%s/%s.php", $i18n_directory, $this->getCurrentEditionLocale());
$translations = $this->getRequest()->get('translation', array());
TemplateHelper::getInstance()->write_translation($file, $texts, $translations);
if ($save_mode == 'stay')
$this->redirectToRoute("admin.configuration.translations", $templateArguments);
else
$this->redirect(URL::getInstance()->adminViewUrl('configuration'));
}
}
}
// Load strings
$stringsCount = TemplateHelper::getInstance()->walkDir(
$directory,
$walkMode,
$this->getTranslator(),
$this->getCurrentEditionLocale(),
$all_strings
);
// Estimate number of fields, and compare to php ini max_input_vars
$stringsCount = $stringsCount * 2 + 6;
if ($stringsCount > ini_get('max_input_vars')) {
$templateArguments['max_input_vars_warning'] = true;
$templateArguments['required_max_input_vars'] = $stringsCount;
$templateArguments['current_max_input_vars'] = ini_get('max_input_vars');
}
else {
$templateArguments['all_strings'] = $all_strings;
}
}
}
return $this->render('translations', array(
'item_to_translate' => $item_to_translate,
'item_id' => $item_id,
'all_strings' => $all_strings,
'view_missing_traductions_only' => $this->getRequest()->get('view_missing_traductions_only', 0)
));
return $this->render('translations', $templateArguments);
}
public function defaultAction()
@@ -129,86 +172,4 @@ class TranslationsController extends BaseAdminController
return $this->renderTemplate();
}
protected function normalize_path($path)
{
$path =
str_replace(
str_replace('\\', '/', THELIA_ROOT),
'',
str_replace('\\', '/', realpath($path))
);
if ($path[0] == '/') $path = substr($path, 1);
return $path;
}
protected function walkDir($directory, $mode, &$strings) {
if ($mode == 'php') {
$prefix = '\-\>[\s]*trans[\s]*\(';
$allowed_exts = array('php');
} else {
$prefix = '\{intl[\s]l=';
$allowed_exts = array('html', 'tpl', 'xml');
}
try {
//echo "walking in $directory<br />";
foreach (new \DirectoryIterator($directory) as $fileInfo) {
if ($fileInfo->isDot()) continue;
if ($fileInfo->isDir()) $this->walkDir($fileInfo->getPathName(), $mode, $strings);
if ($fileInfo->isFile()) {
$ext = $fileInfo->getExtension();
if (in_array($ext, $allowed_exts)) {
if ($content = file_get_contents($fileInfo->getPathName())) {
$short_path = $this->normalize_path($fileInfo->getPathName());
// echo " examining $short_path\n";
$matches = array();
if (preg_match_all('/'.$prefix.'((?<![\\\\])[\'"])((?:.(?!(?<![\\\\])\1))*.?)\1/', $content, $matches)) {
// print_r($matches[2]);
foreach($matches[2] as $match) {
$hash = md5($match);
if (isset($strings[$hash]))
{
if (! in_array($short_path, $strings[$hash]['files']))
{
$strings[$hash]['files'][] = $short_path;
}
}
else
$strings[$hash] = array(
'files' => array($short_path),
'chaine' => $match,
'translation' => $this->getTranslator()->trans($match, array(), 'messages', $this->getCurrentEditionLocale(), false),
'dollar' => strstr($match, '$') !== false
);
}
}
}
}
}
}
} catch (\UnexpectedValueException $ex) {
echo $ex;
}
}
}

View File

@@ -95,7 +95,7 @@ class SmartyParser extends Smarty implements ParserInterface
public static function theliaEscape($content, $smarty)
{
if (is_scalar($content)) {
return htmlspecialchars($content ,ENT_QUOTES, Smarty::$_CHARSET);
return htmlspecialchars($content, ENT_QUOTES, Smarty::$_CHARSET);
} else {
return $content;
}

View File

@@ -24,9 +24,14 @@
namespace Thelia\Core\Template;
use Thelia\Model\ConfigQuery;
use Thelia\Log\Tlog;
use Thelia\Core\Translation\Translator;
class TemplateHelper
{
const WALK_MODE_PHP = 'php';
const WALK_MODE_TEMPLATE = 'tpl';
/**
* This is a singleton
@@ -93,4 +98,156 @@ class TemplateHelper
return $list;
}
protected function normalize_path($path)
{
$path = str_replace(
str_replace('\\', '/', THELIA_ROOT),
'',
str_replace('\\', '/', realpath($path))
);
return ltrim($path, '/');
}
/**
* Récursively examine files in a directory tree, and extract translatable strings.
*
* Returns an array of translatable strings, each item having with the following structure:
* 'files' an arfray of file names in which the string appears,
* 'text' the translatable text
* 'translation' => the text translation, or an empty string if none available.
* 'dollar' => true if the translatable text contains a $
*
* @param string $directory the path to the directory to examine
* @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 array $strings the liste 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) {
$num_files = 0;
if ($walkMode == self::WALK_MODE_PHP) {
$prefix = '\-\>[\s]*trans[\s]*\(';
$allowed_exts = array('php');
} else if ($walkMode == self::WALK_MODE_TEMPLATE) {
$prefix = '\{intl[\s]l=';
$allowed_exts = array('html', 'tpl', 'xml');
}
else {
throw new \InvalidArgumentException(
Translator::getInstance()->trans('Invalid value for walkMode parameter: %value', array('%value' => $walkMode))
);
}
try {
Tlog::getInstance()->debug("Walking in $directory, in mode $walkMode");
foreach (new \DirectoryIterator($directory) as $fileInfo) {
if ($fileInfo->isDot()) continue;
if ($fileInfo->isDir()) $num_files += $this->walkDir($fileInfo->getPathName(), $walkMode, $translator, $currentLocale, $strings);
if ($fileInfo->isFile()) {
$ext = $fileInfo->getExtension();
if (in_array($ext, $allowed_exts)) {
if ($content = file_get_contents($fileInfo->getPathName())) {
$short_path = $this->normalize_path($fileInfo->getPathName());
Tlog::getInstance()->debug("Examining file $short_path\n");
$matches = array();
if (preg_match_all('/'.$prefix.'((?<![\\\\])[\'"])((?:.(?!(?<![\\\\])\1))*.?)\1/', $content, $matches)) {
Tlog::getInstance()->debug("Strings found: ", $matches[2]);
foreach($matches[2] as $match) {
$hash = md5($match);
if (isset($strings[$hash]))
{
if (! in_array($short_path, $strings[$hash]['files']))
{
$strings[$hash]['files'][] = $short_path;
}
}
else
$num_files++;
// remove \'
$match = str_replace("\\'", "'", $match);
$strings[$hash] = array(
'files' => array($short_path),
'text' => $match,
'translation' => $translator->trans($match, array(), 'messages', $currentLocale, false),
'dollar' => strstr($match, '$') !== false
);
}
}
}
}
}
}
return $num_files;
} catch (\UnexpectedValueException $ex) {
echo $ex;
}
}
public function write_translation($file, $texts, $translations)
{
if ($fp = @fopen($file, 'w')) {
fwrite($fp, '<' . "?php\n\n");
fwrite($fp, "return array(\n");
$idx = 0;
foreach($texts as $text)
{
// Write only defined (not empty) translations
if (! empty($translations[$idx])) {
$text = str_replace("'", "\'", $text);
$translation = str_replace("'", "\'", $translations[$idx]);
fwrite($fp, sprintf("\t'%s' => '%s',\n", $text, $translation));
}
$idx++;
}
fwrite($fp, ");\n");
@fclose($fh);
}
else
{
throw new \RuntimeException(
$this->getTranslator()->trans(
"Failed to open translation file %file. Please be sure that this file is writable by your Web server",
array('%file' => $file)
)
);
}
}
}