From 361e4a9d748f656fff5e200e768ae01c6801341c Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Wed, 6 Nov 2013 10:49:03 +0100 Subject: [PATCH] Implementing translations (still in progress) --- core/lib/Thelia/Action/HttpException.php | 3 +- core/lib/Thelia/Action/Product.php | 38 ++- core/lib/Thelia/Config/Resources/loop.xml | 1 + .../Thelia/Config/Resources/routing/admin.xml | 10 + .../Controller/Admin/BaseAdminController.php | 3 +- .../Controller/Admin/OrderController.php | 3 +- .../Controller/Admin/ProductController.php | 1 + .../Admin/TranslationsController.php | 194 ++++++++++++++ .../Compiler/RegisterRouterPass.php | 14 +- .../Core/Security/Resource/AdminResources.php | 2 + .../Thelia/Core/Template/Loop/Template.php | 72 +++--- .../Smarty/Plugins/AdminUtilities.php | 3 +- .../Core/Template/Smarty/Plugins/Module.php | 2 +- .../Core/Template/Smarty/SmartyParser.php | 3 +- .../Core/Template/TemplateDefinition.php | 102 ++++++++ .../Thelia/Core/Template/TemplateHelper.php | 96 +++++++ core/lib/Thelia/Core/Thelia.php | 23 +- core/lib/Thelia/Model/ConfigQuery.php | 6 - core/lib/Thelia/Model/Map/ConfigTableMap.php | 2 +- core/lib/Thelia/Model/Module.php | 21 ++ install/insert.sql | 18 +- install/thelia.sql | 2 +- templates/admin/default/admin-logs.html | 171 +++++++------ templates/admin/default/configuration.html | 7 + templates/admin/default/customer-edit.html | 4 +- templates/admin/default/translations.html | 238 ++++++++++++++++++ templates/admin/default/variable-edit.html | 4 +- templates/pdf/default/I18n/en_US.php | 4 + templates/pdf/default/I18n/es_ES.php | 4 + templates/pdf/default/I18n/fr_FR.php | 4 + templates/pdf/default/I18n/it_IT.php | 4 + templates/pdf/{ => default}/delivery.html | 0 templates/pdf/{ => default}/invoice.html | 0 33 files changed, 890 insertions(+), 169 deletions(-) create mode 100644 core/lib/Thelia/Controller/Admin/TranslationsController.php create mode 100644 core/lib/Thelia/Core/Template/TemplateDefinition.php create mode 100644 core/lib/Thelia/Core/Template/TemplateHelper.php create mode 100644 templates/admin/default/translations.html create mode 100644 templates/pdf/default/I18n/en_US.php create mode 100644 templates/pdf/default/I18n/es_ES.php create mode 100644 templates/pdf/default/I18n/fr_FR.php create mode 100644 templates/pdf/default/I18n/it_IT.php rename templates/pdf/{ => default}/delivery.html (100%) rename templates/pdf/{ => default}/invoice.html (100%) diff --git a/core/lib/Thelia/Action/HttpException.php b/core/lib/Thelia/Action/HttpException.php index 10e0dad37..eff2f7586 100755 --- a/core/lib/Thelia/Action/HttpException.php +++ b/core/lib/Thelia/Action/HttpException.php @@ -30,6 +30,7 @@ use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\KernelEvents; use Thelia\Model\ConfigQuery; +use Thelia\Core\Template\TemplateHelper; /** * @@ -55,7 +56,7 @@ class HttpException extends BaseAction implements EventSubscriberInterface $parser = $this->container->get("thelia.parser"); // Define the template thant shoud be used - $parser->setTemplate(ConfigQuery::getActiveTemplate()); + $parser->setTemplate(TemplateHelper::getInstance()->getActiveFrontTemplate()->getPath()); //$event->getRequest()->attributes->set('_view', ConfigQuery::getPageNotFoundView()); diff --git a/core/lib/Thelia/Action/Product.php b/core/lib/Thelia/Action/Product.php index e56df6523..3917827d1 100644 --- a/core/lib/Thelia/Action/Product.php +++ b/core/lib/Thelia/Action/Product.php @@ -54,6 +54,8 @@ use Thelia\Core\Event\Product\ProductDeleteCategoryEvent; use Thelia\Core\Event\Product\ProductAddCategoryEvent; use Thelia\Core\Event\Product\ProductAddAccessoryEvent; use Thelia\Core\Event\Product\ProductDeleteAccessoryEvent; +use Thelia\Model\Map\ProductTableMap; +use Propel\Runtime\Propel; class Product extends BaseAction implements EventSubscriberInterface { @@ -257,21 +259,37 @@ class Product extends BaseAction implements EventSubscriberInterface public function setProductTemplate(ProductSetTemplateEvent $event) { - $product = $event->getProduct(); - // Delete all product feature relations - FeatureProductQuery::create()->filterByProduct($product)->delete(); + $con = Propel::getWriteConnection(ProductTableMap::DATABASE_NAME); - // Delete all product attributes sale elements - ProductSaleElementsQuery::create()->filterByProduct($product)->delete(); + $con->beginTransaction(); - // Update the product template - $template_id = $event->getTemplateId(); + try { - // Set it to null if it's zero. - if ($template_id <= 0) $template_id = NULL; + $product = $event->getProduct(); - $product->setTemplateId($template_id)->save(); + // Delete all product feature relations + FeatureProductQuery::create()->filterByProduct($product)->delete($con); + + // Delete all product attributes sale elements + ProductSaleElementsQuery::create()->filterByProduct($product)->delete($con); + + // Update the product template + $template_id = $event->getTemplateId(); + + // Set it to null if it's zero. + if ($template_id <= 0) $template_id = NULL; + + $product->setTemplateId($template_id)->save($con); + + // Store all the stuff ! + $con->commit(); + } catch (\Exception $ex) { + + $con->rollback(); + + throw $ex; + } } /** diff --git a/core/lib/Thelia/Config/Resources/loop.xml b/core/lib/Thelia/Config/Resources/loop.xml index bf5c9f7f9..c253b5fb4 100644 --- a/core/lib/Thelia/Config/Resources/loop.xml +++ b/core/lib/Thelia/Config/Resources/loop.xml @@ -49,6 +49,7 @@ + diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index 9fa7d1cbf..a966b2608 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -1040,6 +1040,16 @@ Thelia\Controller\Admin\LangController::deactivateDomainAction + + + + Thelia\Controller\Admin\TranslationsController::defaultAction + + + + Thelia\Controller\Admin\TranslationsController::updateAction + + diff --git a/core/lib/Thelia/Controller/Admin/BaseAdminController.php b/core/lib/Thelia/Controller/Admin/BaseAdminController.php index d34f2ce82..9eeedbbb7 100755 --- a/core/lib/Thelia/Controller/Admin/BaseAdminController.php +++ b/core/lib/Thelia/Controller/Admin/BaseAdminController.php @@ -43,6 +43,7 @@ use Symfony\Component\Routing\Router; use Thelia\Model\Admin; use Thelia\Core\Security\Token\CookieTokenProvider; use Thelia\Model\CurrencyQuery; +use Thelia\Core\Template\TemplateHelper; class BaseAdminController extends BaseController { @@ -199,7 +200,7 @@ class BaseAdminController extends BaseController $parser = $this->container->get("thelia.parser"); // Define the template thant shoud be used - $parser->setTemplate($template ?: ConfigQuery::read('base-admin-template', 'admin/default')); + $parser->setTemplate($template ?: TemplateHelper::getInstance()->getActiveAdminTemplate()->getPath()); return $parser; } diff --git a/core/lib/Thelia/Controller/Admin/OrderController.php b/core/lib/Thelia/Controller/Admin/OrderController.php index ff075b0e4..54dcc3059 100644 --- a/core/lib/Thelia/Controller/Admin/OrderController.php +++ b/core/lib/Thelia/Controller/Admin/OrderController.php @@ -36,6 +36,7 @@ use Thelia\Model\Base\OrderAddressQuery; use Thelia\Model\OrderQuery; use Thelia\Model\OrderStatusQuery; use Thelia\Tools\URL; +use Thelia\Core\Template\TemplateHelper; /** * Class OrderController @@ -218,7 +219,7 @@ class OrderController extends BaseAdminController array( 'order_id' => $order_id ), - ConfigQuery::read('pdf_template', 'pdf') + TemplateHelper::getInstance()->getActivePdfTemplate()->getPath() ); $order = OrderQuery::create()->findPk($order_id); diff --git a/core/lib/Thelia/Controller/Admin/ProductController.php b/core/lib/Thelia/Controller/Admin/ProductController.php index 1279dbff7..a711ada52 100644 --- a/core/lib/Thelia/Controller/Admin/ProductController.php +++ b/core/lib/Thelia/Controller/Admin/ProductController.php @@ -66,6 +66,7 @@ use Thelia\Model\Product; use Thelia\Model\CurrencyQuery; use Thelia\Form\ProductCombinationGenerationForm; use Thelia\Core\Event\Product\ProductCombinationGenerationEvent; +use Thelia\Core\Event\Product\ProductSetTemplateEvent; /** * Manages products diff --git a/core/lib/Thelia/Controller/Admin/TranslationsController.php b/core/lib/Thelia/Controller/Admin/TranslationsController.php new file mode 100644 index 000000000..1e6ba421c --- /dev/null +++ b/core/lib/Thelia/Controller/Admin/TranslationsController.php @@ -0,0 +1,194 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Controller\Admin; + + +use Thelia\Core\Security\Resource\AdminResources; +use Thelia\Core\Security\AccessManager; +use Thelia\Form\SystemLogConfigurationForm; +use Thelia\Log\Tlog; +use Thelia\Model\ConfigQuery; +use Thelia\Model\ModuleQuery; +use Thelia\Core\Template\TemplateHelper; +use Thelia\Core\Template\TemplateDefinition; +/** + * Class LangController + * @package Thelia\Controller\Admin + * @author Manuel Raynaud + */ +class TranslationsController extends BaseAdminController +{ + protected function renderTemplate() + { + + // Find modules + $modules = ModuleQuery::create()->joinI18n($this->getCurrentEditionLocale())->orderByPosition()->find(); + + TemplateHelper::getInstance()->getList(TemplateDefinition::BACK_OFFICE); + TemplateHelper::getInstance()->getList(TemplateDefinition::PDF); + TemplateHelper::getInstance()->getList(TemplateDefinition::FRONT_OFFICE); + + // Get related strings, if all input data are here + $item_to_translate = $this->getRequest()->get('item_to_translate'); + + $item_id = $this->getRequest()->get('item_id', ''); + + $all_strings = $translated_strings = array(); + + $template = $directory = $i18n_directory = false; + + if (! empty($item_id)) { + + 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(); + } + break; + + case 'fo' : + $template = new TemplateDefinition($item_id, TemplateDefinition::FRONT_OFFICE); + break; + + case 'bo' : + $template = new TemplateDefinition($item_id, TemplateDefinition::BACK_OFFICE); + break; + + case 'pf' : + $template = new TemplateDefinition($item_id, TemplateDefinition::PDF); + break; + } + + if ($template) { + $directory = THELIA_TEMPLATE_DIR . $template->getPath(); + $i18n_directory = THELIA_TEMPLATE_DIR . $template->getI18nPath(); + } + + if ($directory) { + + // Load strings + $this->walkDir($directory, $all_strings); + + // Load translated strings + if ($i18n_directory) { + $locale = $this->getCurrentEditionLocale(); + } + } + } + + return $this->render('translations', array( + 'item_to_translate' => $item_to_translate, + 'item_id' => $item_id, + 'all_strings' => $all_strings, + 'translated_strings' => $translated_strings, + 'view_missing_traductions_only' => $this->getRequest()->get('view_missing_traductions_only', 0) + )); + } + + public function defaultAction() + { + if (null !== $response = $this->checkAuth(AdminResources::TRANSLATIONS, AccessManager::VIEW)) return $response; + + return $this->renderTemplate(); + } + + public function updateAction() + { + if (null !== $response = $this->checkAuth(AdminResources::LANGUAGE, AccessManager::UPDATE)) return $response; + + 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, &$strings) { + try { + //echo "walking in $directory
"; + + foreach (new \DirectoryIterator($directory) as $fileInfo) { + + if ($fileInfo->isDot()) continue; + + if ($fileInfo->isDir()) $this->walkDir($fileInfo->getPathName(), $strings); + + if ($fileInfo->isFile()) { + + $ext = $fileInfo->getExtension(); + + if ($ext == 'html' || $ext == 'tpl' || $ext == 'xml') { + + 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('/{intl[\s]l=((? array($short_path), + 'chaine' => $match, + 'dollar' => strstr($match, '$') !== false); + } + } + } + } + } + } + } catch (\UnexpectedValueException $ex) { + echo $ex; + } + } + +} diff --git a/core/lib/Thelia/Core/DependencyInjection/Compiler/RegisterRouterPass.php b/core/lib/Thelia/Core/DependencyInjection/Compiler/RegisterRouterPass.php index 8fb086403..f92b7bf3d 100755 --- a/core/lib/Thelia/Core/DependencyInjection/Compiler/RegisterRouterPass.php +++ b/core/lib/Thelia/Core/DependencyInjection/Compiler/RegisterRouterPass.php @@ -67,26 +67,26 @@ class RegisterRouterPass implements CompilerPassInterface $modules = \Thelia\Model\ModuleQuery::getActivated(); foreach ($modules as $module) { - $moduleCode = ucfirst($module->getCode()); - if (file_exists(THELIA_MODULE_DIR . "/" . $moduleCode . "/Config/routing.xml")) { + $moduleBaseDir = $module->getBaseDir(); + if (file_exists(THELIA_MODULE_DIR . "/" . $moduleBaseDir . "/Config/routing.xml")) { $definition = new Definition( $container->getParameter("router.class"), array( new Reference("router.module.xmlLoader"), - ucfirst($module->getCode()) . "/Config/routing.xml", + $moduleBaseDir . "/Config/routing.xml", array( "cache_dir" => $container->getParameter("kernel.cache_dir"), "debug" => $container->getParameter("kernel.debug"), - "matcher_cache_class" => $container::camelize("ProjectUrlMatcher".$moduleCode), - "generator_cache_class" => $container::camelize("ProjectUrlGenerator".$moduleCode), + "matcher_cache_class" => $container::camelize("ProjectUrlMatcher".$moduleBaseDir), + "generator_cache_class" => $container::camelize("ProjectUrlGenerator".$moduleBaseDir), ), new Reference("request.context") ) ); - $container->setDefinition("router.".$moduleCode, $definition); + $container->setDefinition("router.".$moduleBaseDir, $definition); - $chainRouter->addMethodCall("add", array(new Reference("router.".$moduleCode), 150)); + $chainRouter->addMethodCall("add", array(new Reference("router.".$moduleBaseDir), 150)); } } } diff --git a/core/lib/Thelia/Core/Security/Resource/AdminResources.php b/core/lib/Thelia/Core/Security/Resource/AdminResources.php index 295de1fe8..834c2c628 100644 --- a/core/lib/Thelia/Core/Security/Resource/AdminResources.php +++ b/core/lib/Thelia/Core/Security/Resource/AdminResources.php @@ -99,4 +99,6 @@ final class AdminResources const TEMPLATE = "admin.configuration.template"; const SYSTEM_LOG = "admin.configuration.system-log"; + + const TRANSLATIONS = "admin.configuration.translations"; } diff --git a/core/lib/Thelia/Core/Template/Loop/Template.php b/core/lib/Thelia/Core/Template/Loop/Template.php index 83ef4fabe..b53c4d816 100644 --- a/core/lib/Thelia/Core/Template/Loop/Template.php +++ b/core/lib/Thelia/Core/Template/Loop/Template.php @@ -24,6 +24,7 @@ namespace Thelia\Core\Template\Loop; use Propel\Runtime\ActiveQuery\Criteria; +use Thelia\Core\Security\AccessManager; use Thelia\Core\Template\Element\BaseI18nLoop; use Thelia\Core\Template\Element\LoopResult; use Thelia\Core\Template\Element\LoopResultRow; @@ -31,29 +32,39 @@ use Thelia\Core\Template\Element\LoopResultRow; use Thelia\Core\Template\Loop\Argument\ArgumentCollection; use Thelia\Core\Template\Loop\Argument\Argument; -use Thelia\Model\Base\TemplateQuery; +use Thelia\Model\ModuleQuery; + +use Thelia\Module\BaseModule; +use Thelia\Type; +use Thelia\Core\Template\TemplateHelper; +use Thelia\Core\Template\TemplateDefinition; /** * - * Template loop + * Template loop, to get available back-office or front-office templates. * - * - * Class Template * @package Thelia\Core\Template\Loop - * @author Etienne Roudeix + * + * @author Franck Allimant */ class Template extends BaseI18nLoop { - public $timestampable = true; - /** * @return ArgumentCollection */ protected function getArgDefinitions() { return new ArgumentCollection( - Argument::createIntListTypeArgument('id'), - Argument::createIntListTypeArgument('exclude') + new Argument( + 'template_type', + new Type\TypeCollection( + new Type\EnumListType(array( + 'front-office', + 'back-office', + 'pdf' + )) + ) + ) ); } @@ -64,40 +75,27 @@ class Template extends BaseI18nLoop */ public function exec(&$pagination) { - $search = TemplateQuery::create(); + $type = $this->getArg(template_type); - $backendContext = $this->getBackend_context(); + if ($type == 'front-office') + $templateType = TemplateDefinition::FRONT_OFFICE; + else if ($type == 'back-office') + $templateType = TemplateDefinition::BACK_OFFICE; + else if ($type == 'pdf') + $templateType = TemplateDefinition::PDF; - $lang = $this->getLang(); + $templates = TemplateHelper::getInstance()->getList($templateType); - /* manage translations */ - $locale = $this->configureI18nProcessing($search, $columns = array('NAME')); - - $id = $this->getId(); - - if (null !== $id) { - $search->filterById($id, Criteria::IN); - } - - $exclude = $this->getExclude(); - - if (null !== $exclude) { - $search->filterById($exclude, Criteria::NOT_IN); - } - - /* perform search */ - $templates = $this->search($search, $pagination); - - $loopResult = new LoopResult($templates); + $loopResult = new LoopResult(); foreach ($templates as $template) { - $loopResultRow = new LoopResultRow($loopResult, $template, $this->versionable, $this->timestampable, $this->countable); + + $loopResultRow = new LoopResultRow($loopResult); $loopResultRow - ->set("ID", $template->getId()) - ->set("IS_TRANSLATED" , $template->getVirtualColumn('IS_TRANSLATED')) - ->set("LOCALE" , $locale) - ->set("NAME" , $template->getVirtualColumn('i18n_NAME')) + ->set("NAME" , $template->getName()) + ->set("RELATIVE_PATH" , $template->getPath()) + ->set("ABSOLUTE_PATH" , THELIA_TEMPLATE_DIR . $template->getPath()) ; $loopResult->addRow($loopResultRow); @@ -105,4 +103,4 @@ class Template extends BaseI18nLoop return $loopResult; } -} +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/AdminUtilities.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/AdminUtilities.php index 3b432cea9..0be66997a 100644 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/AdminUtilities.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/AdminUtilities.php @@ -29,6 +29,7 @@ use Thelia\Tools\URL; use Thelia\Core\Security\SecurityContext; use Thelia\Model\Config; use Thelia\Model\ConfigQuery; +use Thelia\Core\Template\TemplateHelper; /** * This class implements variour admin template utilities @@ -50,7 +51,7 @@ class AdminUtilities extends AbstractSmartyPlugin $snippet_path = sprintf('%s/%s/%s.html', THELIA_TEMPLATE_DIR, - ConfigQuery::read('base-admin-template', 'admin/default'), + TemplateHelper::getInstance()->getActiveAdminTemplate()->getPath(), $templateName ); diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/Module.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/Module.php index 2dfbb08fc..39c525c16 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/Module.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/Module.php @@ -48,7 +48,7 @@ class Module extends AbstractSmartyPlugin foreach ($modules as $module) { - $file = sprintf("%s/%s/AdminIncludes/%s.html", THELIA_MODULE_DIR, ucfirst($module->getCode()), $location); + $file = sprintf("%s/%s/AdminIncludes/%s.html", THELIA_MODULE_DIR, $module->getBaseDir(), $location); if (file_exists($file)) { $content .= file_get_contents($file); diff --git a/core/lib/Thelia/Core/Template/Smarty/SmartyParser.php b/core/lib/Thelia/Core/Template/Smarty/SmartyParser.php index 272f6787c..6b8e77d9e 100755 --- a/core/lib/Thelia/Core/Template/Smarty/SmartyParser.php +++ b/core/lib/Thelia/Core/Template/Smarty/SmartyParser.php @@ -14,6 +14,7 @@ use Thelia\Core\Template\Smarty\AbstractSmartyPlugin; use Thelia\Core\Template\Exception\ResourceNotFoundException; use Thelia\Core\Template\ParserContext; use Thelia\Model\ConfigQuery; +use Thelia\Core\Template\TemplateHelper; /** * @@ -62,7 +63,7 @@ class SmartyParser extends Smarty implements ParserInterface $this->setCompileDir($compile_dir); $this->setCacheDir($cache_dir); - $this->setTemplate($template ?: ConfigQuery::read('active-template', 'default')); + $this->setTemplate($template ?: TemplateHelper::getInstance()->getActiveFrontTemplate()->getPath()); $this->debugging = $debug; diff --git a/core/lib/Thelia/Core/Template/TemplateDefinition.php b/core/lib/Thelia/Core/Template/TemplateDefinition.php new file mode 100644 index 000000000..a88f46c75 --- /dev/null +++ b/core/lib/Thelia/Core/Template/TemplateDefinition.php @@ -0,0 +1,102 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Template; +use Thelia\Model\ConfigQuery; + +class TemplateDefinition +{ + const FRONT_OFFICE = 1; + const BACK_OFFICE = 2; + const PDF = 3; + + const BACK_OFFICE_SUBDIR = 'admin/'; + const PDF_SUBDIR = 'pdf/'; + + /** + * @var the template directory name (e.g. 'default') + */ + protected $name; + + /** + * @var the template directory full path + */ + protected $path; + + /** + * @var the template type (front, back, pdf) + */ + protected $type; + + + public function __construct($name, $type) + { + $this->name = $name; + $this->type = $type; + + if ($type == self::BACK_OFFICE) + $this->path = self::BACK_OFFICE_SUBDIR . $name; + else if ($type == self::PDF) + $this->path = self::PDF_SUBDIR . $name; + else + $this->path = $name; + } + + public function getName() + { + return $this->name; + } + + public function setName($name) + { + $this->name = $name; + return $this; + } + + public function getI18nPath() { + return $this->getPath() . DS . 'I18n'; + } + + public function getPath() + { + return $this->path; + } + + public function setPath($path) + { + $this->path = $path; + return $this; + } + + public function getType() + { + return $this->type; + } + + public function setType($type) + { + $this->type = $type; + return $this; + } + +} diff --git a/core/lib/Thelia/Core/Template/TemplateHelper.php b/core/lib/Thelia/Core/Template/TemplateHelper.php new file mode 100644 index 000000000..7ddbdf79a --- /dev/null +++ b/core/lib/Thelia/Core/Template/TemplateHelper.php @@ -0,0 +1,96 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Template; + +use Thelia\Model\ConfigQuery; + +class TemplateHelper +{ + /** + * This is a singleton + + */ + private static $instance = null; + + private function __construct() {} + + public static function getInstance() { + if (self::$instance == null) self::$instance = new TemplateHelper(); + + return self::$instance; + } + + public function getActivePdfTemplate() { + return new TemplateDefinition( + ConfigQuery::read('active-pdf-template', 'default'), + TemplateDefinition::PDF + ); + } + + public function getActiveAdminTemplate() { + return new TemplateDefinition( + ConfigQuery::read('active-admin-template', 'default'), + TemplateDefinition::BACK_OFFICE + ); + } + + public function getActiveFrontTemplate() { + return new TemplateDefinition( + ConfigQuery::read('active-admin-template', 'default'), + TemplateDefinition::FRONT_OFFICE + ); + } + + public function getList($templateType) { + + $list = $exclude = array(); + + if ($templateType == TemplateDefinition::BACK_OFFICE) { + $baseDir = THELIA_TEMPLATE_DIR.TemplateDefinition::BACK_OFFICE_SUBDIR; + } + else if ($templateType == TemplateDefinition::PDF) { + $baseDir = THELIA_TEMPLATE_DIR.TemplateDefinition::PDF_SUBDIR; + } + else { + $baseDir = THELIA_TEMPLATE_DIR; + + $exclude = array(TemplateDefinition::BACK_OFFICE_SUBDIR, TemplateDefinition::PDF_SUBDIR); + } + + // 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; + + // Ignore reserved directory names + if (in_array($file->getFilename()."/", $exclude)) continue; + + $list[] = new TemplateDefinition($file->getFilename(), $templateType); + } + + return $list; + } +} diff --git a/core/lib/Thelia/Core/Thelia.php b/core/lib/Thelia/Core/Thelia.php index fafe50171..50688b53b 100755 --- a/core/lib/Thelia/Core/Thelia.php +++ b/core/lib/Thelia/Core/Thelia.php @@ -52,6 +52,7 @@ use Symfony\Component\Config\FileLocator; use Propel\Runtime\Propel; use Propel\Runtime\Connection\ConnectionManagerSingle; +use Thelia\Core\Template\TemplateHelper; class Thelia extends Kernel { @@ -138,10 +139,10 @@ class Thelia extends Kernel $defintion ); - $loader = new XmlFileLoader($container, new FileLocator(THELIA_MODULE_DIR . "/" . ucfirst($module->getCode()) . "/Config")); + $loader = new XmlFileLoader($container, new FileLocator(THELIA_MODULE_DIR . $module->getConfigPath())); $loader->load("config.xml"); - if (is_dir($dir = THELIA_MODULE_DIR . "/" . ucfirst($module->getCode()) . "/I18n")) { + if (is_dir($dir = THELIA_MODULE_DIR . $module->getI18nPath())) { $dirs[] = $dir; } } catch (\InvalidArgumentException $e) { @@ -149,18 +150,22 @@ class Thelia extends Kernel } } - //Load translation from templates + // Load translation from templates //core translation - $dirs[] = THELIA_ROOT . "/core/lib/Thelia/Config/I18n"; + $dirs[] = THELIA_ROOT . "core/lib/Thelia/Config/I18n"; - //admin template - if(is_dir($dir = THELIA_TEMPLATE_DIR . '/admin/default/I18n')) { + // admin template + if (is_dir($dir = THELIA_TEMPLATE_DIR . TemplateHelper::getInstance()->getActiveAdminTemplate()->getI18nPath())) { $dirs[] = $dir; } - //front template - $template = ConfigQuery::getActiveTemplate(); - if(is_dir($dir = THELIA_TEMPLATE_DIR . $template . "/I18n")) { + // front template + if (is_dir($dir = THELIA_TEMPLATE_DIR . TemplateHelper::getInstance()->getActiveFrontTemplate()->getI18nPath())) { + $dirs[] = $dir; + } + + // PDF template + if (is_dir($dir = THELIA_TEMPLATE_DIR . TemplateHelper::getInstance()->getActivePdfTemplate()->getI18nPath())) { $dirs[] = $dir; } diff --git a/core/lib/Thelia/Model/ConfigQuery.php b/core/lib/Thelia/Model/ConfigQuery.php index 71ff253ea..e2f6a3975 100755 --- a/core/lib/Thelia/Model/ConfigQuery.php +++ b/core/lib/Thelia/Model/ConfigQuery.php @@ -82,12 +82,6 @@ class ConfigQuery extends BaseConfigQuery { return self::read('passed_url_view', 'passed-url'); } - - public static function getActiveTemplate() - { - return self::read('active-template', 'default'); - } - public static function useTaxFreeAmounts() { return self::read('use_tax_free_amounts', 'default') == 1; diff --git a/core/lib/Thelia/Model/Map/ConfigTableMap.php b/core/lib/Thelia/Model/Map/ConfigTableMap.php index ebd5d6edf..8208b56fe 100644 --- a/core/lib/Thelia/Model/Map/ConfigTableMap.php +++ b/core/lib/Thelia/Model/Map/ConfigTableMap.php @@ -166,7 +166,7 @@ class ConfigTableMap extends TableMap // columns $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); $this->addColumn('NAME', 'Name', 'VARCHAR', true, 255, null); - $this->addColumn('VALUE', 'Value', 'VARCHAR', true, 255, null); + $this->addColumn('VALUE', 'Value', 'LONGVARCHAR', true, null, null); $this->addColumn('SECURED', 'Secured', 'TINYINT', true, null, 1); $this->addColumn('HIDDEN', 'Hidden', 'TINYINT', true, null, 1); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); diff --git a/core/lib/Thelia/Model/Module.php b/core/lib/Thelia/Model/Module.php index c9ccd5f8d..d57df77fa 100755 --- a/core/lib/Thelia/Model/Module.php +++ b/core/lib/Thelia/Model/Module.php @@ -11,4 +11,25 @@ class Module extends BaseModule { { ModuleQuery::resetActivated(); } + + /** + * @return the module's base directory path, relative to THELIA_MODULE_DIR + */ + public function getBaseDir() { + return ucfirst($this->getCode()); + } + + /** + * @return the module's config directory path, relative to THELIA_MODULE_DIR + */ + public function getConfigPath() { + return $this->getBaseDir() . DS . "Config"; + } + + /** + * @return the module's i18N directory path, relative to THELIA_MODULE_DIR + */ + public function getI18nPath() { + return $this->getBaseDir() . DS . "I18n"; + } } diff --git a/install/insert.sql b/install/insert.sql index 7ceb6ce34..ea26fbd6f 100755 --- a/install/insert.sql +++ b/install/insert.sql @@ -8,7 +8,8 @@ INSERT INTO `config` (`name`, `value`, `secured`, `hidden`, `created_at`, `updat ('session_config.default', '1', 1, 1, NOW(), NOW()), ('verifyStock', '1', 0, 0, NOW(), NOW()), ('active-template', 'default', 0, 0, NOW(), NOW()), -('base-admin-template', 'admin/default', 0, 0, NOW(), NOW()), +('active-admin-template', 'default', 0, 0, NOW(), NOW()), +('active-pdf-template', 'default', 0, 0, NOW(), NOW()), ('default_lang_without_translation', '1', 1, 1, NOW(), NOW()), ('rewriting_enable', '0', 0, 0, NOW(), NOW()), ('imagine_graphic_driver', 'gd', 0, 0, NOW(), NOW()), @@ -33,6 +34,8 @@ INSERT INTO `config` (`name`, `value`, `secured`, `hidden`, `created_at`, `updat ('contact_email','', 0, 0, NOW(), NOW()), ('url_site','', 0, 0, NOW(), NOW()), ('one_domain_foreach_lang','0', 1, 1, NOW(), NOW()), +('pdf_invoice_file', 'invoice', 0, 0, NOW(), NOW()), +('pdf_delivery_file', 'delivery', 0, 0, NOW(), NOW()), ('thelia_version','2.0.0-beta1', 1, 1, NOW(), NOW()), ('thelia_major_version','2', 1, 1, NOW(), NOW()), ('thelia_minus_version','0', 1, 1, NOW(), NOW()), @@ -1207,7 +1210,7 @@ generated with command : php Thelia thelia:generate-resources --output sql */ INSERT INTO resource (`id`, `code`, `created_at`, `updated_at`) VALUES (1, 'admin.address', NOW(), NOW()), -(2, 'admin.configuration.admin', NOW(), NOW()), +(2, 'admin.configuration.administrator', NOW(), NOW()), (3, 'admin.configuration.area', NOW(), NOW()), (4, 'admin.configuration.attribute', NOW(), NOW()), (5, 'admin.category', NOW(), NOW()), @@ -1228,7 +1231,8 @@ INSERT INTO resource (`id`, `code`, `created_at`, `updated_at`) VALUES (20, 'admin.configuration.profile', NOW(), NOW()), (21, 'admin.configuration.shipping-zone', NOW(), NOW()), (22, 'admin.configuration.tax', NOW(), NOW()), -(23, 'admin.configuration.template', NOW(), NOW()); +(23, 'admin.configuration.template', NOW(), NOW()), +(24, 'admin.configuration.system-log', NOW(), NOW()); /** generated with command : php Thelia thelia:generate-resources --output sql-i18n @@ -1236,8 +1240,8 @@ generated with command : php Thelia thelia:generate-resources --output sql-i18n INSERT INTO resource_i18n (`id`, `locale`, `title`) VALUES (1, 'en_US', 'Address'), (1, 'fr_FR', 'Address'), -(2, 'en_US', 'Configuration / Admin'), -(2, 'fr_FR', 'Configuration / Admin'), +(2, 'en_US', 'Configuration / Administrator'), +(2, 'fr_FR', 'Configuration / Administrator'), (3, 'en_US', 'Configuration / Area'), (3, 'fr_FR', 'Configuration / Area'), (4, 'en_US', 'Configuration / Attribute'), @@ -1279,7 +1283,9 @@ INSERT INTO resource_i18n (`id`, `locale`, `title`) VALUES (22, 'en_US', 'Configuration / Tax'), (22, 'fr_FR', 'Configuration / Tax'), (23, 'en_US', 'Configuration / Template'), -(23, 'fr_FR', 'Configuration / Template'); +(23, 'fr_FR', 'Configuration / Template'), +(24, 'en_US', 'Configuration / System Log'), +(24, 'fr_FR', 'Configuration / Logs système'); INSERT INTO `message` (`id`, `name`, `secured`, `created_at`, `updated_at`, `version`, `version_created_at`, `version_created_by`) VALUES diff --git a/install/thelia.sql b/install/thelia.sql index b213c114f..ed27071fb 100755 --- a/install/thelia.sql +++ b/install/thelia.sql @@ -416,7 +416,7 @@ CREATE TABLE `config` ( `id` INTEGER NOT NULL AUTO_INCREMENT, `name` VARCHAR(255) NOT NULL, - `value` VARCHAR(255) NOT NULL, + `value` TEXT NOT NULL, `secured` TINYINT DEFAULT 1 NOT NULL, `hidden` TINYINT DEFAULT 1 NOT NULL, `created_at` DATETIME, diff --git a/templates/admin/default/admin-logs.html b/templates/admin/default/admin-logs.html index 8f86729b7..74273a6c9 100755 --- a/templates/admin/default/admin-logs.html +++ b/templates/admin/default/admin-logs.html @@ -26,98 +26,106 @@
- +
-
-
- {intl l='Period'} : -
+
+
+
+ {intl l='Period'} : +
-
-
-
- {intl l='From'} - - - - -
-
-
-
- {intl l='To'} - - - - -
-
-
+
+
+
+ {intl l='From'} + + + + +
+
+
+
+ {intl l='To'} + + + + +
+
+
+
-
-
- {intl l='Administrators'} : -
+
+
+
+ {intl l='Administrators'} : +
-
- {loop type="admin" name="admin-list" backend_context="1"} - {if ($LOOP_COUNT-1)%4 == 0 AND $LOOP_COUNT != 0 AND $LOOP_COUNT != $LOOP_TOTAL} -
-
- {/if} -
- - -
- {/loop} -
+
+ {loop type="admin" name="admin-list" backend_context="1"} + {if ($LOOP_COUNT-1)%4 == 0 AND $LOOP_COUNT != 0 AND $LOOP_COUNT != $LOOP_TOTAL} +
+
+ {/if} +
+ + +
+ {/loop} +
+
+
+ +
+
+
+ {intl l='Resources'} : +
+ +
+ {loop type="resource" name="resources-list" backend_context="1"} + {if ($LOOP_COUNT-1)%4 == 0 AND $LOOP_COUNT != 0 AND $LOOP_COUNT != $LOOP_TOTAL} +
+
+ {/if} +
+ + +
+ {/loop} +
+ +
-
-
- {intl l='Resources'} : -
+
+
+
+ {intl l='Modules'} : +
-
- {loop type="resource" name="resources-list" backend_context="1"} - {if ($LOOP_COUNT-1)%4 == 0 AND $LOOP_COUNT != 0 AND $LOOP_COUNT != $LOOP_TOTAL} -
-
- {/if} -
- - -
- {/loop} -
- -
- -
-
- {intl l='Modules'} : -
- -
- {loop type="module" name="modules-list" backend_context="1"} - {if ($LOOP_COUNT-1)%4 == 0 AND $LOOP_COUNT != 0 AND $LOOP_COUNT != $LOOP_TOTAL} -
-
- {/if} -
- - -
- {/loop} -
+
+ {loop type="module" name="modules-list" backend_context="1"} + {if ($LOOP_COUNT-1)%4 == 0 AND $LOOP_COUNT != 0 AND $LOOP_COUNT != $LOOP_TOTAL} +
+
+ {/if} +
+ + +
+ {/loop} +
+
@@ -129,7 +137,6 @@
-
diff --git a/templates/admin/default/configuration.html b/templates/admin/default/configuration.html index 9f0cc4160..6b4428b1a 100644 --- a/templates/admin/default/configuration.html +++ b/templates/admin/default/configuration.html @@ -151,6 +151,13 @@ {/loop} + {loop type="auth" name="pcc5.1" role="ADMIN" resource="admin.configuration.translations" access="VIEW"} + + {intl l='Translations'} + + + {/loop} + {loop type="auth" name="pcc6" role="ADMIN" resource="admin.configuration.mailing-system" access="VIEW"} {intl l='Mailing system'} diff --git a/templates/admin/default/customer-edit.html b/templates/admin/default/customer-edit.html index 370fe11f3..954deceb3 100644 --- a/templates/admin/default/customer-edit.html +++ b/templates/admin/default/customer-edit.html @@ -23,7 +23,7 @@
- {intl l="Edit customer $FIRSTNAME $LASTNAME"} + {intl l="Edit customer %firstname %lastname" firstname=$FIRSTNAME lastname=$LASTNAME}
@@ -143,7 +143,7 @@

- +
diff --git a/templates/admin/default/translations.html b/templates/admin/default/translations.html new file mode 100644 index 000000000..946e68cdb --- /dev/null +++ b/templates/admin/default/translations.html @@ -0,0 +1,238 @@ +{extends file="admin-layout.tpl"} + +{block name="page-title"}{intl l='Translations'}{/block} + +{block name="check-resource"}admin.configuration.variable{/block} +{block name="check-access"}update{/block} + +{block name="main-content"} +
+ +
+ + + +
+
+
+ +
+ {intl l="Translation"} +
+ +
+
+
+
+ + {include + file = "includes/inner-form-toolbar.html" + close_url = {url path='/admin/configuration'} + } + +
+
+
+ + + +
+
+ + {if $item_to_translate == 'mo'} +
+
+ + + +
+
+ {else if $item_to_translate == 'fo'} +
+
+ + + +
+
+ {else if $item_to_translate == 'bo'} +
+
+ + + +
+
+ {else if $item_to_translate == 'pf'} +
+
+ + + +
+
+ {/if} + + +
+
+ + +
+
+
+
+ + {* -- STRINGS TO TRANSLATE --------------------------------------------- *} + + {$currfile = false} + {$untranslated = 0} + + {foreach $all_strings as $hash => $info} + + {if $view_missing_traductions_only != 1 || ! isset($translated_strings[$info.chaine]) || $translated_strings[$info.chaine]== ''} + + {* Create a liste of files names *} + + {if count($info.files) > 1} + {$label = {intl l='In pages:'}} + {capture name="banner" assign=file_names} +
    + {foreach $info.files as $file} +
  • {$file}
  • + {/foreach} +
+ {/capture} + {else} + {$label = {intl l='In page'}} + {$file_names = $info.files.0} + {/if} + + {* Display current file liste, if required *} + + {if $file_names != $currfile} + + {if $currfile !== false} + {* Close current panel *} +
+
+ {/if} + + {$currfile = $file_names} + +
+
+ {loop name="lang_list" type="lang" id=$edit_language_id} + {intl l=$TITLE} + {/loop} + + {$label} {$file_names nofilter} + +
+ + + + {/if} + + + + + + + {/if} + + {/foreach} + +
+ {$info.chaine} + + {if $info.dollar} + {intl l='Warning'} + {intl l='This string contains a Smarty variable, and cannot not be translated properly'} + {/if} + +
+ + +
+
+
{* panel *} + + +
+
+
+ + + + + +{/block} + +{block name="javascript-initialization"} + +{/block} diff --git a/templates/admin/default/variable-edit.html b/templates/admin/default/variable-edit.html index dfc572ec2..267ffb89e 100644 --- a/templates/admin/default/variable-edit.html +++ b/templates/admin/default/variable-edit.html @@ -16,7 +16,7 @@
  • {intl l="Home"}
  • {intl l="Configuration"}
  • {intl l="System variables"}
  • -
  • {intl l='Editing variable "%name"' name="{$NAME}"}
  • +
  • {intl l='Editing variable "%name"' name=$NAME}
  • @@ -24,7 +24,7 @@
    - {intl l="Edit variable $NAME"} + {intl l="Edit variable %name" name=$NAME}
    diff --git a/templates/pdf/default/I18n/en_US.php b/templates/pdf/default/I18n/en_US.php new file mode 100644 index 000000000..8f9845d30 --- /dev/null +++ b/templates/pdf/default/I18n/en_US.php @@ -0,0 +1,4 @@ +