From d8e0a0aa1116927000c16fe507f95405b251906e Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Mon, 28 Oct 2013 12:03:38 +0100 Subject: [PATCH 01/59] update category/product edit link on images --- templates/admin/default/categories.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/admin/default/categories.html b/templates/admin/default/categories.html index 549d52d23..e25b79f1e 100755 --- a/templates/admin/default/categories.html +++ b/templates/admin/default/categories.html @@ -100,7 +100,7 @@ {loop type="image" name="cat_image" source="category" source_id="$ID" limit="1" width="50" height="50" resize_mode="crop" backend_context="1"} - {$TITLE} + {$TITLE} {/loop} @@ -269,7 +269,7 @@ {loop type="image" name="cat_image" source="product" source_id="$ID" limit="1" width="50" height="50" resize_mode="crop" backend_context="1"} - + {$TITLE} {/loop} From 40a99e6f822825aba5e9065e44923eebefe5c6e3 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Mon, 28 Oct 2013 12:05:42 +0100 Subject: [PATCH 02/59] fix foler/content edit link --- templates/admin/default/folders.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/admin/default/folders.html b/templates/admin/default/folders.html index a81165dd1..5a7d9a175 100644 --- a/templates/admin/default/folders.html +++ b/templates/admin/default/folders.html @@ -105,7 +105,7 @@ {loop type="image" name="folder_image" source="folder" source_id="$ID" limit="1" width="50" height="50" resize_mode="crop" backend_context="1"} - {$TITLE} + {$TITLE} {/loop} @@ -264,7 +264,7 @@ {loop type="image" name="folder_image" source="content" source_id="$ID" limit="1" width="50" height="50" resize_mode="crop" backend_context="1"} - + {$TITLE} {/loop} From 3ac7d97661c5c020913fdb4eb6735fac366dad9c Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Mon, 28 Oct 2013 12:09:47 +0100 Subject: [PATCH 03/59] remove company column in customer list --- templates/admin/default/customers.html | 8 -------- 1 file changed, 8 deletions(-) diff --git a/templates/admin/default/customers.html b/templates/admin/default/customers.html index 7da2815b9..cc48b8197 100644 --- a/templates/admin/default/customers.html +++ b/templates/admin/default/customers.html @@ -44,10 +44,6 @@ {intl l="customer ref"} - - {intl l="company"} - - {module_include location='category_list_header'} @@ -81,10 +77,6 @@ {$REF} - - {$COMPANY} - - {$FIRSTNAME} {$LASTNAME} From f44d1dde73d205a6c36e04f68b12bccf8e055351 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Mon, 28 Oct 2013 12:16:56 +0100 Subject: [PATCH 04/59] change class for button group in customer list --- templates/admin/default/customers.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/admin/default/customers.html b/templates/admin/default/customers.html index cc48b8197..81a60fdf3 100644 --- a/templates/admin/default/customers.html +++ b/templates/admin/default/customers.html @@ -90,7 +90,7 @@ {$lastOrderCurrency} {$lastOrderAmount} - +
{loop type="auth" name="can_change" role="ADMIN" resource="admin.customer" access="UPDATE"} From 2eb5fc821cac9ddf2802a2b2c7f4bfa7e466158e Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Mon, 28 Oct 2013 12:24:59 +0100 Subject: [PATCH 05/59] mailing sytem admin --- core/lib/Thelia/Action/MailingSystem.php | 62 ++++++ core/lib/Thelia/Config/Resources/action.xml | 5 + core/lib/Thelia/Config/Resources/config.xml | 2 + .../Thelia/Config/Resources/routing/admin.xml | 12 ++ .../Admin/MailingSystemController.php | 87 ++++++++- .../MailingSystem/MailingSystemEvent.php | 183 ++++++++++++++++++ core/lib/Thelia/Core/Event/TheliaEvents.php | 4 + .../Form/MailingSystemModificationForm.php | 95 +++++++++ core/lib/Thelia/Mailer/MailerFactory.php | 18 +- core/lib/Thelia/Model/ConfigQuery.php | 114 +++++++++++ templates/admin/default/configuration.html | 6 +- templates/admin/default/mailing-system.html | 130 ++++++++----- 12 files changed, 653 insertions(+), 65 deletions(-) create mode 100644 core/lib/Thelia/Action/MailingSystem.php create mode 100644 core/lib/Thelia/Core/Event/MailingSystem/MailingSystemEvent.php create mode 100644 core/lib/Thelia/Form/MailingSystemModificationForm.php diff --git a/core/lib/Thelia/Action/MailingSystem.php b/core/lib/Thelia/Action/MailingSystem.php new file mode 100644 index 000000000..f46352d53 --- /dev/null +++ b/core/lib/Thelia/Action/MailingSystem.php @@ -0,0 +1,62 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Action; + +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Thelia\Core\Event\MailingSystem\MailingSystemEvent; +use Thelia\Core\Event\TheliaEvents; +use Thelia\Model\ConfigQuery; + +class MailingSystem extends BaseAction implements EventSubscriberInterface +{ + /** + * @param MailingSystemEvent $event + */ + public function update(MailingSystemEvent $event) + { + if($event->getEnabled()) { + ConfigQuery::enableSmtp(); + } else { + ConfigQuery::disableSmtp(); + } + ConfigQuery::setSmtpHost($event->getHost()); + ConfigQuery::setSmtpPort($event->getPort()); + ConfigQuery::setSmtpEncryption($event->getEncryption()); + ConfigQuery::setSmtpUsername($event->getUsername()); + ConfigQuery::setSmtpPassword($event->getPassword()); + ConfigQuery::setSmtpAuthMode($event->getAuthMode()); + ConfigQuery::setSmtpTimeout($event->getTimeout()); + ConfigQuery::setSmtpSourceIp($event->getSourceIp()); + } + + /** + * {@inheritDoc} + */ + public static function getSubscribedEvents() + { + return array( + TheliaEvents::MAILING_SYSTEM_UPDATE => array("update", 128), + ); + } +} diff --git a/core/lib/Thelia/Config/Resources/action.xml b/core/lib/Thelia/Config/Resources/action.xml index 1901edfec..60c435a05 100755 --- a/core/lib/Thelia/Config/Resources/action.xml +++ b/core/lib/Thelia/Config/Resources/action.xml @@ -166,6 +166,11 @@ + + + + + diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index 6f635df9c..c0af99896 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -148,6 +148,8 @@
+ + diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index afaacb85a..259c0f54a 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -812,6 +812,18 @@ + + + + Thelia\Controller\Admin\MailingSystemController::defaultAction + + + + Thelia\Controller\Admin\MailingSystemController::updateAction + + + + diff --git a/core/lib/Thelia/Controller/Admin/MailingSystemController.php b/core/lib/Thelia/Controller/Admin/MailingSystemController.php index 5bf2f4e73..cfe6f06dd 100644 --- a/core/lib/Thelia/Controller/Admin/MailingSystemController.php +++ b/core/lib/Thelia/Controller/Admin/MailingSystemController.php @@ -23,20 +23,91 @@ namespace Thelia\Controller\Admin; -use Thelia\Core\Security\Resource\AdminResources; +use Thelia\Core\Event\MailingSystem\MailingSystemEvent; +use Thelia\Core\Event\TheliaEvents; use Thelia\Core\Security\AccessManager; +use Thelia\Form\Exception\FormValidationException; +use Thelia\Form\MailingSystemModificationForm; +use Thelia\Model\ConfigQuery; -/** - * Class MailingSystemController - * @package Thelia\Controller\Admin - * @author Manuel Raynaud - */ class MailingSystemController extends BaseAdminController { + const RESOURCE_CODE = "admin.mailing-system"; + public function defaultAction() { - if (null !== $response = $this->checkAuth(AdminResources::MAILING_SYSTEM, AccessManager::VIEW)) return $response; - return $this->render("mailing-system"); + if (null !== $response = $this->checkAuth(self::RESOURCE_CODE, AccessManager::VIEW)) return $response; + + // Hydrate the form abd pass it to the parser + $data = array( + 'enabled' => ConfigQuery::isSmtpEnable() ? 1 : 0, + 'host' => ConfigQuery::getSmtpHost(), + 'port' => ConfigQuery::getSmtpPort(), + 'encryption' => ConfigQuery::getSmtpEncryption(), + 'username' => ConfigQuery::getSmtpUsername(), + 'password' => ConfigQuery::getSmtpPassword(), + 'authmode' => ConfigQuery::getSmtpAuthMode(), + 'timeout' => ConfigQuery::getSmtpTimeout(), + 'sourceip' => ConfigQuery::getSmtpSourceIp(), + ); + + // Setup the object form + $form = new MailingSystemModificationForm($this->getRequest(), "form", $data); + + // Pass it to the parser + $this->getParserContext()->addForm($form); + + // Render the edition template. + return $this->render('mailing-system'); } + public function updateAction() + { + // Check current user authorization + if (null !== $response = $this->checkAuth(self::RESOURCE_CODE, AccessManager::UPDATE)) return $response; + + $error_msg = false; + + // Create the form from the request + $form = new MailingSystemModificationForm($this->getRequest()); + + try { + + // Check the form against constraints violations + $formData = $this->validateForm($form, "POST"); + + // Get the form field values + $event = new MailingSystemEvent(); + $event->setEnabled($formData->get('enabled')->getData()); + $event->setHost($formData->get('host')->getData()); + $event->setPort($formData->get('port')->getData()); + $event->setEncryption($formData->get('encryption')->getData()); + $event->setUsername($formData->get('username')->getData()); + $event->setPassword($formData->get('password')->getData()); + $event->setAuthMode($formData->get('authmode')->getData()); + $event->setTimeout($formData->get('timeout')->getData()); + $event->setSourceIp($formData->get('sourceip')->getData()); + + $this->dispatch(TheliaEvents::MAILING_SYSTEM_UPDATE, $event); + + // Redirect to the success URL + $this->redirectToRoute("admin.configuration.mailing-system.view"); + } catch (FormValidationException $ex) { + // Form cannot be validated + $error_msg = $this->createStandardFormValidationErrorMessage($ex); + } catch (\Exception $ex) { + // Any other error + $error_msg = $ex->getMessage(); + } + + $this->setupFormErrorContext( + $this->getTranslator()->trans("mailing system modification", array()), + $error_msg, + $form, + $ex + ); + + // At this point, the form has errors, and should be redisplayed. + return $this->render('mailing-system'); + } } diff --git a/core/lib/Thelia/Core/Event/MailingSystem/MailingSystemEvent.php b/core/lib/Thelia/Core/Event/MailingSystem/MailingSystemEvent.php new file mode 100644 index 000000000..02cb25e6e --- /dev/null +++ b/core/lib/Thelia/Core/Event/MailingSystem/MailingSystemEvent.php @@ -0,0 +1,183 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event\MailingSystem; + +use Thelia\Core\Event\ActionEvent; + +class MailingSystemEvent extends ActionEvent +{ + protected $enabled = null; + protected $host = null; + protected $port = null; + protected $encryption = null; + protected $username = null; + protected $password = null; + protected $authMode = null; + protected $timeout = null; + protected $sourceIp = null; + + /** + * @param null $authMode + */ + public function setAuthMode($authMode) + { + $this->authMode = $authMode; + } + + /** + * @return null + */ + public function getAuthMode() + { + return $this->authMode; + } + + /** + * @param null $enabled + */ + public function setEnabled($enabled) + { + $this->enabled = $enabled; + } + + /** + * @return null + */ + public function getEnabled() + { + return $this->enabled; + } + + /** + * @param null $encryption + */ + public function setEncryption($encryption) + { + $this->encryption = $encryption; + } + + /** + * @return null + */ + public function getEncryption() + { + return $this->encryption; + } + + /** + * @param null $host + */ + public function setHost($host) + { + $this->host = $host; + } + + /** + * @return null + */ + public function getHost() + { + return $this->host; + } + + /** + * @param null $password + */ + public function setPassword($password) + { + $this->password = $password; + } + + /** + * @return null + */ + public function getPassword() + { + return $this->password; + } + + /** + * @param null $port + */ + public function setPort($port) + { + $this->port = $port; + } + + /** + * @return null + */ + public function getPort() + { + return $this->port; + } + + /** + * @param null $sourceIp + */ + public function setSourceIp($sourceIp) + { + $this->sourceIp = $sourceIp; + } + + /** + * @return null + */ + public function getSourceIp() + { + return $this->sourceIp; + } + + /** + * @param null $timeout + */ + public function setTimeout($timeout) + { + $this->timeout = $timeout; + } + + /** + * @return null + */ + public function getTimeout() + { + return $this->timeout; + } + + /** + * @param null $username + */ + public function setUsername($username) + { + $this->username = $username; + } + + /** + * @return null + */ + public function getUsername() + { + return $this->username; + } +} diff --git a/core/lib/Thelia/Core/Event/TheliaEvents.php b/core/lib/Thelia/Core/Event/TheliaEvents.php index 5bb6028a9..42b20d8cd 100755 --- a/core/lib/Thelia/Core/Event/TheliaEvents.php +++ b/core/lib/Thelia/Core/Event/TheliaEvents.php @@ -566,6 +566,10 @@ final class TheliaEvents const ADMINISTRATOR_UPDATE = "action.updateAdministrator"; const ADMINISTRATOR_DELETE = "action.deleteAdministrator"; + // -- Mailing System management --------------------------------------------- + + const MAILING_SYSTEM_UPDATE = "action.updateMailingSystem"; + // -- Tax Rules management --------------------------------------------- const TAX_RULE_CREATE = "action.createTaxRule"; diff --git a/core/lib/Thelia/Form/MailingSystemModificationForm.php b/core/lib/Thelia/Form/MailingSystemModificationForm.php new file mode 100644 index 000000000..8334777ab --- /dev/null +++ b/core/lib/Thelia/Form/MailingSystemModificationForm.php @@ -0,0 +1,95 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form; + +use Symfony\Component\Validator\Constraints; +use Symfony\Component\Validator\Constraints\NotBlank; +use Symfony\Component\Validator\ExecutionContextInterface; +use Thelia\Core\Translation\Translator; +use Thelia\Model\ProfileQuery; + +/** + * Class MailingSystemModificationForm + * @package Thelia\Form + * @author Etienne Roudeix + */ +class MailingSystemModificationForm extends BaseForm +{ + protected function buildForm($change_mode = false) + { + $this->formBuilder + ->add("enabled", "choice", array( + "choices" => array(1 => "Yes", 0 => "No"), + "label" => Translator::getInstance()->trans("Enable remote SMTP use"), + "label_attr" => array("for" => "enabled_field"), + )) + ->add("host", "text", array( + "label" => Translator::getInstance()->trans("Host"), + "label_attr" => array("for" => "host_field"), + )) + ->add("port", "text", array( + "label" => Translator::getInstance()->trans("Port"), + "label_attr" => array("for" => "port_field"), + )) + ->add("encryption", "text", array( + "label" => Translator::getInstance()->trans("Encryption"), + "label_attr" => array("for" => "encryption_field"), + )) + ->add("username", "text", array( + "label" => Translator::getInstance()->trans("Username"), + "label_attr" => array("for" => "username_field"), + )) + ->add("password", "text", array( + "label" => Translator::getInstance()->trans("Password"), + "label_attr" => array("for" => "password_field"), + )) + ->add("authmode", "text", array( + "label" => Translator::getInstance()->trans("Auth mode"), + "label_attr" => array("for" => "authmode_field"), + )) + ->add("timeout", "text", array( + "label" => Translator::getInstance()->trans("Timeout"), + "label_attr" => array("for" => "timeout_field"), + )) + ->add("sourceip", "text", array( + "label" => Translator::getInstance()->trans("Source IP"), + "label_attr" => array("for" => "sourceip_field"), + )) + ; + } + + public function getName() + { + return "thelia_mailing_system_modification"; + } + + /*public function verifyCode($value, ExecutionContextInterface $context) + { + $profile = ProfileQuery::create() + ->findOneByCode($value); + + if (null !== $profile) { + $context->addViolation("Profile `code` already exists"); + } + }*/ +} diff --git a/core/lib/Thelia/Mailer/MailerFactory.php b/core/lib/Thelia/Mailer/MailerFactory.php index a327a155f..e4fee490e 100644 --- a/core/lib/Thelia/Mailer/MailerFactory.php +++ b/core/lib/Thelia/Mailer/MailerFactory.php @@ -52,7 +52,7 @@ class MailerFactory { if($transporterEvent->hasTransporter()) { $transporter = $transporterEvent->getTransporter(); } else { - if (ConfigQuery::read("smtp.enabled")) { + if (ConfigQuery::isSmtpEnable()) { $transporter = $this->configureSmtp(); } else { $transporter = \Swift_MailTransport::newInstance(); @@ -65,14 +65,14 @@ class MailerFactory { private function configureSmtp() { $smtpTransporter = new \Swift_SmtpTransport(); - $smtpTransporter->setHost(Configquery::read('smtp.host', 'localhost')) - ->setPort(ConfigQuery::read('smtp.host')) - ->setEncryption(ConfigQuery::read('smtp.encryption')) - ->setUsername(ConfigQuery::read('smtp.username')) - ->setPassword(ConfigQuery::read('smtp.password')) - ->setAuthMode(ConfigQuery::read('smtp.authmode')) - ->setTimeout(ConfigQuery::read('smtp.timeout', 30)) - ->setSourceIp(ConfigQuery::read('smtp.sourceip')) + $smtpTransporter->setHost(Configquery::getSmtpHost()) + ->setPort(ConfigQuery::getSmtpPort()) + ->setEncryption(ConfigQuery::getSmtpEncryption()) + ->setUsername(ConfigQuery::getSmtpUsername()) + ->setPassword(ConfigQuery::getSmtpPassword()) + ->setAuthMode(ConfigQuery::getSmtpAuthMode()) + ->setTimeout(ConfigQuery::getSmtpTimeout()) + ->setSourceIp(ConfigQuery::getSmtpSourceIp()) ; return $smtpTransporter; } diff --git a/core/lib/Thelia/Model/ConfigQuery.php b/core/lib/Thelia/Model/ConfigQuery.php index fb8d6fe90..11bbc51d6 100755 --- a/core/lib/Thelia/Model/ConfigQuery.php +++ b/core/lib/Thelia/Model/ConfigQuery.php @@ -32,6 +32,23 @@ class ConfigQuery extends BaseConfigQuery { return self::$cache[$search]; } + public static function write($configName, $value, $secured, $hidden) + { + $config = self::create()->findOneByName($configName); + + if(null == $config) { + $config = new Config(); + $config->setName($configName); + } + + $config->setSecured($secured ? 1 : 0); + $config->setHidden($hidden ? 1 : 0); + $config->setValue($value); + $config->save(); + + self::$cache[$configName] = $value; + } + public static function resetCache($key = null) { if($key) { @@ -74,4 +91,101 @@ class ConfigQuery extends BaseConfigQuery { { return self::read('use_tax_free_amounts', 'default') == 1; } + + /* smtp config */ + public static function isSmtpEnable() + { + return self::read('smtp.enabled') == 1; + } + + public static function getSmtpHost() + { + return self::read('smtp.host', 'localhost'); + } + + public static function getSmtpPort() + { + return self::read('smtp.port'); + } + + public static function getSmtpEncryption() + { + return self::read('smtp.encryption'); + } + + public static function getSmtpUsername() + { + return self::read('smtp.username'); + } + + public static function getSmtpPassword() + { + return self::read('smtp.authmode'); + } + + public static function getSmtpAuthMode() + { + return self::read('smtp.host'); + } + + public static function getSmtpTimeout() + { + return self::read('smtp.timeout', 30); + } + + public static function getSmtpSourceIp() + { + return self::read('smtp.sourceip'); + } + + public static function enableSmtp() + { + self::write('smtp.enabled', 1, 1, 1); + } + + public static function disableSmtp() + { + self::write('smtp.enabled', 0, 1, 1); + } + + public static function setSmtpHost($value) + { + return self::write('smtp.host', $value, 1, 1); + } + + public static function setSmtpPort($value) + { + return self::write('smtp.port', $value, 1, 1); + } + + public static function setSmtpEncryption($value) + { + return self::write('smtp.encryption', $value, 1, 1); + } + + public static function setSmtpUsername($value) + { + return self::write('smtp.username', $value, 1, 1); + } + + public static function setSmtpPassword($value) + { + return self::write('smtp.password', $value, 1, 1); + } + + public static function setSmtpAuthMode($value) + { + return self::write('smtp.authmode', $value, 1, 1); + } + + public static function setSmtpTimeout($value) + { + return self::write('smtp.timeout', $value, 1, 1); + } + + public static function setSmtpSourceIp($value) + { + return self::write('smtp.sourceip', $value, 1, 1); + } + /* end smtp config */ } // ConfigQuery diff --git a/templates/admin/default/configuration.html b/templates/admin/default/configuration.html index 4c6acd1db..a17042b4d 100644 --- a/templates/admin/default/configuration.html +++ b/templates/admin/default/configuration.html @@ -151,14 +151,14 @@ {/loop} -{* {loop type="auth" name="pcc6" role="ADMIN" resource="admin.configuration.mailing-system" access="VIEW"} + {loop type="auth" name="pcc6" role="ADMIN" resource="admin.configuration.mailing-system" access="VIEW"} {intl l='Mailing system'} - + {/loop} - {loop type="auth" name="pcc7" role="ADMIN" resource="admin.configuration.admin-logs" access="VIEW"} +{* {loop type="auth" name="pcc7" role="ADMIN" resource="admin.configuration.admin-logs" access="VIEW"} {intl l='Administration logs'} diff --git a/templates/admin/default/mailing-system.html b/templates/admin/default/mailing-system.html index 984dfd8bd..8ee5e3e3e 100644 --- a/templates/admin/default/mailing-system.html +++ b/templates/admin/default/mailing-system.html @@ -24,68 +24,98 @@
{intl l="Configuration variables"}
- - -
- -
- - - - + {form name="thelia.admin.mailing-system.update"} + + + +
+
+
-
- -
- - - - + {form_hidden_fields form=$form} + + {if $form_error}
{$form_error_message}
{/if} + + {form_field form=$form field='enabled'} +
+ + + + +
+ +
-
+ {/form_field} -
- -
- - - - + {form_field form=$form field='host'} +
+ +
-
+ {/form_field} -
- -
- - - - + {form_field form=$form field='port'} +
+ +
-
+ {/form_field} -
- -
- - - - + {form_field form=$form field='encryption'} +
+ +
-
+ {/form_field} -
- + {form_field form=$form field='username'} +
+ + +
+ {/form_field} -
- + {form_field form=$form field='password'} +
+ + +
+ {/form_field} + + {form_field form=$form field='authmode'} +
+ + +
+ {/form_field} + + {form_field form=$form field='timeout'} +
+ + +
+ {/form_field} + + {form_field form=$form field='sourceip'} +
+ + +
+ {/form_field} + +
+
+
+ {/form} +
@@ -100,4 +130,14 @@ {javascripts file='assets/js/bootstrap-switch/bootstrap-switch.js'} {/javascripts} + + {/block} \ No newline at end of file From 968c372a5f153b0b347653d270af2bbda2971918 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Mon, 28 Oct 2013 12:36:07 +0100 Subject: [PATCH 06/59] add some info in addresses list --- templates/admin/default/customer-edit.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/templates/admin/default/customer-edit.html b/templates/admin/default/customer-edit.html index 71c6b8695..f8c3ebae7 100644 --- a/templates/admin/default/customer-edit.html +++ b/templates/admin/default/customer-edit.html @@ -161,6 +161,10 @@ {$ADDRESS1}
{$ADDRESS2}
{$ADDRESS3}
+ {$ZIPCODE} {$CITY}
+ {loop name="address.country" type="country" id=$COUNTRY} + {$TITLE}
+ {/loop} {if $PHONE} P: {$PHONE}
{/if} From c1e792d5b1f848405941f8f2cf31d56e2a36f189 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Mon, 28 Oct 2013 15:39:59 +0100 Subject: [PATCH 07/59] format customer address list --- templates/admin/default/customer-edit.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/templates/admin/default/customer-edit.html b/templates/admin/default/customer-edit.html index 71c6b8695..eba0139c0 100644 --- a/templates/admin/default/customer-edit.html +++ b/templates/admin/default/customer-edit.html @@ -158,14 +158,14 @@
{loop name="address.title" type="title" id=$TITLE}{$SHORT}{/loop} {$FIRSTNAME} {$LASTNAME}
- {$ADDRESS1}
- {$ADDRESS2}
- {$ADDRESS3}
+ {$ADDRESS1} + {if $ADDRESS2}
{$ADDRESS2}{/if} + {if $ADDRESS3}
{$ADDRESS3}{/if} {if $PHONE} - P: {$PHONE}
+
P:{$PHONE} {/if} {if $CELLPHONE} - P: {$CELLPHONE} +
P:{$CELLPHONE} {/if}
From 1c3aeb969d05149e25c2647704a6b88e9dc7b25e Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Mon, 28 Oct 2013 15:42:34 +0100 Subject: [PATCH 08/59] select correct country in selectbox on customer edit page --- templates/admin/default/customer-edit.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/admin/default/customer-edit.html b/templates/admin/default/customer-edit.html index 0507e18f7..370fe11f3 100644 --- a/templates/admin/default/customer-edit.html +++ b/templates/admin/default/customer-edit.html @@ -124,7 +124,7 @@
From 1e65ad8cf39b63aab717ea265e0b8afad42935dc Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Mon, 28 Oct 2013 16:10:06 +0100 Subject: [PATCH 09/59] add shim and respond in backoffice --- templates/admin/default/admin-layout.tpl | 8 ++++++++ templates/admin/default/assets/js/libs/respond.min.js | 6 ++++++ 2 files changed, 14 insertions(+) create mode 100755 templates/admin/default/assets/js/libs/respond.min.js diff --git a/templates/admin/default/admin-layout.tpl b/templates/admin/default/admin-layout.tpl index 559395159..d2081d829 100644 --- a/templates/admin/default/admin-layout.tpl +++ b/templates/admin/default/admin-layout.tpl @@ -39,6 +39,14 @@ {* Modules css are included here *} {module_include location='head_css'} + + {* HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries *} + diff --git a/templates/admin/default/assets/js/libs/respond.min.js b/templates/admin/default/assets/js/libs/respond.min.js new file mode 100755 index 000000000..e3dc2c0d6 --- /dev/null +++ b/templates/admin/default/assets/js/libs/respond.min.js @@ -0,0 +1,6 @@ +/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */ +/*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */ +window.matchMedia=window.matchMedia||function(a){"use strict";var c,d=a.documentElement,e=d.firstElementChild||d.firstChild,f=a.createElement("body"),g=a.createElement("div");return g.id="mq-test-1",g.style.cssText="position:absolute;top:-100em",f.style.background="none",f.appendChild(g),function(a){return g.innerHTML='­',d.insertBefore(f,e),c=42===g.offsetWidth,d.removeChild(f),{matches:c,media:a}}}(document); + +/*! Respond.js v1.3.0: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs */ +(function(a){"use strict";function x(){u(!0)}var b={};if(a.respond=b,b.update=function(){},b.mediaQueriesSupported=a.matchMedia&&a.matchMedia("only all").matches,!b.mediaQueriesSupported){var q,r,t,c=a.document,d=c.documentElement,e=[],f=[],g=[],h={},i=30,j=c.getElementsByTagName("head")[0]||d,k=c.getElementsByTagName("base")[0],l=j.getElementsByTagName("link"),m=[],n=function(){for(var b=0;l.length>b;b++){var c=l[b],d=c.href,e=c.media,f=c.rel&&"stylesheet"===c.rel.toLowerCase();d&&f&&!h[d]&&(c.styleSheet&&c.styleSheet.rawCssText?(p(c.styleSheet.rawCssText,d,e),h[d]=!0):(!/^([a-zA-Z:]*\/\/)/.test(d)&&!k||d.replace(RegExp.$1,"").split("/")[0]===a.location.host)&&m.push({href:d,media:e}))}o()},o=function(){if(m.length){var b=m.shift();v(b.href,function(c){p(c,b.href,b.media),h[b.href]=!0,a.setTimeout(function(){o()},0)})}},p=function(a,b,c){var d=a.match(/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi),g=d&&d.length||0;b=b.substring(0,b.lastIndexOf("/"));var h=function(a){return a.replace(/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,"$1"+b+"$2$3")},i=!g&&c;b.length&&(b+="/"),i&&(g=1);for(var j=0;g>j;j++){var k,l,m,n;i?(k=c,f.push(h(a))):(k=d[j].match(/@media *([^\{]+)\{([\S\s]+?)$/)&&RegExp.$1,f.push(RegExp.$2&&h(RegExp.$2))),m=k.split(","),n=m.length;for(var o=0;n>o;o++)l=m[o],e.push({media:l.split("(")[0].match(/(only\s+)?([a-zA-Z]+)\s?/)&&RegExp.$2||"all",rules:f.length-1,hasquery:l.indexOf("(")>-1,minw:l.match(/\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:l.match(/\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}u()},s=function(){var a,b=c.createElement("div"),e=c.body,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",e||(e=f=c.createElement("body"),e.style.background="none"),e.appendChild(b),d.insertBefore(e,d.firstChild),a=b.offsetWidth,f?d.removeChild(e):e.removeChild(b),a=t=parseFloat(a)},u=function(b){var h="clientWidth",k=d[h],m="CSS1Compat"===c.compatMode&&k||c.body[h]||k,n={},o=l[l.length-1],p=(new Date).getTime();if(b&&q&&i>p-q)return a.clearTimeout(r),r=a.setTimeout(u,i),void 0;q=p;for(var v in e)if(e.hasOwnProperty(v)){var w=e[v],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?t||s():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?t||s():1)),w.hasquery&&(z&&A||!(z||m>=x)||!(A||y>=m))||(n[w.media]||(n[w.media]=[]),n[w.media].push(f[w.rules]))}for(var C in g)g.hasOwnProperty(C)&&g[C]&&g[C].parentNode===j&&j.removeChild(g[C]);for(var D in n)if(n.hasOwnProperty(D)){var E=c.createElement("style"),F=n[D].join("\n");E.type="text/css",E.media=D,j.insertBefore(E,o.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(c.createTextNode(F)),g.push(E)}},v=function(a,b){var c=w();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))},w=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}();n(),b.update=n,a.addEventListener?a.addEventListener("resize",x,!1):a.attachEvent&&a.attachEvent("onresize",x)}})(this); From 7a2469cdc868fcbb1e966adb2a018322dcda85ea Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Mon, 28 Oct 2013 16:55:07 +0100 Subject: [PATCH 10/59] allow to create a customer in bakcoffice --- .../Thelia/Config/Resources/routing/admin.xml | 4 ++ .../Controller/Admin/CustomerController.php | 54 ++++++++++++++++++- core/lib/Thelia/Model/Customer.php | 1 + core/lib/Thelia/Tools/Password.php | 54 +++++++++++++++++++ templates/admin/default/customers.html | 12 +++++ 5 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 core/lib/Thelia/Tools/Password.php diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index 259c0f54a..dc5a2c522 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -114,6 +114,10 @@ Thelia\Controller\Admin\CustomerController::deleteAction + + Thelia\Controller\Admin\CustomerController::createAction + + diff --git a/core/lib/Thelia/Controller/Admin/CustomerController.php b/core/lib/Thelia/Controller/Admin/CustomerController.php index df75333c8..814008b7a 100644 --- a/core/lib/Thelia/Controller/Admin/CustomerController.php +++ b/core/lib/Thelia/Controller/Admin/CustomerController.php @@ -29,10 +29,12 @@ use Thelia\Core\Event\Customer\CustomerCreateOrUpdateEvent; use Thelia\Core\Event\Customer\CustomerEvent; use Thelia\Core\Event\TheliaEvents; use Thelia\Core\Security\AccessManager; +use Thelia\Form\CustomerCreateForm; use Thelia\Form\CustomerUpdateForm; use Thelia\Form\Exception\FormValidationException; use Thelia\Model\CustomerQuery; use Thelia\Core\Translation\Translator; +use Thelia\Tools\Password; /** * Class CustomerController @@ -102,7 +104,7 @@ class CustomerController extends BaseAdminController } if ($message !== false) { - \Thelia\Log\Tlog::getInstance()->error(sprintf("Error during customer login process : %s.", $message)); + \Thelia\Log\Tlog::getInstance()->error(sprintf("Error during customer update process : %s.", $message)); $customerUpdateForm->setErrorMessage($message); @@ -117,6 +119,56 @@ class CustomerController extends BaseAdminController )); } + public function createAction() + { + if (null !== $response = $this->checkAuth(AdminResources::CUSTOMER, AccessManager::CREATE)) return $response; + + $message = null; + + $customerCreateForm = new CustomerCreateForm($this->getRequest()); + + try { + + $form = $this->validateForm($customerCreateForm); + + $data = $form->getData(); + $data["password"] = Password::generateRandom(); + + $event = $this->createEventInstance($form->getData()); + + + + $this->dispatch(TheliaEvents::CUSTOMER_CREATEACCOUNT, $event); + + $successUrl = $customerCreateForm->getSuccessUrl(); + + $successUrl = str_replace('_ID_', $event->getCustomer()->getId(), $successUrl); + + $this->redirect($successUrl); + + + }catch (FormValidationException $e) { + $message = sprintf("Please check your input: %s", $e->getMessage()); + } catch (PropelException $e) { + $message = $e->getMessage(); + } catch (\Exception $e) { + $message = sprintf("Sorry, an error occured: %s", $e->getMessage()." ".$e->getFile()); + } + + if ($message !== false) { + \Thelia\Log\Tlog::getInstance()->error(sprintf("Error during customer creation process : %s.", $message)); + + $customerCreateForm->setErrorMessage($message); + + $this->getParserContext() + ->addForm($customerCreateForm) + ->setGeneralError($message) + ; + } + + return $this->render("customers", array("display_customer" => 20)); + } + public function deleteAction() { if (null !== $response = $this->checkAuth(AdminResources::CUSTOMER, AccessManager::DELETE)) return $response; diff --git a/core/lib/Thelia/Model/Customer.php b/core/lib/Thelia/Model/Customer.php index 230023410..ffdc316de 100755 --- a/core/lib/Thelia/Model/Customer.php +++ b/core/lib/Thelia/Model/Customer.php @@ -79,6 +79,7 @@ class Customer extends BaseCustomer implements UserInterface $address = new Address(); $address + ->setLabel("default") ->setCompany($company) ->setTitleId($titleId) ->setFirstname($firstname) diff --git a/core/lib/Thelia/Tools/Password.php b/core/lib/Thelia/Tools/Password.php new file mode 100644 index 000000000..dbb4cf8cb --- /dev/null +++ b/core/lib/Thelia/Tools/Password.php @@ -0,0 +1,54 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Tools; + + +/** + * Class Password + * @package Thelia\Tools + * @author Manuel Raynaud + */ +class Password +{ + + private static function randgen($letter, $length) { + + return substr(str_shuffle($letter), 0, $length); + } + + /** + * generate a Random password with defined length + * + * @param int $length + * @return mixed + */ + public static function generateRandom($length = 8){ + + $letter = "abcdefghijklmnopqrstuvwxyz"; + $letter .= "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + $letter .= "0123456789"; + + return self::randgen($letter, $length); + } +} \ No newline at end of file diff --git a/templates/admin/default/customers.html b/templates/admin/default/customers.html index 81a60fdf3..6ae0caa0c 100644 --- a/templates/admin/default/customers.html +++ b/templates/admin/default/customers.html @@ -166,6 +166,18 @@ {/form_field} + {form_field form=$form field="password"} + + {/form_field} + + {form_field form=$form field="password_confirm"} + + {/form_field} + + {form_field form=$form field="agreed"} + + {/form_field} + {form_field form=$form field='company'}
From 082f9aff8d419babc5ce95b2199dd99051ecfb1f Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Tue, 29 Oct 2013 12:22:34 +0100 Subject: [PATCH 11/59] admin logs --- core/lib/Thelia/Action/BaseAction.php | 18 +- core/lib/Thelia/Action/Document.php | 52 +- core/lib/Thelia/Action/Image.php | 52 +- .../Thelia/Config/Resources/routing/admin.xml | 8 + .../Admin/AbstractCrudController.php | 7 +- .../Controller/Admin/AddressController.php | 4 +- .../Controller/Admin/AdminLogsController.php | 39 + .../Controller/Admin/AreaController.php | 4 +- .../Controller/Admin/BaseAdminController.php | 10 +- .../Controller/Admin/CouponController.php | 2 + .../Controller/Admin/CustomerController.php | 2 +- .../Controller/Admin/FileController.php | 106 +- .../Controller/Admin/LangController.php | 6 +- .../Controller/Admin/ProductController.php | 2 +- .../Controller/Admin/ProfileController.php | 4 +- .../Controller/Admin/SessionController.php | 10 +- .../Controller/Admin/TaxRuleController.php | 2 +- core/lib/Thelia/Model/AdminLog.php | 24 +- core/lib/Thelia/Model/Base/AdminLog.php | 154 +- core/lib/Thelia/Model/Base/AdminLogQuery.php | 68 +- .../lib/Thelia/Model/Map/AdminLogTableMap.php | 46 +- core/lib/Thelia/Tools/FileManager.php | 28 - install/thelia.sql | 4 +- local/config/schema.xml | 2520 +++++++++-------- templates/admin/default/admin-logs.html | 143 + templates/admin/default/configuration.html | 10 +- templates/admin/default/mailing-system.html | 4 +- 27 files changed, 1838 insertions(+), 1491 deletions(-) create mode 100644 core/lib/Thelia/Controller/Admin/AdminLogsController.php create mode 100755 templates/admin/default/admin-logs.html diff --git a/core/lib/Thelia/Action/BaseAction.php b/core/lib/Thelia/Action/BaseAction.php index 33deddf2b..e1edab07d 100755 --- a/core/lib/Thelia/Action/BaseAction.php +++ b/core/lib/Thelia/Action/BaseAction.php @@ -52,8 +52,10 @@ class BaseAction /** * Changes object position, selecting absolute ou relative change. * - * @param $query the query to retrieve the object to move + * @param ModelCriteria $query * @param UpdatePositionEvent $event + * + * @return mixed */ protected function genericUpdatePosition(ModelCriteria $query, UpdatePositionEvent $event) { @@ -71,18 +73,4 @@ class BaseAction return $object->movePositionDown(); } } - - /** - * Helper to append a message to the admin log. - * - * @param string $message - */ - public function adminLogAppend($message) - { - AdminLog::append( - $message, - $this->container->get('request'), - $this->container->get('thelia.securityContext')->getAdminUser() - ); - } } diff --git a/core/lib/Thelia/Action/Document.php b/core/lib/Thelia/Action/Document.php index f048c208e..e38604733 100644 --- a/core/lib/Thelia/Action/Document.php +++ b/core/lib/Thelia/Action/Document.php @@ -143,18 +143,6 @@ class Document extends BaseCachedFile implements EventSubscriberInterface */ public function saveDocument(DocumentCreateOrUpdateEvent $event) { - $this->adminLogAppend( - $this->container->get('thelia.translator')->trans( - 'Saving documents for %parentName% parent id %parentId% (%parentType%)', - array( - '%parentName%' => $event->getParentName(), - '%parentId%' => $event->getParentId(), - '%parentType%' => $event->getDocumentType() - ), - 'document' - ) - ); - $fileManager = new FileManager($this->container); $model = $event->getModelDocument(); @@ -187,18 +175,6 @@ class Document extends BaseCachedFile implements EventSubscriberInterface */ public function updateDocument(DocumentCreateOrUpdateEvent $event) { - $this->adminLogAppend( - $this->container->get('thelia.translator')->trans( - 'Updating documents for %parentName% parent id %parentId% (%parentType%)', - array( - '%parentName%' => $event->getParentName(), - '%parentId%' => $event->getParentId(), - '%parentType%' => $event->getDocumentType() - ), - 'image' - ) - ); - if (null !== $event->getUploadedFile()) { $event->getModelDocument()->setTitle($event->getUploadedFile()->getClientOriginalName()); } @@ -231,33 +207,7 @@ class Document extends BaseCachedFile implements EventSubscriberInterface { $fileManager = new FileManager($this->container); - try { - $fileManager->deleteFile($event->getDocumentToDelete(), $event->getDocumentType(), FileManager::FILE_TYPE_DOCUMENTS); - - $this->adminLogAppend( - $this->container->get('thelia.translator')->trans( - 'Deleting document for %id% with parent id %parentId%', - array( - '%id%' => $event->getDocumentToDelete()->getId(), - '%parentId%' => $event->getDocumentToDelete()->getParentId(), - ), - 'document' - ) - ); - } catch (\Exception $e) { - $this->adminLogAppend( - $this->container->get('thelia.translator')->trans( - 'Fail to delete document for %id% with parent id %parentId% (Exception : %e%)', - array( - '%id%' => $event->getDocumentToDelete()->getId(), - '%parentId%' => $event->getDocumentToDelete()->getParentId(), - '%e%' => $e->getMessage() - ), - 'document' - ) - ); - throw $e; - } + $fileManager->deleteFile($event->getDocumentToDelete(), $event->getDocumentType(), FileManager::FILE_TYPE_DOCUMENTS); } public static function getSubscribedEvents() diff --git a/core/lib/Thelia/Action/Image.php b/core/lib/Thelia/Action/Image.php index 97d4bd095..ed7010a09 100755 --- a/core/lib/Thelia/Action/Image.php +++ b/core/lib/Thelia/Action/Image.php @@ -254,18 +254,6 @@ class Image extends BaseCachedFile implements EventSubscriberInterface */ public function saveImage(ImageCreateOrUpdateEvent $event) { - $this->adminLogAppend( - $this->container->get('thelia.translator')->trans( - 'Saving images for %parentName% parent id %parentId% (%parentType%)', - array( - '%parentName%' => $event->getParentName(), - '%parentId%' => $event->getParentId(), - '%parentType%' => $event->getImageType() - ), - 'image' - ) - ); - $fileManager = new FileManager($this->container); $model = $event->getModelImage(); @@ -297,18 +285,6 @@ class Image extends BaseCachedFile implements EventSubscriberInterface */ public function updateImage(ImageCreateOrUpdateEvent $event) { - $this->adminLogAppend( - $this->container->get('thelia.translator')->trans( - 'Updating images for %parentName% parent id %parentId% (%parentType%)', - array( - '%parentName%' => $event->getParentName(), - '%parentId%' => $event->getParentId(), - '%parentType%' => $event->getImageType() - ), - 'image' - ) - ); - $fileManager = new FileManager($this->container); // Copy and save file if ($event->getUploadedFile()) { @@ -337,33 +313,7 @@ class Image extends BaseCachedFile implements EventSubscriberInterface { $fileManager = new FileManager($this->container); - try { - $fileManager->deleteFile($event->getImageToDelete(), $event->getImageType(), FileManager::FILE_TYPE_IMAGES); - - $this->adminLogAppend( - $this->container->get('thelia.translator')->trans( - 'Deleting image for %id% with parent id %parentId%', - array( - '%id%' => $event->getImageToDelete()->getId(), - '%parentId%' => $event->getImageToDelete()->getParentId(), - ), - 'image' - ) - ); - } catch (\Exception $e) { - $this->adminLogAppend( - $this->container->get('thelia.translator')->trans( - 'Fail to delete image for %id% with parent id %parentId% (Exception : %e%)', - array( - '%id%' => $event->getImageToDelete()->getId(), - '%parentId%' => $event->getImageToDelete()->getParentId(), - '%e%' => $e->getMessage() - ), - 'image' - ) - ); - throw $e; - } + $fileManager->deleteFile($event->getImageToDelete(), $event->getImageType(), FileManager::FILE_TYPE_IMAGES); } /** diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index 259c0f54a..d7df6e5fa 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -824,6 +824,14 @@ + + + + Thelia\Controller\Admin\AdminLogsController::defaultAction + + + + diff --git a/core/lib/Thelia/Controller/Admin/AbstractCrudController.php b/core/lib/Thelia/Controller/Admin/AbstractCrudController.php index e38e08a7a..46760eba9 100644 --- a/core/lib/Thelia/Controller/Admin/AbstractCrudController.php +++ b/core/lib/Thelia/Controller/Admin/AbstractCrudController.php @@ -303,7 +303,7 @@ abstract class AbstractCrudController extends BaseAdminController if (null !== $createdObject = $this->getObjectFromEvent($createEvent)) { // Log object creation - $this->adminLogAppend(sprintf("%s %s (ID %s) created", ucfirst($this->objectName), $this->getObjectLabel($createdObject), $this->getObjectId($createdObject))); + $this->adminLogAppend($this->resourceCode, AccessManager::CREATE, sprintf("%s %s (ID %s) created", ucfirst($this->objectName), $this->getObjectLabel($createdObject), $this->getObjectId($createdObject))); } $response = $this->performAdditionalCreateAction($createEvent); @@ -391,7 +391,7 @@ abstract class AbstractCrudController extends BaseAdminController // Log object modification if (null !== $changedObject = $this->getObjectFromEvent($changeEvent)) { - $this->adminLogAppend(sprintf("%s %s (ID %s) modified", ucfirst($this->objectName), $this->getObjectLabel($changedObject), $this->getObjectId($changedObject))); + $this->adminLogAppend($this->resourceCode, AccessManager::UPDATE, sprintf("%s %s (ID %s) modified", ucfirst($this->objectName), $this->getObjectLabel($changedObject), $this->getObjectId($changedObject))); } $response = $this->performAdditionalUpdateAction($changeEvent); @@ -530,7 +530,8 @@ abstract class AbstractCrudController extends BaseAdminController if (null !== $deletedObject = $this->getObjectFromEvent($deleteEvent)) { $this->adminLogAppend( - sprintf("%s %s (ID %s) deleted", ucfirst($this->objectName), $this->getObjectLabel($deletedObject), $this->getObjectId($deletedObject))); + $this->resourceCode, AccessManager::DELETE, + sprintf("%s %s (ID %s) deleted", ucfirst($this->objectName), $this->getObjectLabel($deletedObject), $this->getObjectId($deletedObject))); } $response = $this->performAdditionalDeleteAction($deleteEvent); diff --git a/core/lib/Thelia/Controller/Admin/AddressController.php b/core/lib/Thelia/Controller/Admin/AddressController.php index f934b3279..26f97c9b3 100644 --- a/core/lib/Thelia/Controller/Admin/AddressController.php +++ b/core/lib/Thelia/Controller/Admin/AddressController.php @@ -74,9 +74,9 @@ class AddressController extends AbstractCrudController $this->dispatch(TheliaEvents::ADDRESS_DEFAULT, $addressEvent); - $this->adminLogAppend(sprintf("address %d for customer %d removal", $address_id, $address->getCustomerId())); + $this->adminLogAppend($this->resourceCode, AccessManager::UPDATE, sprintf("address %d for customer %d set as default address", $address_id, $address->getCustomerId())); } catch (\Exception $e) { - \Thelia\Log\Tlog::getInstance()->error(sprintf("error during address removal with message %s", $e->getMessage())); + \Thelia\Log\Tlog::getInstance()->error(sprintf("error during address setting as default with message %s", $e->getMessage())); } $this->redirectToRoute('admin.customer.update.view', array(), array('customer_id' => $address->getCustomerId())); diff --git a/core/lib/Thelia/Controller/Admin/AdminLogsController.php b/core/lib/Thelia/Controller/Admin/AdminLogsController.php new file mode 100644 index 000000000..e6e364d15 --- /dev/null +++ b/core/lib/Thelia/Controller/Admin/AdminLogsController.php @@ -0,0 +1,39 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Controller\Admin; + +use Thelia\Core\Security\AccessManager; + +class AdminLogsController extends BaseAdminController +{ + const RESOURCE_CODE = "admin.admin-logs"; + + public function defaultAction() + { + if (null !== $response = $this->checkAuth(self::RESOURCE_CODE, AccessManager::VIEW)) return $response; + + // Render the edition template. + return $this->render('admin-logs'); + } +} diff --git a/core/lib/Thelia/Controller/Admin/AreaController.php b/core/lib/Thelia/Controller/Admin/AreaController.php index 4126ef741..79c549201 100644 --- a/core/lib/Thelia/Controller/Admin/AreaController.php +++ b/core/lib/Thelia/Controller/Admin/AreaController.php @@ -249,7 +249,7 @@ class AreaController extends AbstractCrudController // Log object modification if (null !== $changedObject = $this->getObjectFromEvent($event)) { - $this->adminLogAppend(sprintf("%s %s (ID %s) modified, new country added", ucfirst($this->objectName), $this->getObjectLabel($changedObject), $this->getObjectId($changedObject))); + $this->adminLogAppend($this->resourceCode, AccessManager::UPDATE, sprintf("%s %s (ID %s) modified, new country added", ucfirst($this->objectName), $this->getObjectLabel($changedObject), $this->getObjectId($changedObject))); } // Redirect to the success URL @@ -303,7 +303,7 @@ class AreaController extends AbstractCrudController // Log object modification if (null !== $changedObject = $this->getObjectFromEvent($event)) { - $this->adminLogAppend(sprintf("%s %s (ID %s) modified, country remove", ucfirst($this->objectName), $this->getObjectLabel($changedObject), $this->getObjectId($changedObject))); + $this->adminLogAppend($this->resourceCode, AccessManager::UPDATE, sprintf("%s %s (ID %s) modified, country remove", ucfirst($this->objectName), $this->getObjectLabel($changedObject), $this->getObjectId($changedObject))); } // Redirect to the success URL diff --git a/core/lib/Thelia/Controller/Admin/BaseAdminController.php b/core/lib/Thelia/Controller/Admin/BaseAdminController.php index e4d9550d3..ad8d46ba0 100755 --- a/core/lib/Thelia/Controller/Admin/BaseAdminController.php +++ b/core/lib/Thelia/Controller/Admin/BaseAdminController.php @@ -51,18 +51,20 @@ class BaseAdminController extends BaseController /** * Helper to append a message to the admin log. * + * @param string $resource + * @param string $action * @param string $message */ - public function adminLogAppend($message) + public function adminLogAppend($resource, $action, $message) { - AdminLog::append($message, $this->getRequest(), $this->getSecurityContext()->getAdminUser()); + AdminLog::append($resource, $action, $message, $this->getRequest(), $this->getSecurityContext()->getAdminUser()); } /** * This method process the rendering of view called from an admin page * * @param unknown $template - * @return Response the reponse which contains the rendered view + * @return Response the response which contains the rendered view */ public function processTemplateAction($template) { @@ -131,7 +133,7 @@ class BaseAdminController extends BaseController } // Log the problem - $this->adminLogAppend("User is not granted for resources %s with accesses %s", implode(", ", $resources), implode(", ", $accesses)); + $this->adminLogAppend(implode(",", $resources), implode(",", $accesses), "User is not granted for resources %s with accesses %s", implode(", ", $resources), implode(", ", $accesses)); // Generate the proper response $response = new Response(); diff --git a/core/lib/Thelia/Controller/Admin/CouponController.php b/core/lib/Thelia/Controller/Admin/CouponController.php index da0ec200a..5cc71ac00 100755 --- a/core/lib/Thelia/Controller/Admin/CouponController.php +++ b/core/lib/Thelia/Controller/Admin/CouponController.php @@ -356,6 +356,7 @@ class CouponController extends BaseAdminController ); $this->adminLogAppend( + AdminResources::COUPON, AccessManager::UPDATE, sprintf( 'Coupon %s (ID %s) conditions updated', $couponEvent->getCouponModel()->getTitle(), @@ -468,6 +469,7 @@ class CouponController extends BaseAdminController ); $this->adminLogAppend( + AdminResources::COUPON, AccessManager::UPDATE, sprintf( 'Coupon %s (ID ) ' . $log, $couponEvent->getTitle(), diff --git a/core/lib/Thelia/Controller/Admin/CustomerController.php b/core/lib/Thelia/Controller/Admin/CustomerController.php index df75333c8..2f946917a 100644 --- a/core/lib/Thelia/Controller/Admin/CustomerController.php +++ b/core/lib/Thelia/Controller/Admin/CustomerController.php @@ -85,7 +85,7 @@ class CustomerController extends BaseAdminController $customerUpdated = $event->getCustomer(); - $this->adminLogAppend(sprintf("Customer with Ref %s (ID %d) modified", $customerUpdated->getRef() , $customerUpdated->getId())); + $this->adminLogAppend(AdminResources::CUSTOMER, AccessManager::UPDATE, sprintf("Customer with Ref %s (ID %d) modified", $customerUpdated->getRef() , $customerUpdated->getId())); if ($this->getRequest()->get("save_mode") == "close") { $this->redirectToRoute("admin.customers"); diff --git a/core/lib/Thelia/Controller/Admin/FileController.php b/core/lib/Thelia/Controller/Admin/FileController.php index 3c2ad0ba9..38b8d74fb 100755 --- a/core/lib/Thelia/Controller/Admin/FileController.php +++ b/core/lib/Thelia/Controller/Admin/FileController.php @@ -130,6 +130,20 @@ class FileController extends BaseAdminController $imageCreateOrUpdateEvent ); + $this->adminLogAppend( + AdminResources::retrieve($parentType), + AccessManager::UPDATE, + $this->container->get('thelia.translator')->trans( + 'Saving images for %parentName% parent id %parentId% (%parentType%)', + array( + '%parentName%' => $event->getParentName(), + '%parentId%' => $event->getParentId(), + '%parentType%' => $event->getImageType() + ), + 'image' + ) + ); + return new ResponseRest(array('status' => true, 'message' => '')); } } @@ -194,6 +208,20 @@ class FileController extends BaseAdminController $documentCreateOrUpdateEvent ); + $this->adminLogAppend( + AdminResources::retrieve($parentType), + AccessManager::UPDATE, + $this->container->get('thelia.translator')->trans( + 'Saving documents for %parentName% parent id %parentId% (%parentType%)', + array( + '%parentName%' => $event->getParentName(), + '%parentId%' => $event->getParentId(), + '%parentType%' => $event->getDocumentType() + ), + 'document' + ) + ); + return new ResponseRest(array('status' => true, 'message' => '')); } } @@ -368,7 +396,7 @@ class FileController extends BaseAdminController $imageUpdated = $event->getModelImage(); - $this->adminLogAppend(sprintf('Image with Ref %s (ID %d) modified', $imageUpdated->getTitle(), $imageUpdated->getId())); + $this->adminLogAppend(AdminResources::retrieve($parentType), AccessManager::UPDATE, sprintf('Image with Ref %s (ID %d) modified', $imageUpdated->getTitle(), $imageUpdated->getId())); if ($this->getRequest()->get('save_mode') == 'close') { $this->redirectToRoute('admin.images'); @@ -445,7 +473,7 @@ class FileController extends BaseAdminController $documentUpdated = $event->getModelDocument(); - $this->adminLogAppend(sprintf('Document with Ref %s (ID %d) modified', $documentUpdated->getTitle(), $documentUpdated->getId())); + $this->adminLogAppend(AdminResources::retrieve($parentType), AccessManager::UPDATE, sprintf('Document with Ref %s (ID %d) modified', $documentUpdated->getTitle(), $documentUpdated->getId())); if ($this->getRequest()->get('save_mode') == 'close') { $this->redirectToRoute('admin.documents'); @@ -509,10 +537,39 @@ class FileController extends BaseAdminController ); // Dispatch Event to the Action - $this->dispatch( - TheliaEvents::IMAGE_DELETE, - $imageDeleteEvent - ); + try { + $this->dispatch( + TheliaEvents::IMAGE_DELETE, + $imageDeleteEvent + ); + + $this->adminLogAppend( + AdminResources::retrieve($parentType), + AccessManager::UPDATE, + $this->container->get('thelia.translator')->trans( + 'Deleting image for %id% with parent id %parentId%', + array( + '%id%' => $event->getDocumentToDelete()->getId(), + '%parentId%' => $event->getDocumentToDelete()->getParentId(), + ), + 'image' + ) + ); + } catch (\Exception $e) { + $this->adminLogAppend( + AdminResources::retrieve($parentType), + AccessManager::UPDATE, + $this->container->get('thelia.translator')->trans( + 'Fail to delete image for %id% with parent id %parentId% (Exception : %e%)', + array( + '%id%' => $event->getDocumentToDelete()->getId(), + '%parentId%' => $event->getDocumentToDelete()->getParentId(), + '%e%' => $e->getMessage() + ), + 'image' + ) + ); + } $message = $this->getTranslator() ->trans( @@ -552,10 +609,39 @@ class FileController extends BaseAdminController ); // Dispatch Event to the Action - $this->dispatch( - TheliaEvents::DOCUMENT_DELETE, - $documentDeleteEvent - ); + try { + $this->dispatch( + TheliaEvents::DOCUMENT_DELETE, + $documentDeleteEvent + ); + + $this->adminLogAppend( + AdminResources::retrieve($parentType), + AccessManager::UPDATE, + $this->container->get('thelia.translator')->trans( + 'Deleting document for %id% with parent id %parentId%', + array( + '%id%' => $event->getDocumentToDelete()->getId(), + '%parentId%' => $event->getDocumentToDelete()->getParentId(), + ), + 'document' + ) + ); + } catch (\Exception $e) { + $this->adminLogAppend( + AdminResources::retrieve($parentType), + AccessManager::UPDATE, + $this->container->get('thelia.translator')->trans( + 'Fail to delete document for %id% with parent id %parentId% (Exception : %e%)', + array( + '%id%' => $event->getDocumentToDelete()->getId(), + '%parentId%' => $event->getDocumentToDelete()->getParentId(), + '%e%' => $e->getMessage() + ), + 'document' + ) + ); + } $message = $this->getTranslator() ->trans( diff --git a/core/lib/Thelia/Controller/Admin/LangController.php b/core/lib/Thelia/Controller/Admin/LangController.php index 8e0ca5d1c..7c9eefad5 100644 --- a/core/lib/Thelia/Controller/Admin/LangController.php +++ b/core/lib/Thelia/Controller/Admin/LangController.php @@ -116,7 +116,7 @@ class LangController extends BaseAdminController } $changedObject = $event->getLang(); - $this->adminLogAppend(sprintf("%s %s (ID %s) modified", 'Lang', $changedObject->getTitle(), $changedObject->getId())); + $this->adminLogAppend(AdminResources::LANGUAGE, AccessManager::UPDATE, sprintf("%s %s (ID %s) modified", 'Lang', $changedObject->getTitle(), $changedObject->getId())); $this->redirectToRoute('/admin/configuration/languages'); } catch (\Exception $e) { $error_msg = $e->getMessage(); @@ -153,7 +153,7 @@ class LangController extends BaseAdminController } $changedObject = $event->getLang(); - $this->adminLogAppend(sprintf("%s %s (ID %s) modified", 'Lang', $changedObject->getTitle(), $changedObject->getId())); + $this->adminLogAppend(AdminResources::LANGUAGE, AccessManager::UPDATE, sprintf("%s %s (ID %s) modified", 'Lang', $changedObject->getTitle(), $changedObject->getId())); } catch (\Exception $e) { \Thelia\Log\Tlog::getInstance()->error(sprintf("Error on changing default languages with message : %s", $e->getMessage())); @@ -189,7 +189,7 @@ class LangController extends BaseAdminController } $createdObject = $createEvent->getLang(); - $this->adminLogAppend(sprintf("%s %s (ID %s) created", 'Lang', $createdObject->getTitle(), $createdObject->getId())); + $this->adminLogAppend(AdminResources::LANGUAGE, AccessManager::CREATE, sprintf("%s %s (ID %s) created", 'Lang', $createdObject->getTitle(), $createdObject->getId())); $this->redirectToRoute('admin.configuration.languages'); diff --git a/core/lib/Thelia/Controller/Admin/ProductController.php b/core/lib/Thelia/Controller/Admin/ProductController.php index 84e16815d..88baf75f7 100644 --- a/core/lib/Thelia/Controller/Admin/ProductController.php +++ b/core/lib/Thelia/Controller/Admin/ProductController.php @@ -931,7 +931,7 @@ class ProductController extends AbstractCrudController // Log object modification if (null !== $changedObject = $event->getProductSaleElement()) { - $this->adminLogAppend(sprintf("Product Sale Element (ID %s) for product reference %s modified", $changedObject->getId(), $event->getProduct()->getRef())); + $this->adminLogAppend($this->resourceCode, AccessManager::UPDATE, sprintf("Product Sale Element (ID %s) for product reference %s modified", $changedObject->getId(), $event->getProduct()->getRef())); } } diff --git a/core/lib/Thelia/Controller/Admin/ProfileController.php b/core/lib/Thelia/Controller/Admin/ProfileController.php index 9db4e9315..909d055b8 100644 --- a/core/lib/Thelia/Controller/Admin/ProfileController.php +++ b/core/lib/Thelia/Controller/Admin/ProfileController.php @@ -330,7 +330,7 @@ class ProfileController extends AbstractCrudController // Log object modification if (null !== $changedObject = $this->getObjectFromEvent($changeEvent)) { - $this->adminLogAppend(sprintf("%s %s (ID %s) modified", ucfirst($this->objectName), $this->getObjectLabel($changedObject), $this->getObjectId($changedObject))); + $this->adminLogAppend($this->resourceCode, AccessManager::UPDATE, sprintf("%s %s (ID %s) modified", ucfirst($this->objectName), $this->getObjectLabel($changedObject), $this->getObjectId($changedObject))); } if ($response == null) { @@ -379,7 +379,7 @@ class ProfileController extends AbstractCrudController // Log object modification if (null !== $changedObject = $this->getObjectFromEvent($changeEvent)) { - $this->adminLogAppend(sprintf("%s %s (ID %s) modified", ucfirst($this->objectName), $this->getObjectLabel($changedObject), $this->getObjectId($changedObject))); + $this->adminLogAppend($this->resourceCode, AccessManager::UPDATE, sprintf("%s %s (ID %s) modified", ucfirst($this->objectName), $this->getObjectLabel($changedObject), $this->getObjectId($changedObject))); } if ($response == null) { diff --git a/core/lib/Thelia/Controller/Admin/SessionController.php b/core/lib/Thelia/Controller/Admin/SessionController.php index 6d8d14416..0f6f1a105 100755 --- a/core/lib/Thelia/Controller/Admin/SessionController.php +++ b/core/lib/Thelia/Controller/Admin/SessionController.php @@ -50,7 +50,7 @@ class SessionController extends BaseAdminController $this->getSecurityContext()->setAdminUser($user); - $this->adminLogAppend("Successful token authentication"); + $this->adminLogAppend("admin", "LOGIN", "Successful token authentication"); // Update the cookie $cookie = $this->createAdminRememberMeCookie($user); @@ -58,7 +58,7 @@ class SessionController extends BaseAdminController // Render the home page return $this->render("home"); } catch (TokenAuthenticationException $ex) { - $this->adminLogAppend("Token based authentication failed."); + $this->adminLogAppend("admin", "LOGIN", "Token based authentication failed."); // Clear the cookie $this->clearRememberMeCookie(); @@ -99,7 +99,7 @@ class SessionController extends BaseAdminController $this->getSecurityContext()->setAdminUser($user); // Log authentication success - AdminLog::append("Authentication successful", $request, $user); + AdminLog::append("admin", "LOGIN", "Authentication successful", $request, $user); /** * FIXME: we have tou find a way to send cookie @@ -122,13 +122,13 @@ class SessionController extends BaseAdminController } catch (AuthenticationException $ex) { // Log authentication failure - AdminLog::append(sprintf("Authentication failure for username '%s'", $authenticator->getUsername()), $request); + AdminLog::append("admin", "LOGIN", sprintf("Authentication failure for username '%s'", $authenticator->getUsername()), $request); $message = $this->getTranslator()->trans("Login failed. Please check your username and password."); } catch (\Exception $ex) { // Log authentication failure - AdminLog::append(sprintf("Undefined error: %s", $ex->getMessage()), $request); + AdminLog::append("admin", "LOGIN", sprintf("Undefined error: %s", $ex->getMessage()), $request); $message = $this->getTranslator()->trans( "Unable to process your request. Please try again (%err).", diff --git a/core/lib/Thelia/Controller/Admin/TaxRuleController.php b/core/lib/Thelia/Controller/Admin/TaxRuleController.php index db3eca4b4..2e6cb2b70 100644 --- a/core/lib/Thelia/Controller/Admin/TaxRuleController.php +++ b/core/lib/Thelia/Controller/Admin/TaxRuleController.php @@ -279,7 +279,7 @@ class TaxRuleController extends AbstractCrudController // Log object modification if (null !== $changedObject = $this->getObjectFromEvent($changeEvent)) { - $this->adminLogAppend(sprintf("%s %s (ID %s) modified", ucfirst($this->objectName), $this->getObjectLabel($changedObject), $this->getObjectId($changedObject))); + $this->adminLogAppend($this->resourceCode, AccessManager::UPDATE, sprintf("%s %s (ID %s) modified", ucfirst($this->objectName), $this->getObjectLabel($changedObject), $this->getObjectId($changedObject))); } if ($response == null) { diff --git a/core/lib/Thelia/Model/AdminLog.php b/core/lib/Thelia/Model/AdminLog.php index e5720fb35..018fa00d3 100755 --- a/core/lib/Thelia/Model/AdminLog.php +++ b/core/lib/Thelia/Model/AdminLog.php @@ -7,16 +7,18 @@ use Thelia\Core\HttpFoundation\Request; use Thelia\Log\Tlog; use Thelia\Model\Base\Admin as BaseAdminUser; -class AdminLog extends BaseAdminLog { - - /** - * A sdimple helper to insert an entry in the admin log +class AdminLog extends BaseAdminLog +{ + /** + * A simple helper to insert an entry in the admin log * - * @param unknown $actionLabel - * @param Request $request - * @param Admin $adminUser - */ - public static function append($actionLabel, Request $request, BaseAdminUser $adminUser = null) { + * @param $resource + * @param $action + * @param $message + * @param Request $request + * @param Base\Admin $adminUser + */ + public static function append($resource, $action, $message, Request $request, BaseAdminUser $adminUser = null) { $log = new AdminLog(); @@ -24,7 +26,9 @@ class AdminLog extends BaseAdminLog { ->setAdminLogin($adminUser !== null ? $adminUser->getLogin() : '') ->setAdminFirstname($adminUser !== null ? $adminUser->getFirstname() : '') ->setAdminLastname($adminUser !== null ? $adminUser->getLastname() : '') - ->setAction($actionLabel) + ->setResource($resource) + ->setAction($action) + ->setMessage($message) ->setRequest($request->__toString()) ; diff --git a/core/lib/Thelia/Model/Base/AdminLog.php b/core/lib/Thelia/Model/Base/AdminLog.php index dfce950eb..abebb7cd9 100644 --- a/core/lib/Thelia/Model/Base/AdminLog.php +++ b/core/lib/Thelia/Model/Base/AdminLog.php @@ -78,12 +78,24 @@ abstract class AdminLog implements ActiveRecordInterface */ protected $admin_lastname; + /** + * The value for the resource field. + * @var string + */ + protected $resource; + /** * The value for the action field. * @var string */ protected $action; + /** + * The value for the message field. + * @var string + */ + protected $message; + /** * The value for the request field. * @var string @@ -412,6 +424,17 @@ abstract class AdminLog implements ActiveRecordInterface return $this->admin_lastname; } + /** + * Get the [resource] column value. + * + * @return string + */ + public function getResource() + { + + return $this->resource; + } + /** * Get the [action] column value. * @@ -423,6 +446,17 @@ abstract class AdminLog implements ActiveRecordInterface return $this->action; } + /** + * Get the [message] column value. + * + * @return string + */ + public function getMessage() + { + + return $this->message; + } + /** * Get the [request] column value. * @@ -558,6 +592,27 @@ abstract class AdminLog implements ActiveRecordInterface return $this; } // setAdminLastname() + /** + * Set the value of [resource] column. + * + * @param string $v new value + * @return \Thelia\Model\AdminLog The current object (for fluent API support) + */ + public function setResource($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->resource !== $v) { + $this->resource = $v; + $this->modifiedColumns[] = AdminLogTableMap::RESOURCE; + } + + + return $this; + } // setResource() + /** * Set the value of [action] column. * @@ -579,6 +634,27 @@ abstract class AdminLog implements ActiveRecordInterface return $this; } // setAction() + /** + * Set the value of [message] column. + * + * @param string $v new value + * @return \Thelia\Model\AdminLog The current object (for fluent API support) + */ + public function setMessage($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->message !== $v) { + $this->message = $v; + $this->modifiedColumns[] = AdminLogTableMap::MESSAGE; + } + + + return $this; + } // setMessage() + /** * Set the value of [request] column. * @@ -691,19 +767,25 @@ abstract class AdminLog implements ActiveRecordInterface $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : AdminLogTableMap::translateFieldName('AdminLastname', TableMap::TYPE_PHPNAME, $indexType)]; $this->admin_lastname = (null !== $col) ? (string) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : AdminLogTableMap::translateFieldName('Action', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : AdminLogTableMap::translateFieldName('Resource', TableMap::TYPE_PHPNAME, $indexType)]; + $this->resource = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : AdminLogTableMap::translateFieldName('Action', TableMap::TYPE_PHPNAME, $indexType)]; $this->action = (null !== $col) ? (string) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : AdminLogTableMap::translateFieldName('Request', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : AdminLogTableMap::translateFieldName('Message', TableMap::TYPE_PHPNAME, $indexType)]; + $this->message = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : AdminLogTableMap::translateFieldName('Request', TableMap::TYPE_PHPNAME, $indexType)]; $this->request = (null !== $col) ? (string) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : AdminLogTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 8 + $startcol : AdminLogTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } $this->created_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : AdminLogTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 9 + $startcol : AdminLogTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } @@ -716,7 +798,7 @@ abstract class AdminLog implements ActiveRecordInterface $this->ensureConsistency(); } - return $startcol + 8; // 8 = AdminLogTableMap::NUM_HYDRATE_COLUMNS. + return $startcol + 10; // 10 = AdminLogTableMap::NUM_HYDRATE_COLUMNS. } catch (Exception $e) { throw new PropelException("Error populating \Thelia\Model\AdminLog object", 0, $e); @@ -948,9 +1030,15 @@ abstract class AdminLog implements ActiveRecordInterface if ($this->isColumnModified(AdminLogTableMap::ADMIN_LASTNAME)) { $modifiedColumns[':p' . $index++] = 'ADMIN_LASTNAME'; } + if ($this->isColumnModified(AdminLogTableMap::RESOURCE)) { + $modifiedColumns[':p' . $index++] = 'RESOURCE'; + } if ($this->isColumnModified(AdminLogTableMap::ACTION)) { $modifiedColumns[':p' . $index++] = 'ACTION'; } + if ($this->isColumnModified(AdminLogTableMap::MESSAGE)) { + $modifiedColumns[':p' . $index++] = 'MESSAGE'; + } if ($this->isColumnModified(AdminLogTableMap::REQUEST)) { $modifiedColumns[':p' . $index++] = 'REQUEST'; } @@ -983,9 +1071,15 @@ abstract class AdminLog implements ActiveRecordInterface case 'ADMIN_LASTNAME': $stmt->bindValue($identifier, $this->admin_lastname, PDO::PARAM_STR); break; + case 'RESOURCE': + $stmt->bindValue($identifier, $this->resource, PDO::PARAM_STR); + break; case 'ACTION': $stmt->bindValue($identifier, $this->action, PDO::PARAM_STR); break; + case 'MESSAGE': + $stmt->bindValue($identifier, $this->message, PDO::PARAM_STR); + break; case 'REQUEST': $stmt->bindValue($identifier, $this->request, PDO::PARAM_STR); break; @@ -1070,15 +1164,21 @@ abstract class AdminLog implements ActiveRecordInterface return $this->getAdminLastname(); break; case 4: - return $this->getAction(); + return $this->getResource(); break; case 5: - return $this->getRequest(); + return $this->getAction(); break; case 6: - return $this->getCreatedAt(); + return $this->getMessage(); break; case 7: + return $this->getRequest(); + break; + case 8: + return $this->getCreatedAt(); + break; + case 9: return $this->getUpdatedAt(); break; default: @@ -1113,10 +1213,12 @@ abstract class AdminLog implements ActiveRecordInterface $keys[1] => $this->getAdminLogin(), $keys[2] => $this->getAdminFirstname(), $keys[3] => $this->getAdminLastname(), - $keys[4] => $this->getAction(), - $keys[5] => $this->getRequest(), - $keys[6] => $this->getCreatedAt(), - $keys[7] => $this->getUpdatedAt(), + $keys[4] => $this->getResource(), + $keys[5] => $this->getAction(), + $keys[6] => $this->getMessage(), + $keys[7] => $this->getRequest(), + $keys[8] => $this->getCreatedAt(), + $keys[9] => $this->getUpdatedAt(), ); $virtualColumns = $this->virtualColumns; foreach ($virtualColumns as $key => $virtualColumn) { @@ -1169,15 +1271,21 @@ abstract class AdminLog implements ActiveRecordInterface $this->setAdminLastname($value); break; case 4: - $this->setAction($value); + $this->setResource($value); break; case 5: - $this->setRequest($value); + $this->setAction($value); break; case 6: - $this->setCreatedAt($value); + $this->setMessage($value); break; case 7: + $this->setRequest($value); + break; + case 8: + $this->setCreatedAt($value); + break; + case 9: $this->setUpdatedAt($value); break; } // switch() @@ -1208,10 +1316,12 @@ abstract class AdminLog implements ActiveRecordInterface if (array_key_exists($keys[1], $arr)) $this->setAdminLogin($arr[$keys[1]]); if (array_key_exists($keys[2], $arr)) $this->setAdminFirstname($arr[$keys[2]]); if (array_key_exists($keys[3], $arr)) $this->setAdminLastname($arr[$keys[3]]); - if (array_key_exists($keys[4], $arr)) $this->setAction($arr[$keys[4]]); - if (array_key_exists($keys[5], $arr)) $this->setRequest($arr[$keys[5]]); - if (array_key_exists($keys[6], $arr)) $this->setCreatedAt($arr[$keys[6]]); - if (array_key_exists($keys[7], $arr)) $this->setUpdatedAt($arr[$keys[7]]); + if (array_key_exists($keys[4], $arr)) $this->setResource($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setAction($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setMessage($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setRequest($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setCreatedAt($arr[$keys[8]]); + if (array_key_exists($keys[9], $arr)) $this->setUpdatedAt($arr[$keys[9]]); } /** @@ -1227,7 +1337,9 @@ abstract class AdminLog implements ActiveRecordInterface if ($this->isColumnModified(AdminLogTableMap::ADMIN_LOGIN)) $criteria->add(AdminLogTableMap::ADMIN_LOGIN, $this->admin_login); if ($this->isColumnModified(AdminLogTableMap::ADMIN_FIRSTNAME)) $criteria->add(AdminLogTableMap::ADMIN_FIRSTNAME, $this->admin_firstname); if ($this->isColumnModified(AdminLogTableMap::ADMIN_LASTNAME)) $criteria->add(AdminLogTableMap::ADMIN_LASTNAME, $this->admin_lastname); + if ($this->isColumnModified(AdminLogTableMap::RESOURCE)) $criteria->add(AdminLogTableMap::RESOURCE, $this->resource); if ($this->isColumnModified(AdminLogTableMap::ACTION)) $criteria->add(AdminLogTableMap::ACTION, $this->action); + if ($this->isColumnModified(AdminLogTableMap::MESSAGE)) $criteria->add(AdminLogTableMap::MESSAGE, $this->message); if ($this->isColumnModified(AdminLogTableMap::REQUEST)) $criteria->add(AdminLogTableMap::REQUEST, $this->request); if ($this->isColumnModified(AdminLogTableMap::CREATED_AT)) $criteria->add(AdminLogTableMap::CREATED_AT, $this->created_at); if ($this->isColumnModified(AdminLogTableMap::UPDATED_AT)) $criteria->add(AdminLogTableMap::UPDATED_AT, $this->updated_at); @@ -1297,7 +1409,9 @@ abstract class AdminLog implements ActiveRecordInterface $copyObj->setAdminLogin($this->getAdminLogin()); $copyObj->setAdminFirstname($this->getAdminFirstname()); $copyObj->setAdminLastname($this->getAdminLastname()); + $copyObj->setResource($this->getResource()); $copyObj->setAction($this->getAction()); + $copyObj->setMessage($this->getMessage()); $copyObj->setRequest($this->getRequest()); $copyObj->setCreatedAt($this->getCreatedAt()); $copyObj->setUpdatedAt($this->getUpdatedAt()); @@ -1338,7 +1452,9 @@ abstract class AdminLog implements ActiveRecordInterface $this->admin_login = null; $this->admin_firstname = null; $this->admin_lastname = null; + $this->resource = null; $this->action = null; + $this->message = null; $this->request = null; $this->created_at = null; $this->updated_at = null; diff --git a/core/lib/Thelia/Model/Base/AdminLogQuery.php b/core/lib/Thelia/Model/Base/AdminLogQuery.php index 53a5849b5..061b9013d 100644 --- a/core/lib/Thelia/Model/Base/AdminLogQuery.php +++ b/core/lib/Thelia/Model/Base/AdminLogQuery.php @@ -22,7 +22,9 @@ use Thelia\Model\Map\AdminLogTableMap; * @method ChildAdminLogQuery orderByAdminLogin($order = Criteria::ASC) Order by the admin_login column * @method ChildAdminLogQuery orderByAdminFirstname($order = Criteria::ASC) Order by the admin_firstname column * @method ChildAdminLogQuery orderByAdminLastname($order = Criteria::ASC) Order by the admin_lastname column + * @method ChildAdminLogQuery orderByResource($order = Criteria::ASC) Order by the resource column * @method ChildAdminLogQuery orderByAction($order = Criteria::ASC) Order by the action column + * @method ChildAdminLogQuery orderByMessage($order = Criteria::ASC) Order by the message column * @method ChildAdminLogQuery orderByRequest($order = Criteria::ASC) Order by the request column * @method ChildAdminLogQuery orderByCreatedAt($order = Criteria::ASC) Order by the created_at column * @method ChildAdminLogQuery orderByUpdatedAt($order = Criteria::ASC) Order by the updated_at column @@ -31,7 +33,9 @@ use Thelia\Model\Map\AdminLogTableMap; * @method ChildAdminLogQuery groupByAdminLogin() Group by the admin_login column * @method ChildAdminLogQuery groupByAdminFirstname() Group by the admin_firstname column * @method ChildAdminLogQuery groupByAdminLastname() Group by the admin_lastname column + * @method ChildAdminLogQuery groupByResource() Group by the resource column * @method ChildAdminLogQuery groupByAction() Group by the action column + * @method ChildAdminLogQuery groupByMessage() Group by the message column * @method ChildAdminLogQuery groupByRequest() Group by the request column * @method ChildAdminLogQuery groupByCreatedAt() Group by the created_at column * @method ChildAdminLogQuery groupByUpdatedAt() Group by the updated_at column @@ -47,7 +51,9 @@ use Thelia\Model\Map\AdminLogTableMap; * @method ChildAdminLog findOneByAdminLogin(string $admin_login) Return the first ChildAdminLog filtered by the admin_login column * @method ChildAdminLog findOneByAdminFirstname(string $admin_firstname) Return the first ChildAdminLog filtered by the admin_firstname column * @method ChildAdminLog findOneByAdminLastname(string $admin_lastname) Return the first ChildAdminLog filtered by the admin_lastname column + * @method ChildAdminLog findOneByResource(string $resource) Return the first ChildAdminLog filtered by the resource column * @method ChildAdminLog findOneByAction(string $action) Return the first ChildAdminLog filtered by the action column + * @method ChildAdminLog findOneByMessage(string $message) Return the first ChildAdminLog filtered by the message column * @method ChildAdminLog findOneByRequest(string $request) Return the first ChildAdminLog filtered by the request column * @method ChildAdminLog findOneByCreatedAt(string $created_at) Return the first ChildAdminLog filtered by the created_at column * @method ChildAdminLog findOneByUpdatedAt(string $updated_at) Return the first ChildAdminLog filtered by the updated_at column @@ -56,7 +62,9 @@ use Thelia\Model\Map\AdminLogTableMap; * @method array findByAdminLogin(string $admin_login) Return ChildAdminLog objects filtered by the admin_login column * @method array findByAdminFirstname(string $admin_firstname) Return ChildAdminLog objects filtered by the admin_firstname column * @method array findByAdminLastname(string $admin_lastname) Return ChildAdminLog objects filtered by the admin_lastname column + * @method array findByResource(string $resource) Return ChildAdminLog objects filtered by the resource column * @method array findByAction(string $action) Return ChildAdminLog objects filtered by the action column + * @method array findByMessage(string $message) Return ChildAdminLog objects filtered by the message column * @method array findByRequest(string $request) Return ChildAdminLog objects filtered by the request column * @method array findByCreatedAt(string $created_at) Return ChildAdminLog objects filtered by the created_at column * @method array findByUpdatedAt(string $updated_at) Return ChildAdminLog objects filtered by the updated_at column @@ -148,7 +156,7 @@ abstract class AdminLogQuery extends ModelCriteria */ protected function findPkSimple($key, $con) { - $sql = 'SELECT ID, ADMIN_LOGIN, ADMIN_FIRSTNAME, ADMIN_LASTNAME, ACTION, REQUEST, CREATED_AT, UPDATED_AT FROM admin_log WHERE ID = :p0'; + $sql = 'SELECT ID, ADMIN_LOGIN, ADMIN_FIRSTNAME, ADMIN_LASTNAME, RESOURCE, ACTION, MESSAGE, REQUEST, CREATED_AT, UPDATED_AT FROM admin_log WHERE ID = :p0'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key, PDO::PARAM_INT); @@ -365,6 +373,35 @@ abstract class AdminLogQuery extends ModelCriteria return $this->addUsingAlias(AdminLogTableMap::ADMIN_LASTNAME, $adminLastname, $comparison); } + /** + * Filter the query on the resource column + * + * Example usage: + * + * $query->filterByResource('fooValue'); // WHERE resource = 'fooValue' + * $query->filterByResource('%fooValue%'); // WHERE resource LIKE '%fooValue%' + * + * + * @param string $resource The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildAdminLogQuery The current query, for fluid interface + */ + public function filterByResource($resource = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($resource)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $resource)) { + $resource = str_replace('*', '%', $resource); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(AdminLogTableMap::RESOURCE, $resource, $comparison); + } + /** * Filter the query on the action column * @@ -394,6 +431,35 @@ abstract class AdminLogQuery extends ModelCriteria return $this->addUsingAlias(AdminLogTableMap::ACTION, $action, $comparison); } + /** + * Filter the query on the message column + * + * Example usage: + * + * $query->filterByMessage('fooValue'); // WHERE message = 'fooValue' + * $query->filterByMessage('%fooValue%'); // WHERE message LIKE '%fooValue%' + * + * + * @param string $message The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildAdminLogQuery The current query, for fluid interface + */ + public function filterByMessage($message = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($message)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $message)) { + $message = str_replace('*', '%', $message); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(AdminLogTableMap::MESSAGE, $message, $comparison); + } + /** * Filter the query on the request column * diff --git a/core/lib/Thelia/Model/Map/AdminLogTableMap.php b/core/lib/Thelia/Model/Map/AdminLogTableMap.php index 633d6b4e9..fabd848dc 100644 --- a/core/lib/Thelia/Model/Map/AdminLogTableMap.php +++ b/core/lib/Thelia/Model/Map/AdminLogTableMap.php @@ -57,7 +57,7 @@ class AdminLogTableMap extends TableMap /** * The total number of columns */ - const NUM_COLUMNS = 8; + const NUM_COLUMNS = 10; /** * The number of lazy-loaded columns @@ -67,7 +67,7 @@ class AdminLogTableMap extends TableMap /** * The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */ - const NUM_HYDRATE_COLUMNS = 8; + const NUM_HYDRATE_COLUMNS = 10; /** * the column name for the ID field @@ -89,11 +89,21 @@ class AdminLogTableMap extends TableMap */ const ADMIN_LASTNAME = 'admin_log.ADMIN_LASTNAME'; + /** + * the column name for the RESOURCE field + */ + const RESOURCE = 'admin_log.RESOURCE'; + /** * the column name for the ACTION field */ const ACTION = 'admin_log.ACTION'; + /** + * the column name for the MESSAGE field + */ + const MESSAGE = 'admin_log.MESSAGE'; + /** * the column name for the REQUEST field */ @@ -121,12 +131,12 @@ class AdminLogTableMap extends TableMap * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ protected static $fieldNames = array ( - self::TYPE_PHPNAME => array('Id', 'AdminLogin', 'AdminFirstname', 'AdminLastname', 'Action', 'Request', 'CreatedAt', 'UpdatedAt', ), - self::TYPE_STUDLYPHPNAME => array('id', 'adminLogin', 'adminFirstname', 'adminLastname', 'action', 'request', 'createdAt', 'updatedAt', ), - self::TYPE_COLNAME => array(AdminLogTableMap::ID, AdminLogTableMap::ADMIN_LOGIN, AdminLogTableMap::ADMIN_FIRSTNAME, AdminLogTableMap::ADMIN_LASTNAME, AdminLogTableMap::ACTION, AdminLogTableMap::REQUEST, AdminLogTableMap::CREATED_AT, AdminLogTableMap::UPDATED_AT, ), - self::TYPE_RAW_COLNAME => array('ID', 'ADMIN_LOGIN', 'ADMIN_FIRSTNAME', 'ADMIN_LASTNAME', 'ACTION', 'REQUEST', 'CREATED_AT', 'UPDATED_AT', ), - self::TYPE_FIELDNAME => array('id', 'admin_login', 'admin_firstname', 'admin_lastname', 'action', 'request', 'created_at', 'updated_at', ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, ) + self::TYPE_PHPNAME => array('Id', 'AdminLogin', 'AdminFirstname', 'AdminLastname', 'Resource', 'Action', 'Message', 'Request', 'CreatedAt', 'UpdatedAt', ), + self::TYPE_STUDLYPHPNAME => array('id', 'adminLogin', 'adminFirstname', 'adminLastname', 'resource', 'action', 'message', 'request', 'createdAt', 'updatedAt', ), + self::TYPE_COLNAME => array(AdminLogTableMap::ID, AdminLogTableMap::ADMIN_LOGIN, AdminLogTableMap::ADMIN_FIRSTNAME, AdminLogTableMap::ADMIN_LASTNAME, AdminLogTableMap::RESOURCE, AdminLogTableMap::ACTION, AdminLogTableMap::MESSAGE, AdminLogTableMap::REQUEST, AdminLogTableMap::CREATED_AT, AdminLogTableMap::UPDATED_AT, ), + self::TYPE_RAW_COLNAME => array('ID', 'ADMIN_LOGIN', 'ADMIN_FIRSTNAME', 'ADMIN_LASTNAME', 'RESOURCE', 'ACTION', 'MESSAGE', 'REQUEST', 'CREATED_AT', 'UPDATED_AT', ), + self::TYPE_FIELDNAME => array('id', 'admin_login', 'admin_firstname', 'admin_lastname', 'resource', 'action', 'message', 'request', 'created_at', 'updated_at', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ) ); /** @@ -136,12 +146,12 @@ class AdminLogTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'AdminLogin' => 1, 'AdminFirstname' => 2, 'AdminLastname' => 3, 'Action' => 4, 'Request' => 5, 'CreatedAt' => 6, 'UpdatedAt' => 7, ), - self::TYPE_STUDLYPHPNAME => array('id' => 0, 'adminLogin' => 1, 'adminFirstname' => 2, 'adminLastname' => 3, 'action' => 4, 'request' => 5, 'createdAt' => 6, 'updatedAt' => 7, ), - self::TYPE_COLNAME => array(AdminLogTableMap::ID => 0, AdminLogTableMap::ADMIN_LOGIN => 1, AdminLogTableMap::ADMIN_FIRSTNAME => 2, AdminLogTableMap::ADMIN_LASTNAME => 3, AdminLogTableMap::ACTION => 4, AdminLogTableMap::REQUEST => 5, AdminLogTableMap::CREATED_AT => 6, AdminLogTableMap::UPDATED_AT => 7, ), - self::TYPE_RAW_COLNAME => array('ID' => 0, 'ADMIN_LOGIN' => 1, 'ADMIN_FIRSTNAME' => 2, 'ADMIN_LASTNAME' => 3, 'ACTION' => 4, 'REQUEST' => 5, 'CREATED_AT' => 6, 'UPDATED_AT' => 7, ), - self::TYPE_FIELDNAME => array('id' => 0, 'admin_login' => 1, 'admin_firstname' => 2, 'admin_lastname' => 3, 'action' => 4, 'request' => 5, 'created_at' => 6, 'updated_at' => 7, ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, ) + self::TYPE_PHPNAME => array('Id' => 0, 'AdminLogin' => 1, 'AdminFirstname' => 2, 'AdminLastname' => 3, 'Resource' => 4, 'Action' => 5, 'Message' => 6, 'Request' => 7, 'CreatedAt' => 8, 'UpdatedAt' => 9, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'adminLogin' => 1, 'adminFirstname' => 2, 'adminLastname' => 3, 'resource' => 4, 'action' => 5, 'message' => 6, 'request' => 7, 'createdAt' => 8, 'updatedAt' => 9, ), + self::TYPE_COLNAME => array(AdminLogTableMap::ID => 0, AdminLogTableMap::ADMIN_LOGIN => 1, AdminLogTableMap::ADMIN_FIRSTNAME => 2, AdminLogTableMap::ADMIN_LASTNAME => 3, AdminLogTableMap::RESOURCE => 4, AdminLogTableMap::ACTION => 5, AdminLogTableMap::MESSAGE => 6, AdminLogTableMap::REQUEST => 7, AdminLogTableMap::CREATED_AT => 8, AdminLogTableMap::UPDATED_AT => 9, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'ADMIN_LOGIN' => 1, 'ADMIN_FIRSTNAME' => 2, 'ADMIN_LASTNAME' => 3, 'RESOURCE' => 4, 'ACTION' => 5, 'MESSAGE' => 6, 'REQUEST' => 7, 'CREATED_AT' => 8, 'UPDATED_AT' => 9, ), + self::TYPE_FIELDNAME => array('id' => 0, 'admin_login' => 1, 'admin_firstname' => 2, 'admin_lastname' => 3, 'resource' => 4, 'action' => 5, 'message' => 6, 'request' => 7, 'created_at' => 8, 'updated_at' => 9, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ) ); /** @@ -164,8 +174,10 @@ class AdminLogTableMap extends TableMap $this->addColumn('ADMIN_LOGIN', 'AdminLogin', 'VARCHAR', false, 255, null); $this->addColumn('ADMIN_FIRSTNAME', 'AdminFirstname', 'VARCHAR', false, 255, null); $this->addColumn('ADMIN_LASTNAME', 'AdminLastname', 'VARCHAR', false, 255, null); + $this->addColumn('RESOURCE', 'Resource', 'VARCHAR', false, 255, null); $this->addColumn('ACTION', 'Action', 'VARCHAR', false, 255, null); - $this->addColumn('REQUEST', 'Request', 'LONGVARCHAR', false, null, null); + $this->addColumn('MESSAGE', 'Message', 'LONGVARCHAR', false, null, null); + $this->addColumn('REQUEST', 'Request', 'CLOB', false, null, null); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); } // initialize() @@ -332,7 +344,9 @@ class AdminLogTableMap extends TableMap $criteria->addSelectColumn(AdminLogTableMap::ADMIN_LOGIN); $criteria->addSelectColumn(AdminLogTableMap::ADMIN_FIRSTNAME); $criteria->addSelectColumn(AdminLogTableMap::ADMIN_LASTNAME); + $criteria->addSelectColumn(AdminLogTableMap::RESOURCE); $criteria->addSelectColumn(AdminLogTableMap::ACTION); + $criteria->addSelectColumn(AdminLogTableMap::MESSAGE); $criteria->addSelectColumn(AdminLogTableMap::REQUEST); $criteria->addSelectColumn(AdminLogTableMap::CREATED_AT); $criteria->addSelectColumn(AdminLogTableMap::UPDATED_AT); @@ -341,7 +355,9 @@ class AdminLogTableMap extends TableMap $criteria->addSelectColumn($alias . '.ADMIN_LOGIN'); $criteria->addSelectColumn($alias . '.ADMIN_FIRSTNAME'); $criteria->addSelectColumn($alias . '.ADMIN_LASTNAME'); + $criteria->addSelectColumn($alias . '.RESOURCE'); $criteria->addSelectColumn($alias . '.ACTION'); + $criteria->addSelectColumn($alias . '.MESSAGE'); $criteria->addSelectColumn($alias . '.REQUEST'); $criteria->addSelectColumn($alias . '.CREATED_AT'); $criteria->addSelectColumn($alias . '.UPDATED_AT'); diff --git a/core/lib/Thelia/Tools/FileManager.php b/core/lib/Thelia/Tools/FileManager.php index a795bcd5e..b4173645e 100644 --- a/core/lib/Thelia/Tools/FileManager.php +++ b/core/lib/Thelia/Tools/FileManager.php @@ -118,20 +118,6 @@ class FileManager $directory = $this->getUploadDir($parentType, $fileType); $fileName = $this->renameFile($model->getId(), $uploadedFile); - $this->adminLogAppend( - $this->translator->trans( - 'Uploading %type% %fileName% to %directory% for parent_id %parentId% (%parentType%)', - array( - '%type%' => $fileType, - '%fileName%' => $uploadedFile->getClientOriginalName(), - '%directory%' => $directory . '/' . $fileName, - '%parentId%' => $parentId, - '%parentType%' => $parentType - ), - 'image' - ) - ); - $newUploadedFile = $uploadedFile->move($directory, $fileName); $model->setFile($fileName); @@ -282,20 +268,6 @@ class FileManager return strtolower(preg_replace('/[^a-zA-Z0-9-_\.]/', '', $string)); } - /** - * Helper to append a message to the admin log. - * - * @param string $message - */ - public function adminLogAppend($message) - { - AdminLog::append( - $message, - $this->container->get('request'), - $this->container->get('thelia.securityContext')->getAdminUser() - ); - } - /** * Delete image from file storage and database * diff --git a/install/thelia.sql b/install/thelia.sql index 79163345b..c20bbc8e2 100755 --- a/install/thelia.sql +++ b/install/thelia.sql @@ -1138,8 +1138,10 @@ CREATE TABLE `admin_log` `admin_login` VARCHAR(255), `admin_firstname` VARCHAR(255), `admin_lastname` VARCHAR(255), + `resource` VARCHAR(255), `action` VARCHAR(255), - `request` TEXT, + `message` TEXT, + `request` LONGTEXT, `created_at` DATETIME, `updated_at` DATETIME, PRIMARY KEY (`id`) diff --git a/local/config/schema.xml b/local/config/schema.xml index ba19efee0..6e547bd19 100755 --- a/local/config/schema.xml +++ b/local/config/schema.xml @@ -1,1259 +1,1261 @@ - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - -
- - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - -
- - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - -
- - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - -
- - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
- - - - - - - - -
- - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
- - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - -
- - - - - - - - - - -
-
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + +
+ + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
diff --git a/templates/admin/default/admin-logs.html b/templates/admin/default/admin-logs.html new file mode 100755 index 000000000..da9d5bf3e --- /dev/null +++ b/templates/admin/default/admin-logs.html @@ -0,0 +1,143 @@ +{extends file="admin-layout.tpl"} + +{block name="page-title"}{intl l='Thelia Mailing System'}{/block} + +{block name="check-resource"}admin.configuration.admin-logs{/block} +{block name="check-access"}view{/block} + +{block name="main-content"} +
+ +
+ + + + {module_include location='admin_logs_top'} + +
+
+
+ +
{intl l="Configuration variables"}
+ + {form name="thelia.admin.mailing-system.update"} + +
+ +
+
+ +
+
+ + {form_hidden_fields form=$form} + + {if $form_error}
{$form_error_message}
{/if} + + {form_field form=$form field='enabled'} +
+ + + + +
+ +
+
+ {/form_field} + + {form_field form=$form field='host'} +
+ + +
+ {/form_field} + + {form_field form=$form field='port'} +
+ + +
+ {/form_field} + + {form_field form=$form field='encryption'} +
+ + +
+ {/form_field} + + {form_field form=$form field='username'} +
+ + +
+ {/form_field} + + {form_field form=$form field='password'} +
+ + +
+ {/form_field} + + {form_field form=$form field='authmode'} +
+ + +
+ {/form_field} + + {form_field form=$form field='timeout'} +
+ + +
+ {/form_field} + + {form_field form=$form field='sourceip'} +
+ + +
+ {/form_field} + +
+
+ +
+
+ +
+ + {/form} + +
+
+
+ + {module_include location='admin_logs_bottom'} + +
+
+{/block} + +{block name="javascript-initialization"} + {javascripts file='assets/js/bootstrap-switch/bootstrap-switch.js'} + + {/javascripts} + + +{/block} \ No newline at end of file diff --git a/templates/admin/default/configuration.html b/templates/admin/default/configuration.html index a17042b4d..ff9622c45 100644 --- a/templates/admin/default/configuration.html +++ b/templates/admin/default/configuration.html @@ -153,19 +153,19 @@ {loop type="auth" name="pcc6" role="ADMIN" resource="admin.configuration.mailing-system" access="VIEW"} - {intl l='Mailing system'} + {intl l='Mailing system'} {/loop} -{* {loop type="auth" name="pcc7" role="ADMIN" resource="admin.configuration.admin-logs" access="VIEW"} + {loop type="auth" name="pcc7" role="ADMIN" resource="admin.configuration.admin-logs" access="VIEW"} - {intl l='Administration logs'} - + {intl l='Administration logs'} + {/loop} - {loop type="auth" name="pcc8" role="ADMIN" resource="admin.configuration.system-logs" access="VIEW"} +{* {loop type="auth" name="pcc8" role="ADMIN" resource="admin.configuration.system-logs" access="VIEW"} {intl l='System logs'} diff --git a/templates/admin/default/mailing-system.html b/templates/admin/default/mailing-system.html index 8ee5e3e3e..92d205289 100644 --- a/templates/admin/default/mailing-system.html +++ b/templates/admin/default/mailing-system.html @@ -13,7 +13,7 @@ {module_include location='mailing_system_top'} @@ -22,7 +22,7 @@
-
{intl l="Configuration variables"}
+
{intl l="Configuration mailing system"}
{form name="thelia.admin.mailing-system.update"} From c74422f5dc446c7097a9828181dcd0eef5b4f076 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Tue, 29 Oct 2013 15:56:03 +0100 Subject: [PATCH 12/59] implement module inclusion --- .../lib/Thelia/Command/BaseModuleGenerate.php | 9 ++++---- .../Core/Template/Smarty/Plugins/Module.php | 23 +++++++++++++++---- core/lib/Thelia/Model/Module.php | 5 ++++ core/lib/Thelia/Model/ModuleQuery.php | 19 ++++++++++++--- 4 files changed, 45 insertions(+), 11 deletions(-) diff --git a/core/lib/Thelia/Command/BaseModuleGenerate.php b/core/lib/Thelia/Command/BaseModuleGenerate.php index b26db435b..1a27d9e4c 100755 --- a/core/lib/Thelia/Command/BaseModuleGenerate.php +++ b/core/lib/Thelia/Command/BaseModuleGenerate.php @@ -35,13 +35,14 @@ abstract class BaseModuleGenerate extends ContainerAwareCommand protected $moduleDirectory; protected $reservedKeyWords = array( - "thelia" + 'thelia' ); protected $neededDirectories = array( - "Config", - "Model", - "Loop" + 'Config', + 'Model', + 'Loop', + 'AdminModule' ); protected function verifyExistingModule() diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/Module.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/Module.php index 52feae096..1c6ab4fd1 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/Module.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/Module.php @@ -25,6 +25,7 @@ namespace Thelia\Core\Template\Smarty\Plugins; use Thelia\Core\Template\Smarty\SmartyPluginDescriptor; use Thelia\Core\Template\Smarty\AbstractSmartyPlugin; +use Thelia\Model\ModuleQuery; class Module extends AbstractSmartyPlugin { @@ -32,13 +33,27 @@ class Module extends AbstractSmartyPlugin * Process theliaModule template inclusion function * * @param unknown $params - * @param unknown $smarty + * @param \Smarty_Internal_Template $template + * @internal param \Thelia\Core\Template\Smarty\Plugins\unknown $smarty + * * @return string */ - public function theliaModule($params, &$smarty) + public function theliaModule($params, \Smarty_Internal_Template $template) { - // TODO - return ""; + $content = null; + if (array_key_exists('location', $params)) { + $location = $params['location']; + $modules = ModuleQuery::getActivated(); + + foreach ($modules as $module) { + + $file = THELIA_MODULE_DIR . "/". ucfirst($module->getCode()) . "/ModuleAdmin/".$location.".html"; + if(file_exists($file)) { + $content .= file_get_contents($file); + } + } + } + return $template->fetch(sprintf("string:%s", $content)); } /** diff --git a/core/lib/Thelia/Model/Module.php b/core/lib/Thelia/Model/Module.php index b7fb2a443..c9ccd5f8d 100755 --- a/core/lib/Thelia/Model/Module.php +++ b/core/lib/Thelia/Model/Module.php @@ -2,8 +2,13 @@ namespace Thelia\Model; +use Propel\Runtime\Connection\ConnectionInterface; use Thelia\Model\Base\Module as BaseModule; class Module extends BaseModule { + public function postSave(ConnectionInterface $con = null) + { + ModuleQuery::resetActivated(); + } } diff --git a/core/lib/Thelia/Model/ModuleQuery.php b/core/lib/Thelia/Model/ModuleQuery.php index fdfe502a4..aaf2092e6 100755 --- a/core/lib/Thelia/Model/ModuleQuery.php +++ b/core/lib/Thelia/Model/ModuleQuery.php @@ -16,13 +16,26 @@ use Thelia\Model\Base\ModuleQuery as BaseModuleQuery; * */ class ModuleQuery extends BaseModuleQuery { + + protected static $activated = null; /** * @return array|mixed|\PropelObjectCollection */ public static function getActivated() { - return self::create() - ->filterByActivate(1) - ->find(); + if(null === self::$activated) { + self::$activated = self::create() + ->filterByActivate(1) + ->find(); + } + + return self::$activated; } + + public static function resetActivated() + { + self::$activated = null; + } + + } // ModuleQuery From a055f3b3eb71f607fe572c968a6c3d062c2987ab Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Tue, 29 Oct 2013 16:09:50 +0100 Subject: [PATCH 13/59] admin log --- .../Thelia/Config/Resources/routing/admin.xml | 4 + .../Controller/Admin/AdminLogsController.php | 31 +++ core/lib/Thelia/Model/AdminLogQuery.php | 38 +++- templates/admin/default/admin-logs.html | 190 ++++++++++-------- templates/admin/default/ajax/logger.html | 13 ++ .../default/assets/less/thelia/logger.less | 25 +++ .../default/assets/less/thelia/thelia.less | 9 + 7 files changed, 222 insertions(+), 88 deletions(-) create mode 100644 templates/admin/default/ajax/logger.html create mode 100644 templates/admin/default/assets/less/thelia/logger.less diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index d7df6e5fa..27bb58c72 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -830,6 +830,10 @@ Thelia\Controller\Admin\AdminLogsController::defaultAction + + Thelia\Controller\Admin\AdminLogsController::loadLoggerAjaxAction + + diff --git a/core/lib/Thelia/Controller/Admin/AdminLogsController.php b/core/lib/Thelia/Controller/Admin/AdminLogsController.php index e6e364d15..244baf747 100644 --- a/core/lib/Thelia/Controller/Admin/AdminLogsController.php +++ b/core/lib/Thelia/Controller/Admin/AdminLogsController.php @@ -24,6 +24,7 @@ namespace Thelia\Controller\Admin; use Thelia\Core\Security\AccessManager; +use Thelia\Model\AdminLogQuery; class AdminLogsController extends BaseAdminController { @@ -36,4 +37,34 @@ class AdminLogsController extends BaseAdminController // Render the edition template. return $this->render('admin-logs'); } + + public function loadLoggerAjaxAction() + { + $entries = array(); + foreach( AdminLogQuery::getEntries( + $this->getRequest()->request->get('admins', array()), + null, + null, + array_merge($this->getRequest()->request->get('resources', array()), $this->getRequest()->request->get('modules', array())) + ) as $entry) { + + $entries[] = array( + "head" => sprintf( + "[%s][%s][%s:%s]", + date('Y-m-d H:i:s', $entry->getCreatedAt()->getTimestamp()), + $entry->getAdminLogin(), + $entry->getResource(), + $entry->getAction() + ), + "data" => $entry->getMessage(), + ); + } + + return $this->render( + 'ajax/logger', + array( + 'entries' => $entries, + ) + ); + } } diff --git a/core/lib/Thelia/Model/AdminLogQuery.php b/core/lib/Thelia/Model/AdminLogQuery.php index 43a054bbb..8e9fb7eab 100755 --- a/core/lib/Thelia/Model/AdminLogQuery.php +++ b/core/lib/Thelia/Model/AdminLogQuery.php @@ -2,6 +2,7 @@ namespace Thelia\Model; +use Propel\Runtime\ActiveQuery\Criteria; use Thelia\Model\Base\AdminLogQuery as BaseAdminLogQuery; @@ -15,6 +16,41 @@ use Thelia\Model\Base\AdminLogQuery as BaseAdminLogQuery; * long as it does not already exist in the output directory. * */ -class AdminLogQuery extends BaseAdminLogQuery { +class AdminLogQuery extends BaseAdminLogQuery +{ + /** + * @param null $login + * @param \DateTime $maxDateTime + * @param \DateTime $minDateTime + * @param null $resources + * @param null $actions + * + * @return array|mixed|\Propel\Runtime\Collection\ObjectCollection + */ + public static function getEntries($login = null, \DateTime $maxDateTime = null, \DateTime $minDateTime = null, $resources = null, $actions = null) + { + $search = self::create(); + if(null !== $minDateTime) { + $search->filterByCreatedAt($minDateTime->getTimestamp(), Criteria::GREATER_EQUAL); + } + + if(null !== $maxDateTime) { + $search->filterByCreatedAt($maxDateTime->getTimestamp(), Criteria::LESS_EQUAL); + } + + if(null !== $resources) { + $search->filterByResource($resources); + } + + if(null !== $actions) { + $search->filterByAction($actions); + } + + if(null !== $login) { + $search->filterByAdminLogin($login); + } + + return $search->find(); + } } // AdminLogQuery diff --git a/templates/admin/default/admin-logs.html b/templates/admin/default/admin-logs.html index da9d5bf3e..5acb35667 100755 --- a/templates/admin/default/admin-logs.html +++ b/templates/admin/default/admin-logs.html @@ -13,7 +13,7 @@ {module_include location='admin_logs_top'} @@ -22,99 +22,84 @@
-
{intl l="Configuration variables"}
+
{intl l="Administration logs"}
- {form name="thelia.admin.mailing-system.update"} +
-
- -
-
- -
+
+
+
+
- {form_hidden_fields form=$form} +
+ Administrators : +
- {if $form_error}
{$form_error_message}
{/if} - - {form_field form=$form field='enabled'} -
- - - - -
- -
-
- {/form_field} - - {form_field form=$form field='host'} -
- - -
- {/form_field} - - {form_field form=$form field='port'} -
- - -
- {/form_field} - - {form_field form=$form field='encryption'} -
- - -
- {/form_field} - - {form_field form=$form field='username'} -
- - -
- {/form_field} - - {form_field form=$form field='password'} -
- - -
- {/form_field} - - {form_field form=$form field='authmode'} -
- - -
- {/form_field} - - {form_field form=$form field='timeout'} -
- - -
- {/form_field} - - {form_field form=$form field='sourceip'} -
- - -
- {/form_field} - -
-
- +
+ {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} +
- +
- {/form} +
+
+ 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} +
+ +
+ +
+
+ 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} +
+ +
+ +
+
+ +
+
+ +
+ +
@@ -134,8 +119,39 @@ {/javascripts} + {javascripts file='assets/js/jquery.ui/jquery.ui.datepicker/jquery.ui.datepicker.js'} + + {/javascripts} + + {stylesheets file='assets/js/jquery.ui/jquery.ui.theme.css'} + + {/stylesheets} + {stylesheets file='assets/js/jquery.ui/jquery.ui.datepicker/jquery.ui.datepicker.css'} + + {/stylesheets} + + {javascripts file="assets/js/jquery/jquery.ui.ui.datepicker/i18n/jquery.ui.datepicker-{lang attr="locale"}.js" catchException="true"} + + {/javascripts} + + + - {/javascripts} - {javascripts file='assets/js/main.js'} {/javascripts} @@ -63,10 +59,6 @@ filemanager_title:"{intl l='Files manager'}" , external_plugins: { "filemanager" : "{url file='/tinymce/plugins/filemanager/plugin.min.js'}"} }); - - $(function($){ - {*$('.datepicker').datepicker({ dateFormat: "{$dateFormat}", defaultDate: +60, minDate: "+0m" });*} - }); {/block} diff --git a/templates/admin/default/coupon-update.html b/templates/admin/default/coupon-update.html index f96da1319..138ed28aa 100755 --- a/templates/admin/default/coupon-update.html +++ b/templates/admin/default/coupon-update.html @@ -28,10 +28,6 @@ {/block} {block name="javascript-initialization"} - {javascripts file='assets/bootstrap-datepicker/js/bootstrap-datepicker.js'} - - {/javascripts} - {javascripts file='assets/js/main.js'} {/javascripts} From b8dad621fdd01113f8e9b805292dc41a169d4e75 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Wed, 30 Oct 2013 12:19:14 +0100 Subject: [PATCH 17/59] remove temporary home carousel --- templates/default/index.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/templates/default/index.html b/templates/default/index.html index c4204cb83..292aa238a 100644 --- a/templates/default/index.html +++ b/templates/default/index.html @@ -14,16 +14,16 @@
{images file='assets/img/carousel/slider1.png'}img1{/images}
-
+ {*
{images file='assets/img/carousel/slider2.png'}img2{/images}
{images file='assets/img/carousel/slider3.png'}img3{/images} -
+
*}
- - +{* + *}
From 2ee90d35e4b234c7705490a69f8ed141aaccf9b7 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Wed, 30 Oct 2013 14:27:45 +0100 Subject: [PATCH 18/59] create administrator update password event --- .../AdministratorUpdatePasswordEvent.php | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 core/lib/Thelia/Core/Event/Administrator/AdministratorUpdatePasswordEvent.php diff --git a/core/lib/Thelia/Core/Event/Administrator/AdministratorUpdatePasswordEvent.php b/core/lib/Thelia/Core/Event/Administrator/AdministratorUpdatePasswordEvent.php new file mode 100644 index 000000000..70f92532b --- /dev/null +++ b/core/lib/Thelia/Core/Event/Administrator/AdministratorUpdatePasswordEvent.php @@ -0,0 +1,84 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event\Administrator; +use Thelia\Core\Event\ActionEvent; + + +/** + * Class AdministratorUpdatePasswordEvent + * @package Thelia\Core\Event\Administrator + * @author Manuel Raynaud + */ +class AdministratorUpdatePasswordEvent extends ActionEvent +{ + + /** + * @var string administrator login + */ + protected $login; + + /** + * @var string new administrator password + */ + protected $password; + + public function __construct($login) + { + $this->login = $login; + } + + /** + * @param string $password + */ + public function setPassword($password) + { + $this->password = $password; + } + + /** + * @return string + */ + public function getPassword() + { + return $this->password; + } + + /** + * @param string $login + */ + public function setLogin($login) + { + $this->login = $login; + } + + /** + * @return string + */ + public function getLogin() + { + return $this->login; + } + + +} \ No newline at end of file From 434092a33b22f03bef05ac238d103c49400928f9 Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Wed, 30 Oct 2013 14:45:50 +0100 Subject: [PATCH 19/59] admin login is now unique --- install/thelia.sql | 1 + local/config/schema.xml | 3 +++ 2 files changed, 4 insertions(+) diff --git a/install/thelia.sql b/install/thelia.sql index c20bbc8e2..b213c114f 100755 --- a/install/thelia.sql +++ b/install/thelia.sql @@ -984,6 +984,7 @@ CREATE TABLE `admin` `created_at` DATETIME, `updated_at` DATETIME, PRIMARY KEY (`id`), + UNIQUE INDEX `login_UNIQUE` (`login`), INDEX `idx_admin_profile_id` (`profile_id`), CONSTRAINT `fk_admin_profile_id` FOREIGN KEY (`profile_id`) diff --git a/local/config/schema.xml b/local/config/schema.xml index 6e547bd19..cc9c4c396 100755 --- a/local/config/schema.xml +++ b/local/config/schema.xml @@ -771,6 +771,9 @@ + + + From 9d011eb5c67b40174eb5d8e89f1e80c8c5c96fa4 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Wed, 30 Oct 2013 14:46:21 +0100 Subject: [PATCH 20/59] change command line for creating new administrator --- core/lib/Thelia/Command/CreateAdminUser.php | 2 +- reset_install.bat | 2 +- reset_install.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/lib/Thelia/Command/CreateAdminUser.php b/core/lib/Thelia/Command/CreateAdminUser.php index 857790141..5ac62802a 100644 --- a/core/lib/Thelia/Command/CreateAdminUser.php +++ b/core/lib/Thelia/Command/CreateAdminUser.php @@ -38,7 +38,7 @@ class CreateAdminUser extends ContainerAwareCommand protected function configure() { $this - ->setName("thelia:create-admin") + ->setName("admin:create") ->setDescription("Create a new adminsitration user") ->setHelp("The thelia:create-admin command create a new administration user.") ->addOption( diff --git a/reset_install.bat b/reset_install.bat index 0a12c43d2..f8c0b35e2 100644 --- a/reset_install.bat +++ b/reset_install.bat @@ -26,7 +26,7 @@ if exist local\config\database.yml ( php install\faker.php echo [INFO] Adding admin - php Thelia thelia:create-admin + php Thelia admin:create echo [SUCCESS] Reset done ) diff --git a/reset_install.sh b/reset_install.sh index a91a2dc1c..83288a509 100755 --- a/reset_install.sh +++ b/reset_install.sh @@ -32,7 +32,7 @@ echo -e "\n\033[01;34m[INFO] Installing fixtures\033[00m\n" php install/faker.php echo -e "\n\033[01;34m[INFO] Adding admin\033[00m\n" -php Thelia thelia:create-admin --login_name thelia2 --password thelia2 --last_name thelia2 --first_name thelia2 +php Thelia admin:create --login_name thelia2 --password thelia2 --last_name thelia2 --first_name thelia2 echo -e "\n\033[01;34m[INFO] Clearing caches\033[00m\n" php Thelia cache:clear From a540c503957197666deed1a43fe0466674ceffd5 Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Wed, 30 Oct 2013 14:51:13 +0100 Subject: [PATCH 21/59] fix administrators management bug --- templates/admin/default/administrators.html | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/templates/admin/default/administrators.html b/templates/admin/default/administrators.html index 9cb4a792a..c2b8fa521 100644 --- a/templates/admin/default/administrators.html +++ b/templates/admin/default/administrators.html @@ -62,13 +62,20 @@ From b0f3ad69d2e9fbc89f9594535bc5b3c21b955ff9 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Wed, 30 Oct 2013 15:01:18 +0100 Subject: [PATCH 22/59] start creating admin password recovery --- core/lib/Thelia/Action/Administrator.php | 16 ++++- .../Thelia/Command/AdminUpdatePassword.php | 63 +++++++++++++++++++ core/lib/Thelia/Command/CreateAdminUser.php | 4 +- .../AdministratorUpdatePasswordEvent.php | 2 +- core/lib/Thelia/Core/Event/TheliaEvents.php | 1 + 5 files changed, 80 insertions(+), 6 deletions(-) create mode 100644 core/lib/Thelia/Command/AdminUpdatePassword.php diff --git a/core/lib/Thelia/Action/Administrator.php b/core/lib/Thelia/Action/Administrator.php index 2bbfce8a8..23167dd40 100644 --- a/core/lib/Thelia/Action/Administrator.php +++ b/core/lib/Thelia/Action/Administrator.php @@ -25,6 +25,7 @@ namespace Thelia\Action; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Thelia\Core\Event\Administrator\AdministratorEvent; +use Thelia\Core\Event\Administrator\AdministratorUpdatePasswordEvent; use Thelia\Core\Event\TheliaEvents; use Thelia\Model\Admin as AdminModel; use Thelia\Model\AdminQuery; @@ -92,15 +93,24 @@ class Administrator extends BaseAction implements EventSubscriberInterface } } + public function updatePassword(AdministratorUpdatePasswordEvent $event) + { + if (null !== $admin = AdminQuery::create()->filterByLogin($event->getLogin())->findOne()) { + $admin->setPassword($event->getPassword()) + ->save(); + } + } + /** * {@inheritDoc} */ public static function getSubscribedEvents() { return array( - TheliaEvents::ADMINISTRATOR_CREATE => array("create", 128), - TheliaEvents::ADMINISTRATOR_UPDATE => array("update", 128), - TheliaEvents::ADMINISTRATOR_DELETE => array("delete", 128), + TheliaEvents::ADMINISTRATOR_CREATE => array('create', 128), + TheliaEvents::ADMINISTRATOR_UPDATE => array('update', 128), + TheliaEvents::ADMINISTRATOR_DELETE => array('delete', 128), + TheliaEvents::ADMINISTRATOR_UPDATEPASSWORD => array('updatePassword', 128) ); } } diff --git a/core/lib/Thelia/Command/AdminUpdatePassword.php b/core/lib/Thelia/Command/AdminUpdatePassword.php new file mode 100644 index 000000000..6b0a0ec48 --- /dev/null +++ b/core/lib/Thelia/Command/AdminUpdatePassword.php @@ -0,0 +1,63 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Command; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputOption; + + +/** + * command line for updating admin password + * + * php Thelia admin:updatePassword + * + * Class AdminUpdatePassword + * @package Thelia\Command + * @author Manuel Raynaud + */ +class AdminUpdatePassword extends ContainerAwareCommand +{ + + /** + * Configures the current command. + */ + protected function configure() + { + $this + ->setName('admin:updatePassword') + ->setDescription('change administrator password') + ->setHelp('The admin:updatePassword command allows you to change the password for a given administrator') + ->addArgument( + 'login', + InputArgument::REQUIRED, + 'Login for administrator you want to change the password' + ) + ->addOption( + 'password', + null, + InputOption::VALUE_REQUIRED, + 'Desired password. If this option is omitted, a random password is generated and shown in this prompt after' + ) + ; + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Command/CreateAdminUser.php b/core/lib/Thelia/Command/CreateAdminUser.php index 5ac62802a..988122e7a 100644 --- a/core/lib/Thelia/Command/CreateAdminUser.php +++ b/core/lib/Thelia/Command/CreateAdminUser.php @@ -39,8 +39,8 @@ class CreateAdminUser extends ContainerAwareCommand { $this ->setName("admin:create") - ->setDescription("Create a new adminsitration user") - ->setHelp("The thelia:create-admin command create a new administration user.") + ->setDescription("Create a new administrator user") + ->setHelp("The admin:create command create a new administration user.") ->addOption( 'login_name', null, diff --git a/core/lib/Thelia/Core/Event/Administrator/AdministratorUpdatePasswordEvent.php b/core/lib/Thelia/Core/Event/Administrator/AdministratorUpdatePasswordEvent.php index 70f92532b..cccb45cc4 100644 --- a/core/lib/Thelia/Core/Event/Administrator/AdministratorUpdatePasswordEvent.php +++ b/core/lib/Thelia/Core/Event/Administrator/AdministratorUpdatePasswordEvent.php @@ -80,5 +80,5 @@ class AdministratorUpdatePasswordEvent extends ActionEvent return $this->login; } - + } \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/TheliaEvents.php b/core/lib/Thelia/Core/Event/TheliaEvents.php index 42b20d8cd..ea3d7686a 100755 --- a/core/lib/Thelia/Core/Event/TheliaEvents.php +++ b/core/lib/Thelia/Core/Event/TheliaEvents.php @@ -565,6 +565,7 @@ final class TheliaEvents const ADMINISTRATOR_CREATE = "action.createAdministrator"; const ADMINISTRATOR_UPDATE = "action.updateAdministrator"; const ADMINISTRATOR_DELETE = "action.deleteAdministrator"; + const ADMINISTRATOR_UPDATEPASSWORD = 'action.generatePassword'; // -- Mailing System management --------------------------------------------- From e18c8992f82ecc5882803c1733cd09e2ecf970d8 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Wed, 30 Oct 2013 15:33:25 +0100 Subject: [PATCH 23/59] finish admin update password command line --- core/lib/Thelia/Action/Administrator.php | 7 ++-- ...ord.php => AdminUpdatePasswordCommand.php} | 41 ++++++++++++++++++- core/lib/Thelia/Config/Resources/config.xml | 1 + .../AdministratorUpdatePasswordEvent.php | 23 ++++++----- local/modules/Cheque/Config/config.xml | 2 +- 5 files changed, 57 insertions(+), 17 deletions(-) rename core/lib/Thelia/Command/{AdminUpdatePassword.php => AdminUpdatePasswordCommand.php} (70%) diff --git a/core/lib/Thelia/Action/Administrator.php b/core/lib/Thelia/Action/Administrator.php index 23167dd40..15940082a 100644 --- a/core/lib/Thelia/Action/Administrator.php +++ b/core/lib/Thelia/Action/Administrator.php @@ -95,10 +95,9 @@ class Administrator extends BaseAction implements EventSubscriberInterface public function updatePassword(AdministratorUpdatePasswordEvent $event) { - if (null !== $admin = AdminQuery::create()->filterByLogin($event->getLogin())->findOne()) { - $admin->setPassword($event->getPassword()) - ->save(); - } + $admin = $event->getAdmin(); + $admin->setPassword($event->getPassword()) + ->save(); } /** diff --git a/core/lib/Thelia/Command/AdminUpdatePassword.php b/core/lib/Thelia/Command/AdminUpdatePasswordCommand.php similarity index 70% rename from core/lib/Thelia/Command/AdminUpdatePassword.php rename to core/lib/Thelia/Command/AdminUpdatePasswordCommand.php index 6b0a0ec48..d4d0e5fc8 100644 --- a/core/lib/Thelia/Command/AdminUpdatePassword.php +++ b/core/lib/Thelia/Command/AdminUpdatePasswordCommand.php @@ -22,8 +22,15 @@ /*************************************************************************************/ namespace Thelia\Command; + use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; +use Thelia\Core\Event\Administrator\AdministratorUpdatePasswordEvent; +use Thelia\Core\Event\TheliaEvents; +use Thelia\Model\AdminQuery; +use Thelia\Tools\Password; /** @@ -31,11 +38,11 @@ use Symfony\Component\Console\Input\InputOption; * * php Thelia admin:updatePassword * - * Class AdminUpdatePassword + * Class AdminUpdatePasswordCommand * @package Thelia\Command * @author Manuel Raynaud */ -class AdminUpdatePassword extends ContainerAwareCommand +class AdminUpdatePasswordCommand extends ContainerAwareCommand { /** @@ -60,4 +67,34 @@ class AdminUpdatePassword extends ContainerAwareCommand ) ; } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $login = $input->getArgument('login'); + + + if (null === $admin = AdminQuery::create()->filterByLogin($login)->findOne()) { + throw new \RuntimeException(sprintf('Admin with login %s does not exists', $login)); + } + + + $password = $input->getOption('password') ?: Password::generateRandom(); + + $event = new AdministratorUpdatePasswordEvent($admin); + $event->setPassword($password); + + + $this-> + getContainer() + ->get('event_dispatcher') + ->dispatch(TheliaEvents::ADMINISTRATOR_UPDATEPASSWORD, $event); + + $output->writeln(array( + '', + sprintf('admin %s password updated', $login), + sprintf('new password is : %s', $password), + '' + )); + + } } \ No newline at end of file diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index c0af99896..255f70dfd 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -182,6 +182,7 @@ + diff --git a/core/lib/Thelia/Core/Event/Administrator/AdministratorUpdatePasswordEvent.php b/core/lib/Thelia/Core/Event/Administrator/AdministratorUpdatePasswordEvent.php index cccb45cc4..01a36a206 100644 --- a/core/lib/Thelia/Core/Event/Administrator/AdministratorUpdatePasswordEvent.php +++ b/core/lib/Thelia/Core/Event/Administrator/AdministratorUpdatePasswordEvent.php @@ -23,6 +23,7 @@ namespace Thelia\Core\Event\Administrator; use Thelia\Core\Event\ActionEvent; +use Thelia\Model\Admin; /** @@ -34,18 +35,18 @@ class AdministratorUpdatePasswordEvent extends ActionEvent { /** - * @var string administrator login + * @var \Thelia\Model\Admin */ - protected $login; + protected $admin; /** * @var string new administrator password */ protected $password; - public function __construct($login) + public function __construct(Admin $admin) { - $this->login = $login; + $this->admin = $admin; } /** @@ -65,20 +66,22 @@ class AdministratorUpdatePasswordEvent extends ActionEvent } /** - * @param string $login + * @param \Thelia\Model\Admin $admin */ - public function setLogin($login) + public function setAdmin(Admin $admin) { - $this->login = $login; + $this->admin = $admin; } /** - * @return string + * @return \Thelia\Model\Admin */ - public function getLogin() + public function getAdmin() { - return $this->login; + return $this->admin; } + + } \ No newline at end of file diff --git a/local/modules/Cheque/Config/config.xml b/local/modules/Cheque/Config/config.xml index 2430f5027..cac3f6b7b 100755 --- a/local/modules/Cheque/Config/config.xml +++ b/local/modules/Cheque/Config/config.xml @@ -1,4 +1,4 @@ - +string Date: Wed, 30 Oct 2013 14:27:45 +0100 Subject: [PATCH 24/59] create administrator update password event --- .../AdministratorUpdatePasswordEvent.php | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 core/lib/Thelia/Core/Event/Administrator/AdministratorUpdatePasswordEvent.php diff --git a/core/lib/Thelia/Core/Event/Administrator/AdministratorUpdatePasswordEvent.php b/core/lib/Thelia/Core/Event/Administrator/AdministratorUpdatePasswordEvent.php new file mode 100644 index 000000000..b41b83a06 --- /dev/null +++ b/core/lib/Thelia/Core/Event/Administrator/AdministratorUpdatePasswordEvent.php @@ -0,0 +1,84 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event\Administrator; +use Thelia\Core\Event\ActionEvent; + + +/** + * Class AdministratorUpdatePasswordEvent + * @package Thelia\Core\Event\Administrator + * @author Manuel Raynaud + */ +class AdministratorUpdatePasswordEvent extends ActionEvent +{ + + /** + * @var string administrator login + */ + protected $login; + + /** + * @var string new administrator password + */ + protected $password; + + public function __construct($login) + { + $this->login = $login; + } + + /** + * @param string $password + */ + public function setPassword($password) + { + $this->password = $password; + } + + /** + * @return string + */ + public function getPassword() + { + return $this->password; + } + + /** + * @param string $login + */ + public function setLogin($login) + { + $this->login = $login; + } + + /** + * @return string + */ + public function getLogin() + { + return $this->login; + } + + +} \ No newline at end of file From c327b20fd640ffb694a81fd78be406d34f120747 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Wed, 30 Oct 2013 14:46:21 +0100 Subject: [PATCH 25/59] change command line for creating new administrator --- core/lib/Thelia/Command/CreateAdminUser.php | 2 +- reset_install.bat | 2 +- reset_install.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/lib/Thelia/Command/CreateAdminUser.php b/core/lib/Thelia/Command/CreateAdminUser.php index 857790141..5ac62802a 100644 --- a/core/lib/Thelia/Command/CreateAdminUser.php +++ b/core/lib/Thelia/Command/CreateAdminUser.php @@ -38,7 +38,7 @@ class CreateAdminUser extends ContainerAwareCommand protected function configure() { $this - ->setName("thelia:create-admin") + ->setName("admin:create") ->setDescription("Create a new adminsitration user") ->setHelp("The thelia:create-admin command create a new administration user.") ->addOption( diff --git a/reset_install.bat b/reset_install.bat index 0a12c43d2..f8c0b35e2 100644 --- a/reset_install.bat +++ b/reset_install.bat @@ -26,7 +26,7 @@ if exist local\config\database.yml ( php install\faker.php echo [INFO] Adding admin - php Thelia thelia:create-admin + php Thelia admin:create echo [SUCCESS] Reset done ) diff --git a/reset_install.sh b/reset_install.sh index a91a2dc1c..83288a509 100755 --- a/reset_install.sh +++ b/reset_install.sh @@ -32,7 +32,7 @@ echo -e "\n\033[01;34m[INFO] Installing fixtures\033[00m\n" php install/faker.php echo -e "\n\033[01;34m[INFO] Adding admin\033[00m\n" -php Thelia thelia:create-admin --login_name thelia2 --password thelia2 --last_name thelia2 --first_name thelia2 +php Thelia admin:create --login_name thelia2 --password thelia2 --last_name thelia2 --first_name thelia2 echo -e "\n\033[01;34m[INFO] Clearing caches\033[00m\n" php Thelia cache:clear From 66c30a1b4c376f6b321638e39b20e76860805cb6 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Wed, 30 Oct 2013 15:01:18 +0100 Subject: [PATCH 26/59] start creating admin password recovery --- core/lib/Thelia/Action/Administrator.php | 16 ++++- .../Thelia/Command/AdminUpdatePassword.php | 63 +++++++++++++++++++ core/lib/Thelia/Command/CreateAdminUser.php | 4 +- core/lib/Thelia/Core/Event/TheliaEvents.php | 1 + 4 files changed, 79 insertions(+), 5 deletions(-) create mode 100644 core/lib/Thelia/Command/AdminUpdatePassword.php diff --git a/core/lib/Thelia/Action/Administrator.php b/core/lib/Thelia/Action/Administrator.php index 2bbfce8a8..23167dd40 100644 --- a/core/lib/Thelia/Action/Administrator.php +++ b/core/lib/Thelia/Action/Administrator.php @@ -25,6 +25,7 @@ namespace Thelia\Action; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Thelia\Core\Event\Administrator\AdministratorEvent; +use Thelia\Core\Event\Administrator\AdministratorUpdatePasswordEvent; use Thelia\Core\Event\TheliaEvents; use Thelia\Model\Admin as AdminModel; use Thelia\Model\AdminQuery; @@ -92,15 +93,24 @@ class Administrator extends BaseAction implements EventSubscriberInterface } } + public function updatePassword(AdministratorUpdatePasswordEvent $event) + { + if (null !== $admin = AdminQuery::create()->filterByLogin($event->getLogin())->findOne()) { + $admin->setPassword($event->getPassword()) + ->save(); + } + } + /** * {@inheritDoc} */ public static function getSubscribedEvents() { return array( - TheliaEvents::ADMINISTRATOR_CREATE => array("create", 128), - TheliaEvents::ADMINISTRATOR_UPDATE => array("update", 128), - TheliaEvents::ADMINISTRATOR_DELETE => array("delete", 128), + TheliaEvents::ADMINISTRATOR_CREATE => array('create', 128), + TheliaEvents::ADMINISTRATOR_UPDATE => array('update', 128), + TheliaEvents::ADMINISTRATOR_DELETE => array('delete', 128), + TheliaEvents::ADMINISTRATOR_UPDATEPASSWORD => array('updatePassword', 128) ); } } diff --git a/core/lib/Thelia/Command/AdminUpdatePassword.php b/core/lib/Thelia/Command/AdminUpdatePassword.php new file mode 100644 index 000000000..f6cf8ee64 --- /dev/null +++ b/core/lib/Thelia/Command/AdminUpdatePassword.php @@ -0,0 +1,63 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Command; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputOption; + + +/** + * command line for updating admin password + * + * php Thelia admin:updatePassword + * + * Class AdminUpdatePassword + * @package Thelia\Command + * @author Manuel Raynaud + */ +class AdminUpdatePassword extends ContainerAwareCommand +{ + + /** + * Configures the current command. + */ + protected function configure() + { + $this + ->setName('admin:updatePassword') + ->setDescription('change administrator password') + ->setHelp('The admin:updatePassword command allows you to change the password for a given administrator') + ->addArgument( + 'login', + InputArgument::REQUIRED, + 'Login for administrator you want to change the password' + ) + ->addOption( + 'password', + null, + InputOption::VALUE_REQUIRED, + 'Desired password. If this option is omitted, a random password is generated and shown in this prompt after' + ) + ; + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Command/CreateAdminUser.php b/core/lib/Thelia/Command/CreateAdminUser.php index 5ac62802a..988122e7a 100644 --- a/core/lib/Thelia/Command/CreateAdminUser.php +++ b/core/lib/Thelia/Command/CreateAdminUser.php @@ -39,8 +39,8 @@ class CreateAdminUser extends ContainerAwareCommand { $this ->setName("admin:create") - ->setDescription("Create a new adminsitration user") - ->setHelp("The thelia:create-admin command create a new administration user.") + ->setDescription("Create a new administrator user") + ->setHelp("The admin:create command create a new administration user.") ->addOption( 'login_name', null, diff --git a/core/lib/Thelia/Core/Event/TheliaEvents.php b/core/lib/Thelia/Core/Event/TheliaEvents.php index 42b20d8cd..ea3d7686a 100755 --- a/core/lib/Thelia/Core/Event/TheliaEvents.php +++ b/core/lib/Thelia/Core/Event/TheliaEvents.php @@ -565,6 +565,7 @@ final class TheliaEvents const ADMINISTRATOR_CREATE = "action.createAdministrator"; const ADMINISTRATOR_UPDATE = "action.updateAdministrator"; const ADMINISTRATOR_DELETE = "action.deleteAdministrator"; + const ADMINISTRATOR_UPDATEPASSWORD = 'action.generatePassword'; // -- Mailing System management --------------------------------------------- From 78cba61cd56938cdde781278a3c515daffdcd7ec Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Wed, 30 Oct 2013 15:33:25 +0100 Subject: [PATCH 27/59] finish admin update password command line --- core/lib/Thelia/Action/Administrator.php | 7 ++-- ...ord.php => AdminUpdatePasswordCommand.php} | 41 ++++++++++++++++++- core/lib/Thelia/Config/Resources/config.xml | 1 + .../AdministratorUpdatePasswordEvent.php | 23 ++++++----- local/modules/Cheque/Config/config.xml | 2 +- 5 files changed, 57 insertions(+), 17 deletions(-) rename core/lib/Thelia/Command/{AdminUpdatePassword.php => AdminUpdatePasswordCommand.php} (70%) diff --git a/core/lib/Thelia/Action/Administrator.php b/core/lib/Thelia/Action/Administrator.php index 23167dd40..15940082a 100644 --- a/core/lib/Thelia/Action/Administrator.php +++ b/core/lib/Thelia/Action/Administrator.php @@ -95,10 +95,9 @@ class Administrator extends BaseAction implements EventSubscriberInterface public function updatePassword(AdministratorUpdatePasswordEvent $event) { - if (null !== $admin = AdminQuery::create()->filterByLogin($event->getLogin())->findOne()) { - $admin->setPassword($event->getPassword()) - ->save(); - } + $admin = $event->getAdmin(); + $admin->setPassword($event->getPassword()) + ->save(); } /** diff --git a/core/lib/Thelia/Command/AdminUpdatePassword.php b/core/lib/Thelia/Command/AdminUpdatePasswordCommand.php similarity index 70% rename from core/lib/Thelia/Command/AdminUpdatePassword.php rename to core/lib/Thelia/Command/AdminUpdatePasswordCommand.php index f6cf8ee64..035dc75e3 100644 --- a/core/lib/Thelia/Command/AdminUpdatePassword.php +++ b/core/lib/Thelia/Command/AdminUpdatePasswordCommand.php @@ -22,8 +22,15 @@ /*************************************************************************************/ namespace Thelia\Command; + use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; +use Thelia\Core\Event\Administrator\AdministratorUpdatePasswordEvent; +use Thelia\Core\Event\TheliaEvents; +use Thelia\Model\AdminQuery; +use Thelia\Tools\Password; /** @@ -31,11 +38,11 @@ use Symfony\Component\Console\Input\InputOption; * * php Thelia admin:updatePassword * - * Class AdminUpdatePassword + * Class AdminUpdatePasswordCommand * @package Thelia\Command * @author Manuel Raynaud */ -class AdminUpdatePassword extends ContainerAwareCommand +class AdminUpdatePasswordCommand extends ContainerAwareCommand { /** @@ -60,4 +67,34 @@ class AdminUpdatePassword extends ContainerAwareCommand ) ; } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $login = $input->getArgument('login'); + + + if (null === $admin = AdminQuery::create()->filterByLogin($login)->findOne()) { + throw new \RuntimeException(sprintf('Admin with login %s does not exists', $login)); + } + + + $password = $input->getOption('password') ?: Password::generateRandom(); + + $event = new AdministratorUpdatePasswordEvent($admin); + $event->setPassword($password); + + + $this-> + getContainer() + ->get('event_dispatcher') + ->dispatch(TheliaEvents::ADMINISTRATOR_UPDATEPASSWORD, $event); + + $output->writeln(array( + '', + sprintf('admin %s password updated', $login), + sprintf('new password is : %s', $password), + '' + )); + + } } \ No newline at end of file diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index c0af99896..255f70dfd 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -182,6 +182,7 @@ + diff --git a/core/lib/Thelia/Core/Event/Administrator/AdministratorUpdatePasswordEvent.php b/core/lib/Thelia/Core/Event/Administrator/AdministratorUpdatePasswordEvent.php index b41b83a06..e6a5894ac 100644 --- a/core/lib/Thelia/Core/Event/Administrator/AdministratorUpdatePasswordEvent.php +++ b/core/lib/Thelia/Core/Event/Administrator/AdministratorUpdatePasswordEvent.php @@ -23,6 +23,7 @@ namespace Thelia\Core\Event\Administrator; use Thelia\Core\Event\ActionEvent; +use Thelia\Model\Admin; /** @@ -34,18 +35,18 @@ class AdministratorUpdatePasswordEvent extends ActionEvent { /** - * @var string administrator login + * @var \Thelia\Model\Admin */ - protected $login; + protected $admin; /** * @var string new administrator password */ protected $password; - public function __construct($login) + public function __construct(Admin $admin) { - $this->login = $login; + $this->admin = $admin; } /** @@ -65,20 +66,22 @@ class AdministratorUpdatePasswordEvent extends ActionEvent } /** - * @param string $login + * @param \Thelia\Model\Admin $admin */ - public function setLogin($login) + public function setAdmin(Admin $admin) { - $this->login = $login; + $this->admin = $admin; } /** - * @return string + * @return \Thelia\Model\Admin */ - public function getLogin() + public function getAdmin() { - return $this->login; + return $this->admin; } + + } \ No newline at end of file diff --git a/local/modules/Cheque/Config/config.xml b/local/modules/Cheque/Config/config.xml index 2430f5027..cac3f6b7b 100755 --- a/local/modules/Cheque/Config/config.xml +++ b/local/modules/Cheque/Config/config.xml @@ -1,4 +1,4 @@ - +string Date: Wed, 30 Oct 2013 15:44:32 +0100 Subject: [PATCH 28/59] Combination creation management --- core/lib/Thelia/Action/Attribute.php | 2 +- core/lib/Thelia/Action/Feature.php | 2 +- core/lib/Thelia/Action/ProductSaleElement.php | 90 +++++++- core/lib/Thelia/Config/Resources/config.xml | 2 + .../Thelia/Config/Resources/routing/admin.xml | 4 + .../Controller/Admin/FeatureController.php | 17 -- .../Controller/Admin/ProductController.php | 104 +++++++++ .../ProductCombinationGenerationEvent.php | 159 +++++++++++++ core/lib/Thelia/Core/Event/TheliaEvents.php | 2 + .../Template/Loop/AttributeAvailability.php | 19 +- .../Core/Template/Smarty/Plugins/Form.php | 29 ++- .../Form/ProductCombinationGenerationForm.php | 91 ++++++++ .../ProductDefaultSaleElementUpdateForm.php | 4 +- .../Form/ProductSaleElementUpdateForm.php | 4 +- core/lib/Thelia/Model/Attribute.php | 2 +- core/lib/Thelia/Model/Feature.php | 2 +- core/lib/Thelia/Model/Product.php | 15 +- .../default/assets/less/thelia/modals.less | 15 ++ .../default/includes/generic-js-dialog.html | 7 + .../default/includes/product-details-tab.html | 217 ++++++++++++++++-- templates/admin/default/product-edit.html | 56 +++++ 21 files changed, 766 insertions(+), 77 deletions(-) create mode 100644 core/lib/Thelia/Core/Event/Product/ProductCombinationGenerationEvent.php create mode 100644 core/lib/Thelia/Form/ProductCombinationGenerationForm.php diff --git a/core/lib/Thelia/Action/Attribute.php b/core/lib/Thelia/Action/Attribute.php index 7db04518a..30ceea0e8 100644 --- a/core/lib/Thelia/Action/Attribute.php +++ b/core/lib/Thelia/Action/Attribute.php @@ -63,7 +63,7 @@ class Attribute extends BaseAction implements EventSubscriberInterface // Add atribute to all product templates if required if ($event->getAddToAllTemplates() != 0) { - // TODO: add to all product template + $this->doAddToAllTemplates($attribute); } } diff --git a/core/lib/Thelia/Action/Feature.php b/core/lib/Thelia/Action/Feature.php index 6ae7645e3..36853f444 100644 --- a/core/lib/Thelia/Action/Feature.php +++ b/core/lib/Thelia/Action/Feature.php @@ -63,7 +63,7 @@ class Feature extends BaseAction implements EventSubscriberInterface // Add atribute to all product templates if required if ($event->getAddToAllTemplates() != 0) { - // TODO: add to all product template + $this->doAddToAllTemplates($feature); } } diff --git a/core/lib/Thelia/Action/ProductSaleElement.php b/core/lib/Thelia/Action/ProductSaleElement.php index 8349eb1bf..9c40025d8 100644 --- a/core/lib/Thelia/Action/ProductSaleElement.php +++ b/core/lib/Thelia/Action/ProductSaleElement.php @@ -40,6 +40,8 @@ use Thelia\Model\AttributeAvQuery; use Thelia\Model\Currency; use Thelia\Model\Map\AttributeCombinationTableMap; use Propel\Runtime\ActiveQuery\Criteria; +use Thelia\Core\Event\Product\ProductCombinationGenerationEvent; +use Propel\Runtime\Connection\ConnectionInterface; class ProductSaleElement extends BaseAction implements EventSubscriberInterface { @@ -65,7 +67,7 @@ class ProductSaleElement extends BaseAction implements EventSubscriberInterface if ($salesElement == null) { // Create a new default product sale element - $salesElement = $event->getProduct()->createDefaultProductSaleElement($con, 0, 0, $event->getCurrencyId(), true); + $salesElement = $event->getProduct()->createDefaultProductSaleElement($con, 0, 0, 0, $event->getCurrencyId(), true); } else { // This (new) one is the default $salesElement->setIsDefault(true)->save($con); @@ -87,7 +89,7 @@ class ProductSaleElement extends BaseAction implements EventSubscriberInterface ->setAttributeAvId($attributeAvId) ->setAttribute($attributeAv->getAttribute()) ->setProductSaleElements($salesElement) - ->save(); + ->save($con); } } } @@ -206,8 +208,9 @@ class ProductSaleElement extends BaseAction implements EventSubscriberInterface if ($product->countSaleElements() <= 0) { // If we just deleted the last PSE, create a default one - $product->createDefaultProductSaleElement($con, 0, 0, $event->getCurrencyId(), true); - } elseif ($pse->getIsDefault()) { + $product->createProductSaleElement($con, 0, 0, 0, $event->getCurrencyId(), true); + } + elseif ($pse->getIsDefault()) { // If we deleted the default PSE, make the last created one the default $pse = ProductSaleElementsQuery::create() @@ -230,6 +233,83 @@ class ProductSaleElement extends BaseAction implements EventSubscriberInterface } } + /** + * Generate combinations. All existing combinations for the product are deleted. + * + * @param ProductCombinationGenerationEvent $event + */ + public function generateCombinations(ProductCombinationGenerationEvent $event) { + + $con = Propel::getWriteConnection(ProductSaleElementsTableMap::DATABASE_NAME); + + $con->beginTransaction(); + + try { + + // Delete all product's productSaleElement + ProductSaleElementsQuery::create()->filterByProductId($event->product->getId())->delete(); + + $isDefault = true; + + // Create all combinations + foreach($event->getCombinations() as $combinationAttributesAvIds) { + + // Create the PSE + $saleElement = $event->getProduct()->createProductSaleElement( + $con, + $event->getWeight(), + $event->getPrice(), + $event->getSalePrice(), + $event->getCurrencyId(), + $isDefault, + $event->getOnsale(), + $event->getIsnew(), + $event->getQuantity(), + $event->getEanCode(), + $event->getReference() + ); + + $isDefault = false; + + $this->createCombination($con, $saleElement, $combinationAttributesAvIds); + } + + // Store all the stuff ! + $con->commit(); + } + catch (\Exception $ex) { + + $con->rollback(); + + throw $ex; + } + } + + /** + * Create a combination for a given product sale element + * + * @param ConnectionInterface $con the Propel connection + * @param ProductSaleElement $salesElement the product sale element + * @param unknown $combinationAttributes an array oif attributes av IDs + */ + protected function createCombination(ConnectionInterface $con, ProductSaleElements $salesElement, $combinationAttributes) + { + foreach ($combinationAttributes as $attributeAvId) { + + $attributeAv = AttributeAvQuery::create()->findPk($attributeAvId); + + if ($attributeAv !== null) { + $attributeCombination = new AttributeCombination(); + + $attributeCombination + ->setAttributeAvId($attributeAvId) + ->setAttribute($attributeAv->getAttribute()) + ->setProductSaleElements($salesElement) + ->save($con); + } + } + } + /** * {@inheritDoc} */ @@ -239,6 +319,8 @@ class ProductSaleElement extends BaseAction implements EventSubscriberInterface TheliaEvents::PRODUCT_ADD_PRODUCT_SALE_ELEMENT => array("create", 128), TheliaEvents::PRODUCT_UPDATE_PRODUCT_SALE_ELEMENT => array("update", 128), TheliaEvents::PRODUCT_DELETE_PRODUCT_SALE_ELEMENT => array("delete", 128), + TheliaEvents::PRODUCT_COMBINATION_GENERATION => array("generateCombinations", 128), + ); } } diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index c0af99896..84e9ef92e 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -90,6 +90,8 @@
+ + diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index dc5a2c522..64bf37541 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -372,6 +372,10 @@ Thelia\Controller\Admin\ProductController::updateProductSaleElementsAction + + Thelia\Controller\Admin\ProductController::buildCombinationsAction + + Thelia\Controller\Admin\ProductController::updateProductDefaultSaleElementAction diff --git a/core/lib/Thelia/Controller/Admin/FeatureController.php b/core/lib/Thelia/Controller/Admin/FeatureController.php index 7696b9c6e..1be5dfeec 100644 --- a/core/lib/Thelia/Controller/Admin/FeatureController.php +++ b/core/lib/Thelia/Controller/Admin/FeatureController.php @@ -157,23 +157,6 @@ class FeatureController extends AbstractCrudController 'postscriptum' => $object->getPostscriptum() ); - // Setup features values - /* - * FIXME : doesn't work. "We get a This form should not contain extra fields." error - $attr_av_list = FeatureAvQuery::create() - ->joinWithI18n($this->getCurrentEditionLocale()) - ->filterByFeatureId($object->getId()) - ->find(); - - $attr_array = array(); - - foreach ($attr_av_list as $attr_av) { - $attr_array[$attr_av->getId()] = $attr_av->getTitle(); - } - - $data['feature_values'] = $attr_array; - */ - // Setup the object form return new FeatureModificationForm($this->getRequest(), "form", $data); } diff --git a/core/lib/Thelia/Controller/Admin/ProductController.php b/core/lib/Thelia/Controller/Admin/ProductController.php index 84e16815d..5540c529b 100644 --- a/core/lib/Thelia/Controller/Admin/ProductController.php +++ b/core/lib/Thelia/Controller/Admin/ProductController.php @@ -64,6 +64,8 @@ use Thelia\Model\Country; use Thelia\Tools\NumberFormat; use Thelia\Model\Product; use Thelia\Model\CurrencyQuery; +use Thelia\Form\ProductCombinationGenerationForm; +use Thelia\Core\Event\Product\ProductCombinationGenerationEvent; /** * Manages products @@ -1025,6 +1027,108 @@ class ProductController extends AbstractCrudController ); } + // Create combinations + protected function combine($input, &$output, &$tmp) { + $current = array_shift($input); + + if (count($input) > 0) { + foreach($current as $element) { + $tmp[] = $element; + $this->combine($input, $output, $tmp); + array_pop($tmp); + } + } else { + foreach($current as $element) { + $tmp[] = $element; + $output[] = $tmp; + array_pop($tmp); + } + } + } + + /** + * Build combinations from the combination output builder + */ + public function buildCombinationsAction() { + + // Check current user authorization + if (null !== $response = $this->checkAuth($this->resourceCode, AccessManager::UPDATE)) return $response; + + $error_msg = false; + + $changeForm = new ProductCombinationGenerationForm($this->getRequest()); + + try { + + // Check the form against constraints violations + $form = $this->validateForm($changeForm, "POST"); + + // Get the form field values + $data = $form->getData(); + + // Rework attributes_av array, to build an array which contains all combinations, + // in the form combination[] = array of combination attributes av IDs + // + // First, create an array of attributes_av ID in the form $attributes_av_list[$attribute_id] = array of attributes_av ID + // from the list of attribute_id:attributes_av ID from the form. + $combinations = $attributes_av_list = array(); + + foreach($data['attribute_av'] as $item) { + list($attribute_id, $attribute_av_id) = explode(':', $item); + + if (! isset($attributes_av_list[$attribute_id])) + $attributes_av_list[$attribute_id] = array(); + + + $attributes_av_list[$attribute_id][] = $attribute_av_id; + } + + // Next, recursively combine array + $combinations = $tmp = array(); + + $this->combine($attributes_av_list, $combinations, $tmp); + + // Create event + $event = new ProductCombinationGenerationEvent( + $this->getExistingObject(), + $data['currency'], + $combinations + ); + + $event + ->setReference($data['reference'] == null ? '' : $data['reference']) + ->setPrice($data['price'] == null ? 0 : $data['price']) + ->setWeight($data['weight'] == null ? 0 : $data['weight']) + ->setQuantity($data['quantity'] == null ? 0 : $data['quantity']) + ->setSalePrice($data['sale_price'] == null ? 0 : $data['sale_price']) + ->setOnsale($data['onsale'] == null ? false : $data['onsale']) + ->setIsnew($data['isnew'] == null ? false : $data['isnew']) + ->setEanCode($data['ean_code'] == null ? '' : $data['ean_code']) + ; + + $this->dispatch(TheliaEvents::PRODUCT_COMBINATION_GENERATION, $event); + + // Log object modification + $this->adminLogAppend(sprintf("Combination generation for product reference %s", $event->getProduct()->getRef())); + + // Redirect to the success URL + $this->redirect($changeForm->getSuccessUrl()); + + } catch (FormValidationException $ex) { + // Form cannot be validated + $error_msg = $this->createStandardFormValidationErrorMessage($ex); + } catch (\Exception $ex) { + // Any other error + $error_msg = $ex->getMessage(); + } + + $this->setupFormErrorContext( + $this->getTranslator()->trans("Combination builder"), $error_msg, $changeForm, $ex); + + // At this point, the form has errors, and should be redisplayed. + return $this->renderEditionTemplate(); + } + /** * Invoked through Ajax; this method calculates the taxed price from the unaxed price, and * vice versa. diff --git a/core/lib/Thelia/Core/Event/Product/ProductCombinationGenerationEvent.php b/core/lib/Thelia/Core/Event/Product/ProductCombinationGenerationEvent.php new file mode 100644 index 000000000..05b55d733 --- /dev/null +++ b/core/lib/Thelia/Core/Event/Product/ProductCombinationGenerationEvent.php @@ -0,0 +1,159 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event\Product; +use Thelia\Model\Product; + +class ProductCombinationGenerationEvent extends ProductEvent +{ + protected $reference; + protected $price; + protected $currency_id; + protected $weight; + protected $quantity; + protected $sale_price; + protected $onsale; + protected $isnew; + protected $ean_code; + protected $combinations; + + public function __construct(Product $product, $currency_id, $combinations) + { + parent::__construct($product); + + $this->setCombinations($combinations); + $this->setCurrencyId($currency_id); + } + + public function getCurrencyId() + { + return $this->currency_id; + } + + public function setCurrencyId($currency_id) + { + $this->currency_id = $currency_id; + + return $this; + } + + public function getReference() + { + return $this->reference; + } + + public function setReference($reference) + { + $this->reference = $reference; + return $this; + } + + public function getPrice() + { + return $this->price; + } + + public function setPrice($price) + { + $this->price = $price; + return $this; + } + + public function getWeight() + { + return $this->weight; + } + + public function setWeight($weight) + { + $this->weight = $weight; + return $this; + } + + public function getQuantity() + { + return $this->quantity; + } + + public function setQuantity($quantity) + { + $this->quantity = $quantity; + return $this; + } + + public function getSalePrice() + { + return $this->sale_price; + } + + public function setSalePrice($sale_price) + { + $this->sale_price = $sale_price; + return $this; + } + + public function getOnsale() + { + return $this->onsale; + } + + public function setOnsale($onsale) + { + $this->onsale = $onsale; + return $this; + } + + public function getIsnew() + { + return $this->isnew; + } + + public function setIsnew($isnew) + { + $this->isnew = $isnew; + return $this; + } + + public function getEanCode() + { + return $this->ean_code; + } + + public function setEanCode($ean_code) + { + $this->ean_code = $ean_code; + return $this; + return $this; + } + + public function getCombinations() + { + return $this->combinations; + } + + public function setCombinations($combinations) + { + $this->combinations = $combinations; + return $this; + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/TheliaEvents.php b/core/lib/Thelia/Core/Event/TheliaEvents.php index 42b20d8cd..dfd2d27aa 100755 --- a/core/lib/Thelia/Core/Event/TheliaEvents.php +++ b/core/lib/Thelia/Core/Event/TheliaEvents.php @@ -285,6 +285,8 @@ final class TheliaEvents const PRODUCT_DELETE_PRODUCT_SALE_ELEMENT = "action.deleteProductSaleElement"; const PRODUCT_UPDATE_PRODUCT_SALE_ELEMENT = "action.updateProductSaleElement"; + const PRODUCT_COMBINATION_GENERATION = "action.productCombineationGeneration"; + const PRODUCT_SET_TEMPLATE = "action.productSetTemplate"; const PRODUCT_ADD_ACCESSORY = "action.productAddProductAccessory"; diff --git a/core/lib/Thelia/Core/Template/Loop/AttributeAvailability.php b/core/lib/Thelia/Core/Template/Loop/AttributeAvailability.php index e9a7d9eb8..10c1dda00 100755 --- a/core/lib/Thelia/Core/Template/Loop/AttributeAvailability.php +++ b/core/lib/Thelia/Core/Template/Loop/AttributeAvailability.php @@ -128,14 +128,17 @@ class AttributeAvailability extends BaseI18nLoop foreach ($attributesAv as $attributeAv) { $loopResultRow = new LoopResultRow($loopResult, $attributeAv, $this->versionable, $this->timestampable, $this->countable); - $loopResultRow->set("ID", $attributeAv->getId()) - ->set("IS_TRANSLATED",$attributeAv->getVirtualColumn('IS_TRANSLATED')) - ->set("LOCALE",$locale) - ->set("TITLE",$attributeAv->getVirtualColumn('i18n_TITLE')) - ->set("CHAPO", $attributeAv->getVirtualColumn('i18n_CHAPO')) - ->set("DESCRIPTION", $attributeAv->getVirtualColumn('i18n_DESCRIPTION')) - ->set("POSTSCRIPTUM", $attributeAv->getVirtualColumn('i18n_POSTSCRIPTUM')) - ->set("POSITION", $attributeAv->getPosition()); + $loopResultRow + ->set("ID" , $attributeAv->getId()) + ->set("ATTRIBUTE_ID" , $attributeAv->getAttributeId()) + ->set("IS_TRANSLATED", $attributeAv->getVirtualColumn('IS_TRANSLATED')) + ->set("LOCALE" , $locale) + ->set("TITLE" , $attributeAv->getVirtualColumn('i18n_TITLE')) + ->set("CHAPO" , $attributeAv->getVirtualColumn('i18n_CHAPO')) + ->set("DESCRIPTION" , $attributeAv->getVirtualColumn('i18n_DESCRIPTION')) + ->set("POSTSCRIPTUM" , $attributeAv->getVirtualColumn('i18n_POSTSCRIPTUM')) + ->set("POSITION" , $attributeAv->getPosition()) + ; $loopResult->addRow($loopResultRow); } diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php index 494e219eb..ee49fe1ec 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php @@ -199,30 +199,29 @@ class Form extends AbstractSmartyPlugin { if ($repeat) { - $formFieldView = $this->getFormFieldView($params); - $formFieldConfig = $this->getFormFieldConfig($params); + $formFieldView = $this->getFormFieldView($params); + $formFieldConfig = $this->getFormFieldConfig($params); - $this->assignFormTypeValues($template, $formFieldConfig, $formFieldView); + $this->assignFormTypeValues($template, $formFieldConfig, $formFieldView); $value = $formFieldView->vars["value"]; - // We have a collection - if (0 < $value_count = count($formFieldView->children)) { + $key = $this->getParam($params, 'value_key', null); - $key = $this->getParam($params, 'value_key', null); + // We (may) have a collection + if ($key !== null) { - if ($key !== null) { - // If the field is not found, use an empty value - $val = array_key_exists($key, $value) ? $value[$key] : ''; + // Force array + if (! is_array($value)) $value = array(); - $name = sprintf("%s[%s]", $formFieldView->vars["full_name"], $key); + // If the field is not found, use an empty value + $val = array_key_exists($key, $value) ? $value[$key] : ''; - $val = $value[$key]; + $name = sprintf("%s[%s]", $formFieldView->vars["full_name"], $key); - $this->assignFieldValues($template, $name, $val, $formFieldView->vars, $value_count); - } else { - throw new \InvalidArgumentException(sprintf("Missing or empty parameter 'value_key' for field '%s'", $formFieldView->vars["name"])); - } + $val = $value[$key]; + + $this->assignFieldValues($template, $name, $val, $formFieldView->vars, count($formFieldView->children)); } else { $this->assignFieldValues($template, $formFieldView->vars["full_name"], $formFieldView->vars["value"], $formFieldView->vars); } diff --git a/core/lib/Thelia/Form/ProductCombinationGenerationForm.php b/core/lib/Thelia/Form/ProductCombinationGenerationForm.php new file mode 100644 index 000000000..8e4b155b9 --- /dev/null +++ b/core/lib/Thelia/Form/ProductCombinationGenerationForm.php @@ -0,0 +1,91 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form; + +use Symfony\Component\Validator\Constraints\GreaterThan; +use Symfony\Component\Validator\Constraints\NotBlank; +use Thelia\Model\Currency; +use Thelia\Core\Translation\Translator; + +class ProductCombinationGenerationForm extends BaseForm +{ + protected function buildForm() + { + $this->formBuilder + ->add('product_id', 'integer', array( + 'label' => Translator::getInstance()->trans('Product ID'), + 'label_attr' => array('for' => 'combination_builder_id_field'), + 'constraints' => array(new GreaterThan(array('value' => 0))) + )) + ->add('currency', 'integer', array( + 'label' => Translator::getInstance()->trans('Price currency *'), + 'label_attr' => array('for' => 'combination_builder_currency_field'), + 'constraints' => array(new GreaterThan(array('value' => 0))) + )) + ->add('reference', 'text', array( + 'label' => Translator::getInstance()->trans('Reference'), + 'label_attr' => array('for' => 'combination_builder_reference_field') + )) + ->add('price', 'number', array( + 'label' => Translator::getInstance()->trans('Product price excluding taxes'), + 'label_attr' => array('for' => 'combination_builder_price_field') + )) + ->add('weight', 'number', array( + 'label' => Translator::getInstance()->trans('Weight'), + 'label_attr' => array('for' => 'combination_builder_weight_field') + )) + ->add('quantity', 'number', array( + 'label' => Translator::getInstance()->trans('Available quantity'), + 'label_attr' => array('for' => 'combination_builder_quantity_field') + )) + ->add('sale_price', 'number', array( + 'label' => Translator::getInstance()->trans('Sale price excluding taxes'), + 'label_attr' => array('for' => 'combination_builder_price_with_tax_field') + )) + ->add('onsale', 'integer', array( + 'label' => Translator::getInstance()->trans('This product is on sale'), + 'label_attr' => array('for' => 'combination_builder_onsale_field') + )) + ->add('isnew', 'integer', array( + 'label' => Translator::getInstance()->trans('Advertise this product as new'), + 'label_attr' => array('for' => 'combination_builder_isnew_field') + )) + ->add('ean_code', 'text', array( + 'label' => Translator::getInstance()->trans('EAN Code'), + 'label_attr' => array('for' => 'combination_builder_ean_code_field') + )) + ->add('attribute_av', 'collection', array( + 'type' => 'text', + 'label' => Translator::getInstance()->trans('Attribute ID:Attribute AV ID'), + 'label_attr' => array('for' => 'combination_builder_attribute_av_id'), + 'allow_add' => true, + 'allow_delete' => true, + )) + ; + } + + public function getName() + { + return 'thelia_product_combination_generation_form'; + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Form/ProductDefaultSaleElementUpdateForm.php b/core/lib/Thelia/Form/ProductDefaultSaleElementUpdateForm.php index 2643692a2..54fb2fdc1 100644 --- a/core/lib/Thelia/Form/ProductDefaultSaleElementUpdateForm.php +++ b/core/lib/Thelia/Form/ProductDefaultSaleElementUpdateForm.php @@ -29,8 +29,6 @@ use Thelia\Core\Translation\Translator; class ProductDefaultSaleElementUpdateForm extends ProductSaleElementUpdateForm { - use StandardDescriptionFieldsTrait; - protected function buildForm() { $this->formBuilder @@ -77,7 +75,7 @@ class ProductDefaultSaleElementUpdateForm extends ProductSaleElementUpdateForm "label_attr" => array("for" => "quantity_field") )) ->add("sale_price", "number", array( - "label" => Translator::getInstance()->trans("Sale price without taxes"), + "label" => Translator::getInstance()->trans("Sale price excluding taxes"), "label_attr" => array("for" => "price_with_tax_field") )) ->add("sale_price_with_tax", "number", array( diff --git a/core/lib/Thelia/Form/ProductSaleElementUpdateForm.php b/core/lib/Thelia/Form/ProductSaleElementUpdateForm.php index da831545a..cda72cc72 100644 --- a/core/lib/Thelia/Form/ProductSaleElementUpdateForm.php +++ b/core/lib/Thelia/Form/ProductSaleElementUpdateForm.php @@ -29,8 +29,6 @@ use Thelia\Core\Translation\Translator; class ProductSaleElementUpdateForm extends BaseForm { - use StandardDescriptionFieldsTrait; - protected function buildForm() { $this->formBuilder @@ -112,7 +110,7 @@ class ProductSaleElementUpdateForm extends BaseForm ) )) ->add('sale_price', 'collection', array( - 'label' => Translator::getInstance()->trans('Sale price without taxes'), + 'label' => Translator::getInstance()->trans('Sale price excluding taxes'), 'label_attr' => array('for' => 'price_with_tax_field'), 'allow_add' => true, 'allow_delete' => true, diff --git a/core/lib/Thelia/Model/Attribute.php b/core/lib/Thelia/Model/Attribute.php index 615fa643e..3439cac06 100755 --- a/core/lib/Thelia/Model/Attribute.php +++ b/core/lib/Thelia/Model/Attribute.php @@ -20,7 +20,7 @@ class Attribute extends BaseAttribute { $this->dispatchEvent(TheliaEvents::BEFORE_CREATEATTRIBUTE, new AttributeEvent($this)); // Set the current position for the new object - //$this->setPosition($this->getNextPosition()); + $this->setPosition($this->getNextPosition()); return true; } diff --git a/core/lib/Thelia/Model/Feature.php b/core/lib/Thelia/Model/Feature.php index 800ff832a..2627d5190 100755 --- a/core/lib/Thelia/Model/Feature.php +++ b/core/lib/Thelia/Model/Feature.php @@ -20,7 +20,7 @@ class Feature extends BaseFeature { $this->dispatchEvent(TheliaEvents::BEFORE_CREATEFEATURE, new FeatureEvent($this)); // Set the current position for the new object - //$this->setPosition($this->getNextPosition()); + $this->setPosition($this->getNextPosition()); return true; } diff --git a/core/lib/Thelia/Model/Product.php b/core/lib/Thelia/Model/Product.php index f16a8a776..1b3f1eefa 100755 --- a/core/lib/Thelia/Model/Product.php +++ b/core/lib/Thelia/Model/Product.php @@ -167,7 +167,7 @@ class Product extends BaseProduct $this->setTaxRuleId($taxRuleId); // Create the default product sale element of this product - $sale_elements = $this->createDefaultProductSaleElement($con, $baseWeight, $basePrice, $priceCurrencyId, true); + $sale_elements = $this->createProductSaleElement($con, $baseWeight, $basePrice, $basePrice, $priceCurrencyId, true); // Store all the stuff ! $con->commit(); @@ -185,19 +185,20 @@ class Product extends BaseProduct /** * Create a basic product sale element attached to this product. */ - public function createDefaultProductSaleElement(ConnectionInterface $con, $weight, $basePrice, $currencyId, $isDefault) { + public function createProductSaleElement(ConnectionInterface $con, $weight, $basePrice, $salePrice, $currencyId, $isDefault, $isPromo = false, $isNew = false, $quantity = 0, $eanCode = '', $ref = false) { // Create an empty product sale element $sale_elements = new ProductSaleElements(); $sale_elements ->setProduct($this) - ->setRef($this->getRef()) - ->setPromo(0) - ->setNewness(0) + ->setRef($ref == false ? $this->getRef() : $ref) + ->setPromo($isPromo) + ->setNewness($isNew) ->setWeight($weight) ->setIsDefault($isDefault) - ->setEanCode('') + ->setEanCode($eanCode) + ->setQuantity($quantity) ->save($con) ; @@ -206,7 +207,7 @@ class Product extends BaseProduct $product_price ->setProductSaleElements($sale_elements) - ->setPromoPrice($basePrice) + ->setPromoPrice($salePrice) ->setPrice($basePrice) ->setCurrencyId($currencyId) ->save($con) diff --git a/templates/admin/default/assets/less/thelia/modals.less b/templates/admin/default/assets/less/thelia/modals.less index 2d371e6c0..ee6b3c662 100755 --- a/templates/admin/default/assets/less/thelia/modals.less +++ b/templates/admin/default/assets/less/thelia/modals.less @@ -9,7 +9,22 @@ } } +.modal-header { + h3 { + margin-bottom: 0; + } +} + // Body (where all modal content resides) .modal-body { max-height: none; + .scrollable { + border: 1px solid @input-border; + border-radius: @input-border-radius; + height: 458px; + overflow: auto; + padding-bottom: 5px; + padding-left: 10px; + padding-top: 5px; + } } \ No newline at end of file diff --git a/templates/admin/default/includes/generic-js-dialog.html b/templates/admin/default/includes/generic-js-dialog.html index 891bb0957..f12a64664 100644 --- a/templates/admin/default/includes/generic-js-dialog.html +++ b/templates/admin/default/includes/generic-js-dialog.html @@ -30,6 +30,13 @@ $('#{$dialog_id}').on('hidden.bs.modal', function() { // Clear error status $("#{$dialog_id} .error").removeClass('error'); + $('#{$dialog_id} .form-group').removeClass('has-error') + // Empty field values $("#{$dialog_id} input[type=text], #{$dialog_id} select").val(''); + + // Uncheck boxes + $("#{$dialog_id} input[type=checkbox]").removeAttr('checked'); + + {$additionnal_js_code|default:''} }); \ No newline at end of file diff --git a/templates/admin/default/includes/product-details-tab.html b/templates/admin/default/includes/product-details-tab.html index 67b20ab77..096b0a7e7 100644 --- a/templates/admin/default/includes/product-details-tab.html +++ b/templates/admin/default/includes/product-details-tab.html @@ -26,9 +26,8 @@ close_url = "{url path='/admin/categories' category_id=$DEFAULT_CATEGORY}" } - {* Be sure to get the product ID, even if the form could not be validated *} + {* Be sure to get the product ID and current tab, even if the form could not be validated *} - {form_hidden_fields form=$form} @@ -177,8 +176,6 @@ {/form_field} - {module_include location='product_details_shipping_form'} - {form_field form=$form field='quantity'}
@@ -189,7 +186,7 @@
{/form_field} - {module_include location='product_details_quantity_form'} + {module_include location='product_details_details_form'} @@ -268,9 +265,8 @@ close_url = "{url path='/admin/categories' category_id=$DEFAULT_CATEGORY}" } - {* Be sure to get the product ID, even if the form could not be validated *} + {* Be sure to get the product ID and current tab, even if the form could not be validated *} - {form_hidden_fields form=$form} @@ -340,7 +336,7 @@ {module_include location='product_combinations_list_caption'} {loop type="auth" name="can_create" role="ADMIN" resource="admin.product" access="UPDATE"} - + {intl l='Combination builder'} @@ -358,8 +354,8 @@
+ - @@ -375,18 +371,20 @@ {for $idx = 0 to $total_value_count-1} - + + @@ -469,10 +467,16 @@

{intl l='Attribute Combinations'}

- {intl - l='This product has no combination. The default price is used. Click here to create a new combination' - url='#combination_creation_dialog' - } +

{intl + l='This product has no combination. The default price is used. Click here to create a new combination.' + url='#combination_creation_dialog' + }

+

+ {intl + l='You may also quickly create combinations from products attributes using the Combination Builder.' + url='#combination_builder_dialog' + } +

@@ -494,7 +498,7 @@ @@ -583,3 +587,184 @@ form_action = {url path='/admin/product/combination/delete'} form_content = {$smarty.capture.combination_delete_dialog nofilter} } + +{* -- Combination builder dialog -------------------------------------------- *} + +{* Capture the dialog body, to pass it to the generic dialog *} + +{form name="thelia.admin.product_combination.build"} + +{capture "combination_builder_dialog"} + + {* Be sure to get the product ID and current tab, even if the form could not be validated *} + + + + {form_hidden_fields form=$form} + + {form_field form=$form field='product_id'} + + {/form_field} + + {if $form_error}
{$form_error_message}
{/if} + + {loop type="currency" name="get-currency-symbol" id=$edit_currency_id backend_context="1"} + {$currency_symbol = $SYMBOL} + + {form_field form=$form field='currency'} + + {/form_field} + {/loop} + + {form_field form=$form field='success_url'} + + {/form_field} + +
+ {intl l='Select attribute values to combine. You may enter a default value for some of the fields of the generated combinations.'} +
+ +
+
+
+
    + {$index = 0} + {loop name="product-attributes" type="attribute" order="manual" product=$product_id backend_context="1" lang=$edit_language_id} + {ifloop rel="product-attributes-av"} +
  • + {$TITLE} +
      + {loop name="product-attributes-av" type="attribute_availability" attribute="{$ID}" order="manual" backend_context="1" lang=$edit_language_id} +
    • +
      + +
      +
    • + {$index = $index + 1} + {/loop} +
    +
  • + {/ifloop} + {/loop} +
+
+
+ +
+ {form_field form=$form field='price'} +
+ + +
+ + {$currency_symbol} +
+
+ {/form_field} + + {form_field form=$form field='reference'} +
+ + +
+ +
+
+ {/form_field} + + {form_field form=$form field='ean_code'} +
+ + +
+ +
+
+ {/form_field} + +
+
+ {form_field form=$form field='weight'} +
+ + +
+ + {intl l="Kg"} +
+
+ {/form_field} +
+ +
+ {form_field form=$form field='quantity'} +
+ + +
+ +
+
+ {/form_field} +
+
+ + {form_field form=$form field='sale_price'} +
+ +
+ + {$currency_symbol} +
+
+ {/form_field} + + {form_field form=$form field='onsale'} +
+
+ +
+
+ {/form_field} + + {form_field form=$form field='isnew'} +
+
+ +
+
+ {/form_field} + +
{intl l='0 combinations'}
+
+
+ +{/capture} + +{include + file = "includes/generic-create-dialog.html" + + dialog_id = "combination_builder_dialog" + dialog_title = {intl l="Create combinations"} + dialog_body = {$smarty.capture.combination_builder_dialog nofilter} + + dialog_ok_label = {intl l="Create combinations"} + + form_action = {url path='/admin/product/combination/build'} + form_enctype = {form_enctype form=$form} + form_error_message = '' + + ok_button_id = "combination_builder_dialog_ok" +} + +{/form} diff --git a/templates/admin/default/product-edit.html b/templates/admin/default/product-edit.html index 446e1fd7f..184fb916b 100644 --- a/templates/admin/default/product-edit.html +++ b/templates/admin/default/product-edit.html @@ -344,6 +344,21 @@ $(function() { } } + // -- Combination builder stuff -------------------------------------------- + + $('#open_combination_builder').click(function(ev) { + if (! confirm("{intl l='Existing combiations will be deleted. Do you want to continue ?'}'")) { + ev.preventDefault(); + ev.stopPropagation(); + } + }); + + {include + file = "includes/generic-js-dialog.html" + dialog_id = "combination_builder_dialog" + form_name = "thelia.admin.product_combination.build" + } + // Automatic update of price fields: any change in the taxed (resp. untaxed) price // will update the untaxed (resp. taxed) one $('.automatic_price_field').typeWatch({ @@ -353,6 +368,47 @@ $(function() { update_price($(this).val(), $(this).data('price-type'), $(this).data('rel-price')); } }); + + // Count generated combinations in real time + function countGeneratedCombinations() { + + var total = 0; + + var counter = {}; + + var list = $('.attribute_av_value:checked'); + + if (list.length > 0) { + console.log("ok !"); + + list.each(function() { + var attr_id = $(this).data('attribute-id'); + + console.log("att="+attr_id); + + if (undefined != counter[attr_id]) + counter[attr_id]++; + else + counter[attr_id] = 1; + }); + + console.log(counter); + + total = 1; + + for(var count in counter) { + total *= counter[count]; + } + } + + return total; + } + + $('.attribute_av_value').change(function(ev) { + var total = countGeneratedCombinations(); + + $('#number_of_generated_combinations').text(total); + }); }); From 9f11f475eeaf3d7b95a579f1e605779fc3536e46 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Wed, 30 Oct 2013 15:47:21 +0100 Subject: [PATCH 29/59] Typo --- templates/admin/default/product-edit.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/admin/default/product-edit.html b/templates/admin/default/product-edit.html index 184fb916b..e05bc7434 100644 --- a/templates/admin/default/product-edit.html +++ b/templates/admin/default/product-edit.html @@ -347,7 +347,7 @@ $(function() { // -- Combination builder stuff -------------------------------------------- $('#open_combination_builder').click(function(ev) { - if (! confirm("{intl l='Existing combiations will be deleted. Do you want to continue ?'}'")) { + if (! confirm("{intl l='Existing combinations will be deleted. Do you want to continue ?'}'")) { ev.preventDefault(); ev.stopPropagation(); } From 86d84462adb9432bb144a132fab66112341e661e Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Wed, 30 Oct 2013 16:13:06 +0100 Subject: [PATCH 30/59] clean some code in FileController --- .../Controller/Admin/FileController.php | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/core/lib/Thelia/Controller/Admin/FileController.php b/core/lib/Thelia/Controller/Admin/FileController.php index 38b8d74fb..ced780181 100755 --- a/core/lib/Thelia/Controller/Admin/FileController.php +++ b/core/lib/Thelia/Controller/Admin/FileController.php @@ -136,9 +136,9 @@ class FileController extends BaseAdminController $this->container->get('thelia.translator')->trans( 'Saving images for %parentName% parent id %parentId% (%parentType%)', array( - '%parentName%' => $event->getParentName(), - '%parentId%' => $event->getParentId(), - '%parentType%' => $event->getImageType() + '%parentName%' => $imageCreateOrUpdateEvent->getParentName(), + '%parentId%' => $imageCreateOrUpdateEvent->getParentId(), + '%parentType%' => $imageCreateOrUpdateEvent->getImageType() ), 'image' ) @@ -214,9 +214,9 @@ class FileController extends BaseAdminController $this->container->get('thelia.translator')->trans( 'Saving documents for %parentName% parent id %parentId% (%parentType%)', array( - '%parentName%' => $event->getParentName(), - '%parentId%' => $event->getParentId(), - '%parentType%' => $event->getDocumentType() + '%parentName%' => $documentCreateOrUpdateEvent->getParentName(), + '%parentId%' => $documentCreateOrUpdateEvent->getParentId(), + '%parentType%' => $documentCreateOrUpdateEvent->getDocumentType() ), 'document' ) @@ -549,8 +549,8 @@ class FileController extends BaseAdminController $this->container->get('thelia.translator')->trans( 'Deleting image for %id% with parent id %parentId%', array( - '%id%' => $event->getDocumentToDelete()->getId(), - '%parentId%' => $event->getDocumentToDelete()->getParentId(), + '%id%' => $imageDeleteEvent->getImageToDelete()->getId(), + '%parentId%' => $imageDeleteEvent->getImageToDelete()->getParentId(), ), 'image' ) @@ -562,8 +562,8 @@ class FileController extends BaseAdminController $this->container->get('thelia.translator')->trans( 'Fail to delete image for %id% with parent id %parentId% (Exception : %e%)', array( - '%id%' => $event->getDocumentToDelete()->getId(), - '%parentId%' => $event->getDocumentToDelete()->getParentId(), + '%id%' => $imageDeleteEvent->getImageToDelete()->getId(), + '%parentId%' => $imageDeleteEvent->getImageToDelete()->getParentId(), '%e%' => $e->getMessage() ), 'image' @@ -621,8 +621,8 @@ class FileController extends BaseAdminController $this->container->get('thelia.translator')->trans( 'Deleting document for %id% with parent id %parentId%', array( - '%id%' => $event->getDocumentToDelete()->getId(), - '%parentId%' => $event->getDocumentToDelete()->getParentId(), + '%id%' => $documentDeleteEvent->getDocumentToDelete()->getId(), + '%parentId%' => $documentDeleteEvent->getDocumentToDelete()->getParentId(), ), 'document' ) @@ -634,8 +634,8 @@ class FileController extends BaseAdminController $this->container->get('thelia.translator')->trans( 'Fail to delete document for %id% with parent id %parentId% (Exception : %e%)', array( - '%id%' => $event->getDocumentToDelete()->getId(), - '%parentId%' => $event->getDocumentToDelete()->getParentId(), + '%id%' => $documentDeleteEvent->getDocumentToDelete()->getId(), + '%parentId%' => $documentDeleteEvent->getDocumentToDelete()->getParentId(), '%e%' => $e->getMessage() ), 'document' From 083dde5e930cd5a7c7413841f932ef00358571be Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Wed, 30 Oct 2013 16:32:24 +0100 Subject: [PATCH 31/59] admin home stats --- .../Thelia/Config/Resources/routing/admin.xml | 12 +++ .../Controller/Admin/HomeController.php | 102 ++++++++++++++++++ core/lib/Thelia/Model/CustomerQuery.php | 17 +++ core/lib/Thelia/Model/OrderQuery.php | 68 ++++++++++++ templates/admin/default/home.html | 20 ++-- 5 files changed, 209 insertions(+), 10 deletions(-) create mode 100644 core/lib/Thelia/Controller/Admin/HomeController.php diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index 046395fa9..e051fb3e5 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -9,6 +9,18 @@ Thelia\Controller\Admin\AdminController::indexAction + + + + Thelia\Controller\Admin\HomeController::defaultAction + + + + Thelia\Controller\Admin\HomeController::loadStatsAjaxAction + + + + Thelia\Controller\Admin\SessionController::showLoginAction diff --git a/core/lib/Thelia/Controller/Admin/HomeController.php b/core/lib/Thelia/Controller/Admin/HomeController.php new file mode 100644 index 000000000..90b0c6655 --- /dev/null +++ b/core/lib/Thelia/Controller/Admin/HomeController.php @@ -0,0 +1,102 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Controller\Admin; + +use Thelia\Core\Security\AccessManager; +use Thelia\Model\CustomerQuery; +use Thelia\Model\OrderQuery; + +class HomeController extends BaseAdminController +{ + const RESOURCE_CODE = "admin.home"; + + public function defaultAction() + { + if (null !== $response = $this->checkAuth(self::RESOURCE_CODE, AccessManager::VIEW)) return $response; + + // Render the edition template. + return $this->render('home'); + } + + public function loadStatsAjaxAction() + { + $data = new \stdClass(); + + $data->title = "Stats on [...]"; + + /* sales */ + $saleSeries = new \stdClass(); + $saleSeries->color = $this->getRequest()->request->get('sales_color', '#adadad'); + $saleSeries->data = OrderQuery::getSaleStats( + $this->getRequest()->request->get('month', date('m')), + $this->getRequest()->request->get('year', date('Y')) + ); + + /* new customers */ + $newCustomerSeries = new \stdClass(); + $newCustomerSeries->color = $this->getRequest()->request->get('customers_color', '#f39922'); + $newCustomerSeries->data = CustomerQuery::getNewCustomersStats( + $this->getRequest()->request->get('month', date('m')), + $this->getRequest()->request->get('year', date('Y')) + ); + + /* orders */ + $orderSeries = new \stdClass(); + $orderSeries->color = $this->getRequest()->request->get('orders_color', '#5cb85c'); + $orderSeries->data = OrderQuery::getOrdersStats( + $this->getRequest()->request->get('month', date('m')), + $this->getRequest()->request->get('year', date('Y')) + ); + + /* first order */ + $firstOrderSeries = new \stdClass(); + $firstOrderSeries->color = $this->getRequest()->request->get('first_orders_color', '#5bc0de'); + $firstOrderSeries->data = OrderQuery::getFirstOrdersStats( + $this->getRequest()->request->get('month', date('m')), + $this->getRequest()->request->get('year', date('Y')) + ); + + /* cancelled orders */ + $cancelledOrderSeries = new \stdClass(); + $cancelledOrderSeries->color = $this->getRequest()->request->get('cancelled_orders_color', '#d9534f'); + $cancelledOrderSeries->data = OrderQuery::getOrdersStats( + $this->getRequest()->request->get('month', date('m')), + $this->getRequest()->request->get('year', date('Y')), + array(5) + ); + + + $data->series = array( + $saleSeries, + $newCustomerSeries, + $orderSeries, + $firstOrderSeries, + $cancelledOrderSeries, + ); + + $json = json_encode($data); + + return $this->jsonResponse($json); + } +} diff --git a/core/lib/Thelia/Model/CustomerQuery.php b/core/lib/Thelia/Model/CustomerQuery.php index 359d072bd..5c225510b 100755 --- a/core/lib/Thelia/Model/CustomerQuery.php +++ b/core/lib/Thelia/Model/CustomerQuery.php @@ -2,6 +2,7 @@ namespace Thelia\Model; +use Propel\Runtime\ActiveQuery\Criteria; use Thelia\Model\Base\CustomerQuery as BaseCustomerQuery; @@ -21,4 +22,20 @@ class CustomerQuery extends BaseCustomerQuery { { return self::create()->findOneByEmail($email); } + + public static function getNewCustomersStats($month, $year) + { + $numberOfDay = cal_days_in_month(CAL_GREGORIAN, $month, $year); + + $stats = array(); + for($day=1; $day<=$numberOfDay; $day++) { + $dayCustomers = self::create() + ->filterByCreatedAt(sprintf("%s-%s-%s 00:00:00", $year, $month, $day), Criteria::GREATER_EQUAL) + ->filterByCreatedAt(sprintf("%s-%s-%s 23:59:59", $year, $month, $day), Criteria::LESS_EQUAL) + ->count(); + $stats[] = array($day-1, $dayCustomers); + } + + return $stats; + } } // CustomerQuery diff --git a/core/lib/Thelia/Model/OrderQuery.php b/core/lib/Thelia/Model/OrderQuery.php index 0fff5dba1..6eee6a81b 100755 --- a/core/lib/Thelia/Model/OrderQuery.php +++ b/core/lib/Thelia/Model/OrderQuery.php @@ -3,6 +3,7 @@ namespace Thelia\Model; use Propel\Runtime\ActiveQuery\Criteria; +use Propel\Runtime\ActiveQuery\Join; use Propel\Runtime\Exception\PropelException; use Propel\Runtime\Propel; use Thelia\Model\Base\OrderQuery as BaseOrderQuery; @@ -54,4 +55,71 @@ class OrderQuery extends BaseOrderQuery return $obj; } + public static function getSaleStats($month, $year) + { + $numberOfDay = cal_days_in_month(CAL_GREGORIAN, $month, $year); + + $stats = array(); + for($day=1; $day<=$numberOfDay; $day++) { + $dayAmount = 0; + foreach(self::create() + ->filterByStatusId(array(2,3,4), Criteria::IN) + ->filterByCreatedAt(sprintf("%s-%s-%s 00:00:00", $year, $month, $day), Criteria::GREATER_EQUAL) + ->filterByCreatedAt(sprintf("%s-%s-%s 23:59:59", $year, $month, $day), Criteria::LESS_EQUAL) + ->find() as $dayOrders) { + $dayAmount += $dayOrders->getTotalAmount(); + } + $stats[] = array($day-1, $dayAmount); + } + + return $stats; + } + + public static function getOrdersStats($month, $year, $status = null) + { + $numberOfDay = cal_days_in_month(CAL_GREGORIAN, $month, $year); + + $stats = array(); + for($day=1; $day<=$numberOfDay; $day++) { + $dayOrdersQuery = self::create() + ->filterByCreatedAt(sprintf("%s-%s-%s 00:00:00", $year, $month, $day), Criteria::GREATER_EQUAL) + ->filterByCreatedAt(sprintf("%s-%s-%s 23:59:59", $year, $month, $day), Criteria::LESS_EQUAL); + if(null !== $status) { + $dayOrdersQuery->filterByStatusId($status, Criteria::IN); + } + $dayOrders = $dayOrdersQuery->count(); + $stats[] = array($day-1, $dayOrders); + } + + return $stats; + } + + public static function getFirstOrdersStats($month, $year) + { + $numberOfDay = cal_days_in_month(CAL_GREGORIAN, $month, $year); + + $stats = array(); + for($day=1; $day<=$numberOfDay; $day++) { + $dayOrdersQuery = self::create('matching_order') + ->filterByCreatedAt(sprintf("%s-%s-%s 00:00:00", $year, $month, $day), Criteria::GREATER_EQUAL) + ->filterByCreatedAt(sprintf("%s-%s-%s 23:59:59", $year, $month, $day), Criteria::LESS_EQUAL); + + $otherOrderJoin = new Join(); + $otherOrderJoin->addExplicitCondition(OrderTableMap::TABLE_NAME, 'CUSTOMER_ID', 'matching_order', OrderTableMap::TABLE_NAME, 'CUSTOMER_ID', 'other_order'); + $otherOrderJoin->setJoinType(Criteria::LEFT_JOIN); + + $dayOrdersQuery->addJoinObject($otherOrderJoin, 'other_order_join') + ->addJoinCondition('other_order_join', '`matching_order`.`ID` <> `other_order`.`ID`') + ->addJoinCondition('other_order_join', '`matching_order`.`CREATED_AT` > `other_order`.`CREATED_AT`'); + + $dayOrdersQuery->where('ISNULL(`other_order`.`ID`)'); + + $dayOrders = $dayOrdersQuery->count(); + $stats[] = array($day-1, $dayOrders); + } + + return $stats; + } + + } // OrderQuery diff --git a/templates/admin/default/home.html b/templates/admin/default/home.html index 22989d8fb..0081eeebf 100755 --- a/templates/admin/default/home.html +++ b/templates/admin/default/home.html @@ -274,7 +274,7 @@ var $elem = $('#jqplot'); - var url = "{url file='/test_to_remove/admin-stats.json'}", + var url = "{url path='/admin/home/stats'}", series = [], seriesColors = [], ticks = [], @@ -318,12 +318,12 @@ } }; - // Get datas Json + // Get data Json $.getJSON(url) .done(function(data) { - // Init series datas and colors - initJqplotDatas(series, seriesColors, options, data); + // Init series data and colors + initJqplotData(series, seriesColors, options, data); // Add days to xaxis for(var i = 1; i < (days+1); i++){ @@ -350,8 +350,8 @@ series = []; seriesColors = []; - // Init series datas and colors - initJqplotDatas(series, seriesColors, options, data); + // Init series data and colors + initJqplotData(series, seriesColors, options, data); // Restart jqplot jqplot.destroy(); @@ -372,15 +372,15 @@ }); - function initJqplotDatas(series, seriesColors, options, json){ + function initJqplotData(series, seriesColors, options, json){ $('[data-toggle="jqplot-serie"].active').each(function(i){ var position = $(this).index() - 1; - series.push(json.series[position].datas); + series.push(json.series[position].data); seriesColors.push(json.series[position].color); }); - // Number of days to display ( = datas.length in one serie) - days = json.series[0].datas.length; + // Number of days to display ( = data.length in one serie) + days = json.series[0].data.length; // Graph title options.title = json.title; From c7835758e5efe45cdf591e88c45f885267d00ff2 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Wed, 30 Oct 2013 16:32:36 +0100 Subject: [PATCH 32/59] Minor css tuning, renamed "details" tab of categories edition to associaitons --- .../default/assets/less/thelia/thelia.less | 23 ++++++++++++------- templates/admin/default/category-edit.html | 10 ++++---- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/templates/admin/default/assets/less/thelia/thelia.less b/templates/admin/default/assets/less/thelia/thelia.less index 0d42273e9..00ab43a74 100644 --- a/templates/admin/default/assets/less/thelia/thelia.less +++ b/templates/admin/default/assets/less/thelia/thelia.less @@ -338,7 +338,7 @@ // -- Drag & drop -- .take{ - + .draggable{ border: 2px dashed @gray-light; margin-bottom: 10px; @@ -346,9 +346,9 @@ &:last-child{ margin-bottom: 0; - } + } } - + .over{ .drop-message{ border-color: @brand-primary; @@ -358,8 +358,8 @@ } -.place{ - +.place{ + .over{ .drop-message{ border-color: @brand-primary; @@ -368,10 +368,10 @@ } .panel-body{ - + .draggable, .drag{ margin: 5px 0; - padding: 10px; + padding: 10px; border: 1px dashed @gray-light; } @@ -390,7 +390,7 @@ } .take, .place{ - + .drop-message{ width: 50%; margin: 10px auto; @@ -410,4 +410,11 @@ .ui-draggable-dragging{ z-index: 100; } +} + +// -- File Upoload drop zone --------------------------------------------------- + +.dropzone { + border: 1px dashed #ddd; + padding: 20px; } \ No newline at end of file diff --git a/templates/admin/default/category-edit.html b/templates/admin/default/category-edit.html index 340e7cbbd..200098d69 100755 --- a/templates/admin/default/category-edit.html +++ b/templates/admin/default/category-edit.html @@ -42,7 +42,7 @@ *} + {module_include location='folder_list_caption'} {loop type="auth" name="can_create" role="ADMIN" resource="admin.folder" access="CREATE"} diff --git a/templates/admin/default/includes/content-folder-management.html b/templates/admin/default/includes/content-folder-management.html index 31f86e058..cbace2455 100644 --- a/templates/admin/default/includes/content-folder-management.html +++ b/templates/admin/default/includes/content-folder-management.html @@ -6,7 +6,7 @@
-

{intl l='Additional categories'}

+

{intl l='Additional Folders'}

{intl l='A content could be attached to more than one folder. Select here the additional fodlers for this content.'} {loop name="default_folder" type="folder" id=$DEFAULT_FOLDER} {intl l='You can change the default folder (%title) in the "General" tab.' title=$TITLE} diff --git a/templates/admin/default/includes/document-upload-list-ajax.html b/templates/admin/default/includes/document-upload-list-ajax.html index 1233e06a8..5c271e769 100644 --- a/templates/admin/default/includes/document-upload-list-ajax.html +++ b/templates/admin/default/includes/document-upload-list-ajax.html @@ -29,3 +29,6 @@ Parameters: {/loop}

- {loop type="auth" name="can_change" role="ADMIN" resource="admin.configuration.administrator" access="UPDATE"} + {* if admin is current admin : + - can UPDATE anyway + - cannot delete himself + *} + {if $ID == {admin attr="id"}} - {/loop} - - {loop type="auth" name="can_delete" role="ADMIN" resource="admin.configuration.administrator" access="DELETE"} - - {/loop} + {else} + {loop type="auth" name="can_change" role="ADMIN" resource="admin.configuration.administrator" access="UPDATE"} + + {/loop} + {loop type="auth" name="can_delete" role="ADMIN" resource="admin.configuration.administrator" access="DELETE"} + + {/loop} + {/if}
{intl l='Price
w/ taxes (%currency)' currency=$currency_symbol}
{intl l='Weight
(Kg)'}
{intl l='Default'}{intl l='Sale'} {intl l='New'}{intl l='Sale'} {intl l='Sale price
w/o taxes (%currency)' currency=$currency_symbol}
{intl l='Sale price
w/ taxes (%currency)' currency=$currency_symbol}
 
+ {form_field form=$form field='product_sale_element_id' value_key=$idx} {$current_pse_id = $value} - {$current_pse_id}: {loop name="product.sales.elements.combinations" type="attribute_combination" product_sale_elements=$current_pse_id backend_context="1"} + {loop name="product.sales.elements.combinations" type="attribute_combination" product_sale_elements=$current_pse_id backend_context="1"} {if $LOOP_COUNT > 1} - {/if}{$ATTRIBUTE_TITLE} {/loop} {/form_field} ID: {$current_pse_id}
- - {$TITLE} - -
{/ifloop} +{elseloop rel="document"} +
{intl l='There is no documents attached to this %type.' type=$documentType}
+{/elseloop} diff --git a/templates/admin/default/includes/image-upload-list-ajax.html b/templates/admin/default/includes/image-upload-list-ajax.html index e2c19932b..8acb5c7ef 100644 --- a/templates/admin/default/includes/image-upload-list-ajax.html +++ b/templates/admin/default/includes/image-upload-list-ajax.html @@ -27,4 +27,7 @@ Parameters:
{/loop}
-{/ifloop} \ No newline at end of file +{/ifloop} +{elseloop rel="image"} +
{intl l='There is no images attached to this %type.' type=$imageType}
+{/elseloop} \ No newline at end of file From f5828dc18b75d25a028f084d3601288cb692e049 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Wed, 30 Oct 2013 19:52:47 +0100 Subject: [PATCH 35/59] added timestamp parameter to format_date sparty plugin --- .../Controller/Admin/AttributeController.php | 17 ----------------- core/lib/Thelia/Core/Template/Loop/Feed.php | 15 ++++++++------- .../Core/Template/Smarty/Plugins/Format.php | 9 ++++++++- .../admin/default/ajax/thelia_news_feed.html | 4 ++-- 4 files changed, 18 insertions(+), 27 deletions(-) diff --git a/core/lib/Thelia/Controller/Admin/AttributeController.php b/core/lib/Thelia/Controller/Admin/AttributeController.php index 00162ffcf..9644d6651 100644 --- a/core/lib/Thelia/Controller/Admin/AttributeController.php +++ b/core/lib/Thelia/Controller/Admin/AttributeController.php @@ -157,23 +157,6 @@ class AttributeController extends AbstractCrudController 'postscriptum' => $object->getPostscriptum() ); - // Setup attributes values - /* - * FIXME : doesn't work. "We get a This form should not contain extra fields." error - $attr_av_list = AttributeAvQuery::create() - ->joinWithI18n($this->getCurrentEditionLocale()) - ->filterByAttributeId($object->getId()) - ->find(); - - $attr_array = array(); - - foreach ($attr_av_list as $attr_av) { - $attr_array[$attr_av->getId()] = $attr_av->getTitle(); - } - - $data['attribute_values'] = $attr_array; - */ - // Setup the object form return new AttributeModificationForm($this->getRequest(), "form", $data); } diff --git a/core/lib/Thelia/Core/Template/Loop/Feed.php b/core/lib/Thelia/Core/Template/Loop/Feed.php index cf29cf3b7..11f872432 100755 --- a/core/lib/Thelia/Core/Template/Loop/Feed.php +++ b/core/lib/Thelia/Core/Template/Loop/Feed.php @@ -29,6 +29,7 @@ use Thelia\Core\Template\Element\LoopResultRow; use Thelia\Core\Template\Loop\Argument\ArgumentCollection; use Thelia\Core\Template\Loop\Argument\Argument; +use Thelia\Tools\DateTimeFormat; /** * @@ -90,15 +91,15 @@ class Feed extends BaseLoop $author = $item->get_author(); $description = $item->get_description(); - $date = $item->get_date('d/m/Y'); - $loopResultRow = new LoopResultRow($loopResult, null, $this->versionable, $this->timestampable, $this->countable); - $loopResultRow->set("URL", $item->get_permalink()); - $loopResultRow->set("TITLE", $item->get_title()); - $loopResultRow->set("AUTHOR", $item->get_author()); - $loopResultRow->set("DESCRIPTION", $item->get_description()); - $loopResultRow->set("DATE", $item->get_date('d/m/Y')); // FIXME - date format should be an intl parameter + $loopResultRow + ->set("URL" , $item->get_permalink()) + ->set("TITLE" , $item->get_title()) + ->set("AUTHOR" , $item->get_author()) + ->set("DESCRIPTION" , $item->get_description()) + ->set("DATE" , $item->get_date('U')) // FIXME - date format should be an intl parameter + ; $loopResult->addRow($loopResultRow); } diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/Format.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/Format.php index 01491e6fd..7b9e12eb8 100644 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/Format.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/Format.php @@ -73,7 +73,14 @@ class Format extends AbstractSmartyPlugin $date = $this->getParam($params, "date", false); if ($date === false) { - throw new SmartyPluginException("date is a mandatory parameter in format_date function"); + $timestamp = $this->getParam($params, "timestamp", false); + + if ($timestamp === false) + throw new SmartyPluginException("Either date or timestamp is a mandatory parameter in format_date function"); + else { + $date = new \DateTime(); + $date->setTimestamp($timestamp); + } } if (!$date instanceof \DateTime) { diff --git a/templates/admin/default/ajax/thelia_news_feed.html b/templates/admin/default/ajax/thelia_news_feed.html index f1b7e3133..360ca696b 100755 --- a/templates/admin/default/ajax/thelia_news_feed.html +++ b/templates/admin/default/ajax/thelia_news_feed.html @@ -7,7 +7,7 @@ @@ -20,7 +20,7 @@ {intl l='Lire la suite'}
-
+
{/loop}
\ No newline at end of file From a06d83bfb4986c89b915c6864bf848e55c1b6a7e Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Wed, 30 Oct 2013 20:10:37 +0100 Subject: [PATCH 36/59] Fixed exception if module content is empty --- core/lib/Thelia/Core/Template/Smarty/Plugins/Module.php | 6 +++++- .../Tests/Core/Template/Smarty/Plugins/FormatTest.php | 1 + templates/admin/default/ajax/thelia_news_feed.html | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/Module.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/Module.php index 1c6ab4fd1..23f9ed231 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/Module.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/Module.php @@ -53,7 +53,11 @@ class Module extends AbstractSmartyPlugin } } } - return $template->fetch(sprintf("string:%s", $content)); + + if (! empty($content)) + return $template->fetch(sprintf("string:%s", $content)); + + return ""; } /** diff --git a/core/lib/Thelia/Tests/Core/Template/Smarty/Plugins/FormatTest.php b/core/lib/Thelia/Tests/Core/Template/Smarty/Plugins/FormatTest.php index 979642677..a673b805b 100644 --- a/core/lib/Thelia/Tests/Core/Template/Smarty/Plugins/FormatTest.php +++ b/core/lib/Thelia/Tests/Core/Template/Smarty/Plugins/FormatTest.php @@ -155,6 +155,7 @@ class FormatTest extends \PHPUnit_Framework_TestCase * test formatDate without mandatory parameters * * @covers ::formatDate + * @expectedException Thelia\Core\Template\Smarty\Exception\SmartyPluginException */ public function testFormatDateWithoutDate() { diff --git a/templates/admin/default/ajax/thelia_news_feed.html b/templates/admin/default/ajax/thelia_news_feed.html index 360ca696b..fcc064ea9 100755 --- a/templates/admin/default/ajax/thelia_news_feed.html +++ b/templates/admin/default/ajax/thelia_news_feed.html @@ -7,7 +7,7 @@ From 1e549c2b8ffb3d98791d507a41ec2912aa4ebe58 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Thu, 31 Oct 2013 09:39:22 +0100 Subject: [PATCH 37/59] change default locale in config.xml for translator --- core/lib/Thelia/Config/Resources/config.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index 185568516..7cc2e1359 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -211,7 +211,7 @@ - + From 5be233c0790e57650543e4884b86b4d53b53cd9f Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Thu, 31 Oct 2013 09:52:06 +0100 Subject: [PATCH 38/59] set default locale to null in translator --- core/lib/Thelia/Config/Resources/config.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index 7cc2e1359..0cf616126 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -211,7 +211,7 @@ - + null From 8abe56458f26169677f2bc014a8a6b7cd86e2b3e Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Thu, 31 Oct 2013 10:02:13 +0100 Subject: [PATCH 39/59] retrieve local from session in translator --- core/lib/Thelia/Config/Resources/config.xml | 2 +- core/lib/Thelia/Core/Translation/Translator.php | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index 0cf616126..5574d07bc 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -211,7 +211,7 @@ - null + diff --git a/core/lib/Thelia/Core/Translation/Translator.php b/core/lib/Thelia/Core/Translation/Translator.php index 22dc47afd..444604e28 100755 --- a/core/lib/Thelia/Core/Translation/Translator.php +++ b/core/lib/Thelia/Core/Translation/Translator.php @@ -1,18 +1,28 @@ container = $container; // Allow singleton style calls once intanciated. // For this to work, the Translator service has to be instanciated very early. This is done manually // in TheliaHttpKernel, by calling $this->container->get('thelia.translator'); + parent::__construct(null); self::$instance = $this; } @@ -28,6 +38,11 @@ class Translator extends BaseTranslator return self::$instance; } + public function getLocale() + { + return $this->container->get('request')->getSession()->getLang()->getLocale(); + } + /** * {@inheritdoc} * From 00dab8e7ec0a3bc82971a591022205e7b8e6b582 Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Thu, 31 Oct 2013 11:20:51 +0100 Subject: [PATCH 40/59] review jqplot --- .../Controller/Admin/HomeController.php | 32 +-- templates/admin/default/home.html | 271 +++++++++--------- 2 files changed, 151 insertions(+), 152 deletions(-) diff --git a/core/lib/Thelia/Controller/Admin/HomeController.php b/core/lib/Thelia/Controller/Admin/HomeController.php index c30e61985..dbd0a5d30 100644 --- a/core/lib/Thelia/Controller/Admin/HomeController.php +++ b/core/lib/Thelia/Controller/Admin/HomeController.php @@ -43,46 +43,46 @@ class HomeController extends BaseAdminController { $data = new \stdClass(); - $data->title = "Stats on " . $this->getRequest()->request->get('month', date('m')) . "/" . $this->getRequest()->request->get('month', date('Y')); + $data->title = "Stats on " . $this->getRequest()->query->get('month', date('m')) . "/" . $this->getRequest()->query->get('year', date('Y')); /* sales */ $saleSeries = new \stdClass(); - $saleSeries->color = $this->getRequest()->request->get('sales_color', '#adadad'); + $saleSeries->color = $this->getRequest()->query->get('sales_color', '#adadad'); $saleSeries->data = OrderQuery::getSaleStats( - $this->getRequest()->request->get('month', date('m')), - $this->getRequest()->request->get('year', date('Y')) + $this->getRequest()->query->get('month', date('m')), + $this->getRequest()->query->get('year', date('Y')) ); /* new customers */ $newCustomerSeries = new \stdClass(); - $newCustomerSeries->color = $this->getRequest()->request->get('customers_color', '#f39922'); + $newCustomerSeries->color = $this->getRequest()->query->get('customers_color', '#f39922'); $newCustomerSeries->data = CustomerQuery::getNewCustomersStats( - $this->getRequest()->request->get('month', date('m')), - $this->getRequest()->request->get('year', date('Y')) + $this->getRequest()->query->get('month', date('m')), + $this->getRequest()->query->get('year', date('Y')) ); /* orders */ $orderSeries = new \stdClass(); - $orderSeries->color = $this->getRequest()->request->get('orders_color', '#5cb85c'); + $orderSeries->color = $this->getRequest()->query->get('orders_color', '#5cb85c'); $orderSeries->data = OrderQuery::getOrdersStats( - $this->getRequest()->request->get('month', date('m')), - $this->getRequest()->request->get('year', date('Y')) + $this->getRequest()->query->get('month', date('m')), + $this->getRequest()->query->get('year', date('Y')) ); /* first order */ $firstOrderSeries = new \stdClass(); - $firstOrderSeries->color = $this->getRequest()->request->get('first_orders_color', '#5bc0de'); + $firstOrderSeries->color = $this->getRequest()->query->get('first_orders_color', '#5bc0de'); $firstOrderSeries->data = OrderQuery::getFirstOrdersStats( - $this->getRequest()->request->get('month', date('m')), - $this->getRequest()->request->get('year', date('Y')) + $this->getRequest()->query->get('month', date('m')), + $this->getRequest()->query->get('year', date('Y')) ); /* cancelled orders */ $cancelledOrderSeries = new \stdClass(); - $cancelledOrderSeries->color = $this->getRequest()->request->get('cancelled_orders_color', '#d9534f'); + $cancelledOrderSeries->color = $this->getRequest()->query->get('cancelled_orders_color', '#d9534f'); $cancelledOrderSeries->data = OrderQuery::getOrdersStats( - $this->getRequest()->request->get('month', date('m')), - $this->getRequest()->request->get('year', date('Y')), + $this->getRequest()->query->get('month', date('m')), + $this->getRequest()->query->get('year', date('Y')), array(5) ); diff --git a/templates/admin/default/home.html b/templates/admin/default/home.html index fd6d85a4a..105c640c5 100755 --- a/templates/admin/default/home.html +++ b/templates/admin/default/home.html @@ -12,10 +12,10 @@
{intl l='Dashboard'} -
- - - +
+ + +
@@ -33,12 +33,6 @@
- -
-
-
-
-
@@ -255,144 +249,149 @@ {javascripts file='assets/js/jqplot/jquery.jqplot.min.js'} - - {javascripts file='assets/js/jqplot/plugins/jqplot.highlighter.min.js'} - - {/javascripts} - {javascripts file='assets/js/jqplot/plugins/jqplot.barRenderer.min.js'} - - {/javascripts} - {javascripts file='assets/js/jqplot/plugins/jqplot.pieRenderer.min.js'} - - {/javascripts} + {/javascripts} + {javascripts file='assets/js/jqplot/plugins/jqplot.highlighter.min.js'} + + {/javascripts} + {javascripts file='assets/js/jqplot/plugins/jqplot.barRenderer.min.js'} + + {/javascripts} + {javascripts file='assets/js/jqplot/plugins/jqplot.pieRenderer.min.js'} + + {/javascripts} - {/javascripts} {/block} \ No newline at end of file From 1ce6dfe04dc7c0b654185ed67a0a75543d62b405 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Thu, 31 Oct 2013 11:21:26 +0100 Subject: [PATCH 41/59] explode master config file. Now each xml file file presents in master config is parse --- core/lib/Thelia/Config/Resources/command.xml | 21 ++ core/lib/Thelia/Config/Resources/config.xml | 298 ------------------ core/lib/Thelia/Config/Resources/coupon.xml | 55 ++++ core/lib/Thelia/Config/Resources/form.xml | 125 ++++++++ core/lib/Thelia/Config/Resources/loop.xml | 59 ++++ .../Thelia/Config/Resources/smarty-plugin.xml | 100 ++++++ .../Compiler/TranslatorPass.php | 56 ++++ core/lib/Thelia/Core/Thelia.php | 13 +- 8 files changed, 426 insertions(+), 301 deletions(-) create mode 100644 core/lib/Thelia/Config/Resources/command.xml create mode 100644 core/lib/Thelia/Config/Resources/coupon.xml create mode 100644 core/lib/Thelia/Config/Resources/form.xml create mode 100644 core/lib/Thelia/Config/Resources/loop.xml create mode 100644 core/lib/Thelia/Config/Resources/smarty-plugin.xml create mode 100644 core/lib/Thelia/Core/DependencyInjection/Compiler/TranslatorPass.php diff --git a/core/lib/Thelia/Config/Resources/command.xml b/core/lib/Thelia/Config/Resources/command.xml new file mode 100644 index 000000000..308a1c50c --- /dev/null +++ b/core/lib/Thelia/Config/Resources/command.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index 5574d07bc..e75ab8ebb 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -4,188 +4,6 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://thelia.net/schema/dic/config http://thelia.net/schema/dic/config/thelia-1.0.xsd"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -238,83 +56,6 @@
- - - - - %kernel.environment% - - - - - - - - - - - - - - - - %thelia.parser.loops% - - - - - - - - - - - - - - - %thelia.parser.forms% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -328,45 +69,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/core/lib/Thelia/Config/Resources/coupon.xml b/core/lib/Thelia/Config/Resources/coupon.xml new file mode 100644 index 000000000..fc327911c --- /dev/null +++ b/core/lib/Thelia/Config/Resources/coupon.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/lib/Thelia/Config/Resources/form.xml b/core/lib/Thelia/Config/Resources/form.xml new file mode 100644 index 000000000..8577bf145 --- /dev/null +++ b/core/lib/Thelia/Config/Resources/form.xml @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/lib/Thelia/Config/Resources/loop.xml b/core/lib/Thelia/Config/Resources/loop.xml new file mode 100644 index 000000000..fe2c333d4 --- /dev/null +++ b/core/lib/Thelia/Config/Resources/loop.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/lib/Thelia/Config/Resources/smarty-plugin.xml b/core/lib/Thelia/Config/Resources/smarty-plugin.xml new file mode 100644 index 000000000..0d0b7ed15 --- /dev/null +++ b/core/lib/Thelia/Config/Resources/smarty-plugin.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + %kernel.environment% + + + + + + + + + + + + + + + + %thelia.parser.loops% + + + + + + + + + + + + + + + %thelia.parser.forms% + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/lib/Thelia/Core/DependencyInjection/Compiler/TranslatorPass.php b/core/lib/Thelia/Core/DependencyInjection/Compiler/TranslatorPass.php new file mode 100644 index 000000000..3bd35bb62 --- /dev/null +++ b/core/lib/Thelia/Core/DependencyInjection/Compiler/TranslatorPass.php @@ -0,0 +1,56 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\DependencyInjection\Compiler; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; + + +/** + * Class TranslatorPass + * @package Thelia\Core\DependencyInjection\Compiler + * @author Manuel Raynaud + */ +class TranslatorPass implements CompilerPassInterface +{ + + /** + * You can modify the container here before it is dumped to PHP code. + * + * @param ContainerBuilder $container + * + * @api + */ + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('thelia.translator')) { + return; + } + + $translator = $container->getDefinition('thelia.translator'); + + foreach($container->findTaggedServiceIds('translator.loader') as $id => $attributes) { + + } + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Thelia.php b/core/lib/Thelia/Core/Thelia.php index 1bc1e7649..9b0d1402f 100755 --- a/core/lib/Thelia/Core/Thelia.php +++ b/core/lib/Thelia/Core/Thelia.php @@ -35,6 +35,7 @@ namespace Thelia\Core; use Propel\Runtime\Connection\ConnectionWrapper; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\Finder\Finder; use Symfony\Component\HttpKernel\Kernel; use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\Yaml\Yaml; @@ -110,9 +111,15 @@ class Thelia extends Kernel { $loader = new XmlFileLoader($container, new FileLocator(THELIA_ROOT . "/core/lib/Thelia/Config/Resources")); - $loader->load("config.xml"); - $loader->load("routing.xml"); - $loader->load("action.xml"); + $finder = Finder::create() + ->name('*.xml') + ->depth(0) + ->in(THELIA_ROOT . "/core/lib/Thelia/Config/Resources"); + + foreach($finder as $file) { + $loader->load($file->getBaseName()); + } + if (defined("THELIA_INSTALL_MODE") === false) { $modules = \Thelia\Model\ModuleQuery::getActivated(); From a295fee0d3d6499af22b819ace7c7e558c495da5 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Thu, 31 Oct 2013 11:36:56 +0100 Subject: [PATCH 42/59] Changed ModulesAdmin dir into AdminIncludes - Updated debug bar module --- core/lib/Thelia/Command/BaseModuleGenerate.php | 2 +- core/lib/Thelia/Core/Template/Smarty/Plugins/Module.php | 2 +- local/modules/TheliaDebugBar/AdminIncludes/footer_js.html | 2 ++ local/modules/TheliaDebugBar/AdminIncludes/head_css.html | 3 +++ templates/admin/default/admin-layout.tpl | 7 ------- templates/admin/default/configuration.html | 4 ++-- 6 files changed, 9 insertions(+), 11 deletions(-) create mode 100644 local/modules/TheliaDebugBar/AdminIncludes/footer_js.html create mode 100644 local/modules/TheliaDebugBar/AdminIncludes/head_css.html diff --git a/core/lib/Thelia/Command/BaseModuleGenerate.php b/core/lib/Thelia/Command/BaseModuleGenerate.php index 1a27d9e4c..7d487d4cc 100755 --- a/core/lib/Thelia/Command/BaseModuleGenerate.php +++ b/core/lib/Thelia/Command/BaseModuleGenerate.php @@ -42,7 +42,7 @@ abstract class BaseModuleGenerate extends ContainerAwareCommand 'Config', 'Model', 'Loop', - 'AdminModule' + 'AdminIncludes' ); protected function verifyExistingModule() diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/Module.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/Module.php index 23f9ed231..beb9a6b25 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/Module.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/Module.php @@ -47,7 +47,7 @@ class Module extends AbstractSmartyPlugin foreach ($modules as $module) { - $file = THELIA_MODULE_DIR . "/". ucfirst($module->getCode()) . "/ModuleAdmin/".$location.".html"; + $file = THELIA_MODULE_DIR . "/". ucfirst($module->getCode()) . "/AdminIncludes/".$location.".html"; if(file_exists($file)) { $content .= file_get_contents($file); } diff --git a/local/modules/TheliaDebugBar/AdminIncludes/footer_js.html b/local/modules/TheliaDebugBar/AdminIncludes/footer_js.html new file mode 100644 index 000000000..52b154116 --- /dev/null +++ b/local/modules/TheliaDebugBar/AdminIncludes/footer_js.html @@ -0,0 +1,2 @@ +{debugbar_renderjs} +{debugbar_renderresult} diff --git a/local/modules/TheliaDebugBar/AdminIncludes/head_css.html b/local/modules/TheliaDebugBar/AdminIncludes/head_css.html new file mode 100644 index 000000000..23d047f7e --- /dev/null +++ b/local/modules/TheliaDebugBar/AdminIncludes/head_css.html @@ -0,0 +1,3 @@ +{* Include debug bar smarty calls *} + +{debugbar_rendercss} \ No newline at end of file diff --git a/templates/admin/default/admin-layout.tpl b/templates/admin/default/admin-layout.tpl index d2081d829..e84084513 100644 --- a/templates/admin/default/admin-layout.tpl +++ b/templates/admin/default/admin-layout.tpl @@ -26,8 +26,6 @@ {/stylesheets} - {debugbar_rendercss} - {block name="after-bootstrap-css"}{/block} {* -- Admin CSS section ------------------------------------------------- *} @@ -245,11 +243,6 @@ } - - - {debugbar_renderjs} - {debugbar_renderresult} - {block name="after-javascript-include"}{/block} {javascripts file='assets/js/bootstrap/bootstrap.js'} diff --git a/templates/admin/default/configuration.html b/templates/admin/default/configuration.html index ff9622c45..d0e3c880c 100644 --- a/templates/admin/default/configuration.html +++ b/templates/admin/default/configuration.html @@ -165,12 +165,12 @@ {/loop} -{* {loop type="auth" name="pcc8" role="ADMIN" resource="admin.configuration.system-logs" access="VIEW"} + {loop type="auth" name="pcc8" role="ADMIN" resource="admin.configuration.system-logs" access="VIEW"} {intl l='System logs'} - {/loop}*} + {/loop} {module_include location='system_configuration_bottom'} From 453575eeaeb84b6c0e48c9c6e228c5ea156715fe Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Thu, 31 Oct 2013 11:48:18 +0100 Subject: [PATCH 43/59] create compiler for loading translation.loader tag --- .../Thelia/Config/Resources/translation.xml | 62 +++++++++++++++++++ core/lib/Thelia/Core/Bundle/TheliaBundle.php | 6 +- .../Compiler/TranslatorPass.php | 8 ++- 3 files changed, 73 insertions(+), 3 deletions(-) create mode 100644 core/lib/Thelia/Config/Resources/translation.xml diff --git a/core/lib/Thelia/Config/Resources/translation.xml b/core/lib/Thelia/Config/Resources/translation.xml new file mode 100644 index 000000000..2fdef3882 --- /dev/null +++ b/core/lib/Thelia/Config/Resources/translation.xml @@ -0,0 +1,62 @@ + + + + + + Symfony\Component\Translation\Loader\PhpFileLoader + Symfony\Component\Translation\Loader\YamlFileLoader + Symfony\Component\Translation\Loader\XliffFileLoader + Symfony\Component\Translation\Loader\PoFileLoader + Symfony\Component\Translation\Loader\MoFileLoader + Symfony\Component\Translation\Loader\QtFileLoader + Symfony\Component\Translation\Loader\CsvFileLoader + Symfony\Component\Translation\Loader\IcuResFileLoader + Symfony\Component\Translation\Loader\IcuDatFileLoader + Symfony\Component\Translation\Loader\IniFileLoader + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/lib/Thelia/Core/Bundle/TheliaBundle.php b/core/lib/Thelia/Core/Bundle/TheliaBundle.php index dcdcdd5d2..9a536f88d 100755 --- a/core/lib/Thelia/Core/Bundle/TheliaBundle.php +++ b/core/lib/Thelia/Core/Bundle/TheliaBundle.php @@ -31,6 +31,7 @@ use Thelia\Core\DependencyInjection\Compiler\RegisterListenersPass; use Thelia\Core\DependencyInjection\Compiler\RegisterParserPluginPass; use Thelia\Core\DependencyInjection\Compiler\RegisterRouterPass; use Thelia\Core\DependencyInjection\Compiler\RegisterCouponConditionPass; +use Thelia\Core\DependencyInjection\Compiler\TranslatorPass; /** * First Bundle use in Thelia @@ -63,6 +64,9 @@ class TheliaBundle extends Bundle ->addCompilerPass(new RegisterParserPluginPass()) ->addCompilerPass(new RegisterRouterPass()) ->addCompilerPass(new RegisterCouponPass()) - ->addCompilerPass(new RegisterCouponConditionPass()); + ->addCompilerPass(new RegisterCouponConditionPass()) + ->addCompilerPass(new TranslatorPass()) + + ; } } diff --git a/core/lib/Thelia/Core/DependencyInjection/Compiler/TranslatorPass.php b/core/lib/Thelia/Core/DependencyInjection/Compiler/TranslatorPass.php index 3bd35bb62..e007f9961 100644 --- a/core/lib/Thelia/Core/DependencyInjection/Compiler/TranslatorPass.php +++ b/core/lib/Thelia/Core/DependencyInjection/Compiler/TranslatorPass.php @@ -24,6 +24,7 @@ namespace Thelia\Core\DependencyInjection\Compiler; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; /** @@ -49,8 +50,11 @@ class TranslatorPass implements CompilerPassInterface $translator = $container->getDefinition('thelia.translator'); - foreach($container->findTaggedServiceIds('translator.loader') as $id => $attributes) { - + foreach($container->findTaggedServiceIds('translation.loader') as $id => $attributes) { + $translator->addMethodCall('addLoader', array($attributes[0]['alias'], new Reference($id))); + if (isset($attributes[0]['legacy-alias'])) { + $translator->addMethodCall('addLoader', array($attributes[0]['legacy-alias'], new Reference($id))); + } } } } \ No newline at end of file From 07c5dd4a517519283ea34b4959b8201e230b4f1f Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Thu, 31 Oct 2013 11:59:25 +0100 Subject: [PATCH 44/59] admoin home stats navigation --- templates/admin/default/home.html | 44 ++++++++++++++++++------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/templates/admin/default/home.html b/templates/admin/default/home.html index 105c640c5..c1fbfa7c6 100755 --- a/templates/admin/default/home.html +++ b/templates/admin/default/home.html @@ -13,9 +13,9 @@
{intl l='Dashboard'}
- + - +
@@ -264,6 +264,8 @@ jQuery(function($){ + var jQplotDate = new Date(); + jQplotDate.setDate(1); // Set day to 1 so we can add month without 30/31 days of month troubles. var url = "{url path='/admin/home/stats'}"; var jQplotData; // json data var jQPlotInstance; // global instance @@ -306,13 +308,10 @@ jQuery(function($){ } }; + {literal} + // Get initial data Json - $.getJSON(url) - .done(function(data) { - jQplotData = data; - jsonSuccessLoad(); - }) - .fail(jsonFailLoad); + retrieveJQPlotJson(jQplotDate.getMonth()+1, jQplotDate.getFullYear()); $('[data-toggle="jqplot"]').click(function(){ @@ -323,21 +322,26 @@ jQuery(function($){ $('.js-stats-change-month').click(function(e){ $('.js-stats-change-month').attr('disabled', true); + jQplotDate.setMonth(parseInt(jQplotDate.getMonth()) + parseInt($(this).data('month-offset'))); + retrieveJQPlotJson(jQplotDate.getMonth()+1, jQplotDate.getFullYear(), function(){$('.js-stats-change-month').attr('disabled', false);}); - $('#jqplot'); - - {literal} - $.getJSON(url, {month: 9, year: 2010}) - .done(function(data) { - jQplotData = data; - jsonSuccessLoad(); - }) - .fail(jsonFailLoad); - {/literal} }); + function retrieveJQPlotJson(month, year, callback) { + console.log(month, year); - function initJqplotData(json){ + $.getJSON(url, {month: month, year: year}) + .done(function(data) { + jQplotData = data; + jsonSuccessLoad(); + if(callback) { + callback(); + } + }) + .fail(jsonFailLoad); + } + + function initJqplotData(json) { var series = []; var seriesColors = []; $('[data-toggle="jqplot"].active').each(function(i){ @@ -391,6 +395,8 @@ jQuery(function($){ } + {/literal} + }); From 3b9f94cec843a2e4a3373977a175126fbda71996 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Thu, 31 Oct 2013 12:16:14 +0100 Subject: [PATCH 45/59] Using now templates instead of hard code in AdminUtilities smarty plugin --- .../Controller/Admin/BaseAdminController.php | 2 +- .../Smarty/Plugins/AdminUtilities.php | 55 +++++++++++++------ install/insert.sql | 1 + .../AdminIncludes/footer_js.html | 2 + .../admin-utilities-position-block.html | 7 +++ ...dmin-utilities-sortable-column-header.html | 10 ++++ templates/admin/default/modules.html | 5 +- 7 files changed, 62 insertions(+), 20 deletions(-) create mode 100644 templates/admin/default/includes/admin-utilities-position-block.html create mode 100644 templates/admin/default/includes/admin-utilities-sortable-column-header.html diff --git a/core/lib/Thelia/Controller/Admin/BaseAdminController.php b/core/lib/Thelia/Controller/Admin/BaseAdminController.php index ad8d46ba0..5fc11c814 100755 --- a/core/lib/Thelia/Controller/Admin/BaseAdminController.php +++ b/core/lib/Thelia/Controller/Admin/BaseAdminController.php @@ -199,7 +199,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 ?: ConfigQuery::read('base-admin-template', 'admin/default')); return $parser; } diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/AdminUtilities.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/AdminUtilities.php index 244d09166..3b432cea9 100644 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/AdminUtilities.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/AdminUtilities.php @@ -27,6 +27,8 @@ use Thelia\Core\Template\Smarty\SmartyPluginDescriptor; use Thelia\Core\Template\Smarty\AbstractSmartyPlugin; use Thelia\Tools\URL; use Thelia\Core\Security\SecurityContext; +use Thelia\Model\Config; +use Thelia\Model\ConfigQuery; /** * This class implements variour admin template utilities @@ -42,6 +44,26 @@ class AdminUtilities extends AbstractSmartyPlugin $this->securityContext = $securityContext; } + protected function fetch_snippet($smarty, $templateName, $variablesArray) { + + $data = ''; + + $snippet_path = sprintf('%s/%s/%s.html', + THELIA_TEMPLATE_DIR, + ConfigQuery::read('base-admin-template', 'admin/default'), + $templateName + ); + + if (false !== $snippet_content = file_get_contents($snippet_path)) { + + $smarty->assign($variablesArray); + + $data = $smarty->fetch(sprintf('string:%s', $snippet_content)); + } + + return $data; + } + public function generatePositionChangeBlock($params, &$smarty) { // The required permissions @@ -70,15 +92,15 @@ class AdminUtilities extends AbstractSmartyPlugin */ if ($permissions == null || $this->securityContext->isGranted("ADMIN", array($resource), array($access))) { - return sprintf( - '%s', - URL::getInstance()->absoluteUrl($path, array('mode' => 'up', $url_parameter => $id)), - $in_place_edit_class, - $id, - $position, - URL::getInstance()->absoluteUrl($path, array('mode' => 'down', $url_parameter => $id)) - ); - } else { + + return $this->fetch_snippet($smarty, 'includes/admin-utilities-position-block', array( + 'admin_utilities_go_up_url' => URL::getInstance()->absoluteUrl($path, array('mode' => 'up', $url_parameter => $id)), + 'admin_utilities_in_place_edit_class' => $in_place_edit_class, + 'admin_utilities_object_id' => $id, + 'admin_utilities_current_position' => $position, + 'admin_utilities_go_down_url' => URL::getInstance()->absoluteUrl($path, array('mode' => 'down', $url_parameter => $id)) + )); + } else { return $position; } } @@ -111,21 +133,20 @@ class AdminUtilities extends AbstractSmartyPlugin $request_parameter_name = $this->getParam($params, 'request_parameter_name', 'order'); if ($current_order == $order) { - $icon = 'up'; + $sort_direction = 'up'; $order_change = $reverse_order; } elseif ($current_order == $reverse_order) { - $icon = 'down'; + $sort_direction = 'down'; $order_change = $order; } else { $order_change = $order; } - if (! empty($icon)) - $output = sprintf(' ', $icon); - else - $output = ''; - - return sprintf('%s%s', $output, URL::getInstance()->absoluteUrl($path, array($request_parameter_name => $order_change)), $label); + return $this->fetch_snippet($smarty, 'includes/admin-utilities-sortable-column-header', array( + 'admin_utilities_sort_direction' => $sort_direction, + 'admin_utilities_sorting_url' => URL::getInstance()->absoluteUrl($path, array($request_parameter_name => $order_change)), + 'admin_utilities_header_text' => $label + )); } /** diff --git a/install/insert.sql b/install/insert.sql index 71dc0c745..7ceb6ce34 100755 --- a/install/insert.sql +++ b/install/insert.sql @@ -8,6 +8,7 @@ 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()), ('default_lang_without_translation', '1', 1, 1, NOW(), NOW()), ('rewriting_enable', '0', 0, 0, NOW(), NOW()), ('imagine_graphic_driver', 'gd', 0, 0, NOW(), NOW()), diff --git a/local/modules/TheliaDebugBar/AdminIncludes/footer_js.html b/local/modules/TheliaDebugBar/AdminIncludes/footer_js.html index 52b154116..6f897e091 100644 --- a/local/modules/TheliaDebugBar/AdminIncludes/footer_js.html +++ b/local/modules/TheliaDebugBar/AdminIncludes/footer_js.html @@ -1,2 +1,4 @@ +{* Include debug bar smarty calls *} + {debugbar_renderjs} {debugbar_renderresult} diff --git a/templates/admin/default/includes/admin-utilities-position-block.html b/templates/admin/default/includes/admin-utilities-position-block.html new file mode 100644 index 000000000..c1277f212 --- /dev/null +++ b/templates/admin/default/includes/admin-utilities-position-block.html @@ -0,0 +1,7 @@ +{* +This snippet is used by the AdminUtilities Smarty plugin to generate +the position maagement block in tables +*} + +{$admin_utilities_current_position} + \ No newline at end of file diff --git a/templates/admin/default/includes/admin-utilities-sortable-column-header.html b/templates/admin/default/includes/admin-utilities-sortable-column-header.html new file mode 100644 index 000000000..0dce13492 --- /dev/null +++ b/templates/admin/default/includes/admin-utilities-sortable-column-header.html @@ -0,0 +1,10 @@ +{* +This snippet is used by the AdminUtilities Smarty plugin to generate +the header on a sortable column +*} +{if $admin_utilities_sort_direction == 'up'} + +{else if $admin_utilities_sort_direction == 'down'} + +{/if} +{$admin_utilities_header_text} \ No newline at end of file diff --git a/templates/admin/default/modules.html b/templates/admin/default/modules.html index ca94be812..d82bce399 100644 --- a/templates/admin/default/modules.html +++ b/templates/admin/default/modules.html @@ -9,7 +9,7 @@
- +
{module_include location='modules_top'} From 696d67805d326d948b1463afbf9f772b5e326818 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Thu, 31 Oct 2013 12:43:29 +0100 Subject: [PATCH 46/59] finish to implement translation --- core/lib/Thelia/Core/Thelia.php | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/core/lib/Thelia/Core/Thelia.php b/core/lib/Thelia/Core/Thelia.php index 9b0d1402f..3d476ad30 100755 --- a/core/lib/Thelia/Core/Thelia.php +++ b/core/lib/Thelia/Core/Thelia.php @@ -47,6 +47,7 @@ use Thelia\Config\DatabaseConfiguration; use Thelia\Config\DefinePropel; use Thelia\Core\TheliaContainerBuilder; use Thelia\Core\DependencyInjection\Loader\XmlFileLoader; +use Thelia\Model\ConfigQuery; use Symfony\Component\Config\FileLocator; use Propel\Runtime\Propel; @@ -122,7 +123,8 @@ class Thelia extends Kernel if (defined("THELIA_INSTALL_MODE") === false) { $modules = \Thelia\Model\ModuleQuery::getActivated(); - + $translator = $container->getDefinition('thelia.translator'); + $dirs = array(); foreach ($modules as $module) { try { @@ -138,10 +140,38 @@ class Thelia extends Kernel $loader = new XmlFileLoader($container, new FileLocator(THELIA_MODULE_DIR . "/" . ucfirst($module->getCode()) . "/Config")); $loader->load("config.xml"); + + if (is_dir($dir = THELIA_MODULE_DIR . "/" . ucfirst($module->getCode()) . "/I18n")) { + $dirs[] = $dir; + } } catch (\InvalidArgumentException $e) { // FIXME: process module configuration exception } } + + //Load translation from templates + //admin template + if(is_dir($dir = THELIA_TEMPLATE_DIR . '/admin/default/I18n')) { + $dirs[] = $dir; + } + + //front template + $template = ConfigQuery::getActiveTemplate(); + if(is_dir($dir = THELIA_TEMPLATE_DIR . $template . "/I18n")) { + $dirs[] = $dir; + } + + if ($dirs) { + $finder = Finder::create() + ->files() + ->depth(0) + ->in($dirs); + + foreach ($finder as $file) { + list($locale, $format) = explode('.', $file->getBaseName(), 2); + $translator->addMethodCall('addResource', array($format, (string) $file, $locale)); + } + } } } From bbae85156bfbd8d2c8b502ca880facebfd7b787b Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Thu, 31 Oct 2013 15:44:07 +0100 Subject: [PATCH 47/59] create translation files --- templates/default/I18n/en_US.php | 156 +++++++++++++++++++++++++++++++ templates/default/I18n/es_ES.php | 156 +++++++++++++++++++++++++++++++ templates/default/I18n/fr_FR.php | 156 +++++++++++++++++++++++++++++++ templates/default/I18n/it_IT.php | 156 +++++++++++++++++++++++++++++++ 4 files changed, 624 insertions(+) create mode 100755 templates/default/I18n/en_US.php create mode 100755 templates/default/I18n/es_ES.php create mode 100755 templates/default/I18n/fr_FR.php create mode 100755 templates/default/I18n/it_IT.php diff --git a/templates/default/I18n/en_US.php b/templates/default/I18n/en_US.php new file mode 100755 index 000000000..b301bb505 --- /dev/null +++ b/templates/default/I18n/en_US.php @@ -0,0 +1,156 @@ + '+ View All', + 'Thelia V2' => 'Thelia V2', + 'Skip to content' => 'Skip to content', + 'Toggle navigation' => 'Toggle navigation', + 'Main Navigation' => 'Main Navigation', + 'Register!' => 'Register!', + 'Log In!' => 'Log In!', + 'Sign In' => 'Sign In', + 'Register' => 'Register', + 'Cart' => 'Cart', + 'View Cart' => 'View Cart', + 'Checkout' => 'Checkout', + 'You have no items in your shopping cart.' => 'You have no items in your shopping cart.', + 'Home' => 'Home', + 'Search a product' => 'Search a product', + 'Search...' => 'Search...', + 'Minimum 2 characters.' => 'Minimum 2 characters.', + 'Search' => 'Search', + 'Language:' => 'Language:', + 'Currency:' => 'Currency:', + 'Latest' => 'Latest', + 'Offers' => 'Offers', + 'Special Price:' => 'Special Price:', + 'Regular Price:' => 'Regular Price:', + 'Free shipping' => 'Free shipping', + 'Orders over $50' => 'Orders over $50', + 'Secure payment' => 'Secure payment', + 'Multi-payment plateform' => 'Multi-payment plateform', + 'Need help ?' => 'Need help ?', + 'Questions ? See or F.A.Q.' => 'Questions ? See or F.A.Q.', + 'Latest articles' => 'Latest articles', + 'No articles currently' => 'No articles currently', + 'Usefull links' => 'Usefull links', + 'Login' => 'Login', + 'Follow us' => 'Follow us', + 'Newsletter' => 'Newsletter', + 'Sign up to receive our latest news.' => 'Sign up to receive our latest news.', + 'Email address' => 'Email address', + 'Your email address' => 'Your email address', + 'Subscribe' => 'Subscribe', + 'Contact Us' => 'Contact Us', + 'Copyright' => 'Copyright', + 'You are here:' => 'You are here:', + 'Show' => 'Show', + 'per page' => 'per page', + 'Sort By' => 'Sort By', + 'Name ascending' => 'Name ascending', + 'Name descending' => 'Name descending', + 'Price ascending' => 'Price ascending', + 'Price descending' => 'Price descending', + 'View as' => 'View as', + 'View product' => 'View product', + 'Pagination' => 'Pagination', + 'No products available in this category' => 'No products available in this category', + 'Categories' => 'Categories', + 'Ref.' => 'Ref.', + 'Availability' => 'Availability', + 'In stock' => 'In stock', + 'Out of stock' => 'Out of stock', + 'Add to cart' => 'Add to cart', + 'Description' => 'Description', + 'Additional Info' => 'Additional Info', + 'View cart' => 'View cart', + 'Continue Shopping' => 'Continue Shopping', + 'Upsell Products' => 'Upsell Products', + 'Your Cart' => 'Your Cart', + 'Billing and delivery' => 'Billing and delivery', + 'Check my order' => 'Check my order', + 'Product Name' => 'Product Name', + 'Name' => 'Name', + 'Unit Price' => 'Unit Price', + 'Price' => 'Price', + 'Quantity' => 'Quantity', + 'Qty' => 'Qty', + 'Total' => 'Total', + 'Tax Inclusive' => 'Tax Inclusive', + 'TTC' => 'TTC', + 'Available' => 'Available', + 'In Stock' => 'In Stock', + 'No.' => 'No.', + 'Remove' => 'Remove', + 'Proceed checkout' => 'Proceed checkout', + 'Warning' => 'Warning', + 'missing or invalid data' => 'missing or invalid data', + 'Do you have an account?' => 'Do you have an account?', + 'Forgot your Password?' => 'Forgot your Password?', + 'Next' => 'Next', + 'Log out!' => 'Log out!', + 'My Account' => 'My Account', + 'Previous product' => 'Previous product', + 'Next product' => 'Next product', + 'instead of' => 'instead of', + 'Add a new address' => 'Add a new address', + 'Choose your delivery address' => 'Choose your delivery address', + 'Address %nb' => 'Address %nb', + 'Edit this address' => 'Edit this address', + 'Edit' => 'Edit', + 'Remove this address' => 'Remove this address', + 'Cancel' => 'Cancel', + 'Choose your delivery method' => 'Choose your delivery method', + 'Back' => 'Back', + 'Next Step' => 'Next Step', + 'Delete address' => 'Delete address', + 'Do you really want to delete this address ?' => 'Do you really want to delete this address ?', + 'No' => 'No', + 'Yes' => 'Yes', + 'Shipping Tax' => 'Shipping Tax', + 'You may have a coupon ?' => 'You may have a coupon ?', + 'Code :' => 'Code :', + 'Coupon code' => 'Coupon code', + 'Ok' => 'Ok', + 'Delivery address' => 'Delivery address', + 'Billing addres' => 'Billing addres', + 'Change address' => 'Change address', + 'Choose your payment method' => 'Choose your payment method', + 'Secure Payment' => 'Secure Payment', + 'You chose to pay by' => 'You chose to pay by', + 'Thank you for the trust you place in us.' => 'Thank you for the trust you place in us.', + 'A summary of your order email has been sent to the following address' => 'A summary of your order email has been sent to the following address', + 'Your order will be confirmed by us upon receipt of your payment.' => 'Your order will be confirmed by us upon receipt of your payment.', + 'Order number' => 'Order number', + 'Date' => 'Date', + 'Go home' => 'Go home', + 'Account' => 'Account', + 'Personal Information' => 'Personal Information', + 'Change my account information' => 'Change my account information', + 'Change my password' => 'Change my password', + 'My Address book' => 'My Address book', + 'My Address Books' => 'My Address Books', + 'My Orders' => 'My Orders', + 'List of orders' => 'List of orders', + 'Order Number' => 'Order Number', + 'Amount' => 'Amount', + 'Status' => 'Status', + 'View' => 'View', + 'View order %ref as pdf document' => 'View order %ref as pdf document', + 'Order details' => 'Order details', + 'You don\'t have orders yet.' => 'You don\'t have orders yet.', + 'Update Profil' => 'Update Profil', + 'Personal Informations' => 'Personal Informations', + 'Select Title' => 'Select Title', + 'Update' => 'Update', + 'Change Password' => 'Change Password', + 'Login Information' => 'Login Information', + 'Create New Address' => 'Create New Address', + 'Address' => 'Address', + 'Home address' => 'Home address', + 'Complementary address' => 'Complementary address', + 'Select Country' => 'Select Country', + 'Create' => 'Create', + 'Related' => 'Related', +) +; \ No newline at end of file diff --git a/templates/default/I18n/es_ES.php b/templates/default/I18n/es_ES.php new file mode 100755 index 000000000..cbf0e3a78 --- /dev/null +++ b/templates/default/I18n/es_ES.php @@ -0,0 +1,156 @@ + '', + 'Thelia V2' => '', + 'Skip to content' => '', + 'Toggle navigation' => '', + 'Main Navigation' => '', + 'Register!' => '', + 'Log In!' => '', + 'Sign In' => '', + 'Register' => '', + 'Cart' => '', + 'View Cart' => '', + 'Checkout' => '', + 'You have no items in your shopping cart.' => '', + 'Home' => '', + 'Search a product' => '', + 'Search...' => '', + 'Minimum 2 characters.' => '', + 'Search' => '', + 'Language:' => '', + 'Currency:' => '', + 'Latest' => '', + 'Offers' => '', + 'Special Price:' => '', + 'Regular Price:' => '', + 'Free shipping' => '', + 'Orders over $50' => '', + 'Secure payment' => '', + 'Multi-payment plateform' => '', + 'Need help ?' => '', + 'Questions ? See or F.A.Q.' => '', + 'Latest articles' => '', + 'No articles currently' => '', + 'Usefull links' => '', + 'Login' => '', + 'Follow us' => '', + 'Newsletter' => '', + 'Sign up to receive our latest news.' => '', + 'Email address' => '', + 'Your email address' => '', + 'Subscribe' => '', + 'Contact Us' => '', + 'Copyright' => '', + 'You are here:' => '', + 'Show' => '', + 'per page' => '', + 'Sort By' => '', + 'Name ascending' => '', + 'Name descending' => '', + 'Price ascending' => '', + 'Price descending' => '', + 'View as' => '', + 'View product' => '', + 'Pagination' => '', + 'No products available in this category' => '', + 'Categories' => '', + 'Ref.' => '', + 'Availability' => '', + 'In stock' => '', + 'Out of stock' => '', + 'Add to cart' => '', + 'Description' => '', + 'Additional Info' => '', + 'View cart' => '', + 'Continue Shopping' => '', + 'Upsell Products' => '', + 'Your Cart' => '', + 'Billing and delivery' => '', + 'Check my order' => '', + 'Product Name' => '', + 'Name' => '', + 'Unit Price' => '', + 'Price' => '', + 'Quantity' => '', + 'Qty' => '', + 'Total' => '', + 'Tax Inclusive' => '', + 'TTC' => '', + 'Available' => '', + 'In Stock' => '', + 'No.' => '', + 'Remove' => '', + 'Proceed checkout' => '', + 'Warning' => '', + 'missing or invalid data' => '', + 'Do you have an account?' => '', + 'Forgot your Password?' => '', + 'Next' => '', + 'Log out!' => '', + 'My Account' => '', + 'Previous product' => '', + 'Next product' => '', + 'instead of' => '', + 'Add a new address' => '', + 'Choose your delivery address' => '', + 'Address %nb' => '', + 'Edit this address' => '', + 'Edit' => '', + 'Remove this address' => '', + 'Cancel' => '', + 'Choose your delivery method' => '', + 'Back' => '', + 'Next Step' => '', + 'Delete address' => '', + 'Do you really want to delete this address ?' => '', + 'No' => '', + 'Yes' => '', + 'Shipping Tax' => '', + 'You may have a coupon ?' => '', + 'Code :' => '', + 'Coupon code' => '', + 'Ok' => '', + 'Delivery address' => '', + 'Billing addres' => '', + 'Change address' => '', + 'Choose your payment method' => '', + 'Secure Payment' => '', + 'You chose to pay by' => '', + 'Thank you for the trust you place in us.' => '', + 'A summary of your order email has been sent to the following address' => '', + 'Your order will be confirmed by us upon receipt of your payment.' => '', + 'Order number' => '', + 'Date' => '', + 'Go home' => '', + 'Account' => '', + 'Personal Information' => '', + 'Change my account information' => '', + 'Change my password' => '', + 'My Address book' => '', + 'My Address Books' => '', + 'My Orders' => '', + 'List of orders' => '', + 'Order Number' => '', + 'Amount' => '', + 'Status' => '', + 'View' => '', + 'View order %ref as pdf document' => '', + 'Order details' => '', + 'You don\'t have orders yet.' => '', + 'Update Profil' => '', + 'Personal Informations' => '', + 'Select Title' => '', + 'Update' => '', + 'Change Password' => '', + 'Login Information' => '', + 'Create New Address' => '', + 'Address' => '', + 'Home address' => '', + 'Complementary address' => '', + 'Select Country' => '', + 'Create' => '', + 'Related' => '', +) +; \ No newline at end of file diff --git a/templates/default/I18n/fr_FR.php b/templates/default/I18n/fr_FR.php new file mode 100755 index 000000000..cbf0e3a78 --- /dev/null +++ b/templates/default/I18n/fr_FR.php @@ -0,0 +1,156 @@ + '', + 'Thelia V2' => '', + 'Skip to content' => '', + 'Toggle navigation' => '', + 'Main Navigation' => '', + 'Register!' => '', + 'Log In!' => '', + 'Sign In' => '', + 'Register' => '', + 'Cart' => '', + 'View Cart' => '', + 'Checkout' => '', + 'You have no items in your shopping cart.' => '', + 'Home' => '', + 'Search a product' => '', + 'Search...' => '', + 'Minimum 2 characters.' => '', + 'Search' => '', + 'Language:' => '', + 'Currency:' => '', + 'Latest' => '', + 'Offers' => '', + 'Special Price:' => '', + 'Regular Price:' => '', + 'Free shipping' => '', + 'Orders over $50' => '', + 'Secure payment' => '', + 'Multi-payment plateform' => '', + 'Need help ?' => '', + 'Questions ? See or F.A.Q.' => '', + 'Latest articles' => '', + 'No articles currently' => '', + 'Usefull links' => '', + 'Login' => '', + 'Follow us' => '', + 'Newsletter' => '', + 'Sign up to receive our latest news.' => '', + 'Email address' => '', + 'Your email address' => '', + 'Subscribe' => '', + 'Contact Us' => '', + 'Copyright' => '', + 'You are here:' => '', + 'Show' => '', + 'per page' => '', + 'Sort By' => '', + 'Name ascending' => '', + 'Name descending' => '', + 'Price ascending' => '', + 'Price descending' => '', + 'View as' => '', + 'View product' => '', + 'Pagination' => '', + 'No products available in this category' => '', + 'Categories' => '', + 'Ref.' => '', + 'Availability' => '', + 'In stock' => '', + 'Out of stock' => '', + 'Add to cart' => '', + 'Description' => '', + 'Additional Info' => '', + 'View cart' => '', + 'Continue Shopping' => '', + 'Upsell Products' => '', + 'Your Cart' => '', + 'Billing and delivery' => '', + 'Check my order' => '', + 'Product Name' => '', + 'Name' => '', + 'Unit Price' => '', + 'Price' => '', + 'Quantity' => '', + 'Qty' => '', + 'Total' => '', + 'Tax Inclusive' => '', + 'TTC' => '', + 'Available' => '', + 'In Stock' => '', + 'No.' => '', + 'Remove' => '', + 'Proceed checkout' => '', + 'Warning' => '', + 'missing or invalid data' => '', + 'Do you have an account?' => '', + 'Forgot your Password?' => '', + 'Next' => '', + 'Log out!' => '', + 'My Account' => '', + 'Previous product' => '', + 'Next product' => '', + 'instead of' => '', + 'Add a new address' => '', + 'Choose your delivery address' => '', + 'Address %nb' => '', + 'Edit this address' => '', + 'Edit' => '', + 'Remove this address' => '', + 'Cancel' => '', + 'Choose your delivery method' => '', + 'Back' => '', + 'Next Step' => '', + 'Delete address' => '', + 'Do you really want to delete this address ?' => '', + 'No' => '', + 'Yes' => '', + 'Shipping Tax' => '', + 'You may have a coupon ?' => '', + 'Code :' => '', + 'Coupon code' => '', + 'Ok' => '', + 'Delivery address' => '', + 'Billing addres' => '', + 'Change address' => '', + 'Choose your payment method' => '', + 'Secure Payment' => '', + 'You chose to pay by' => '', + 'Thank you for the trust you place in us.' => '', + 'A summary of your order email has been sent to the following address' => '', + 'Your order will be confirmed by us upon receipt of your payment.' => '', + 'Order number' => '', + 'Date' => '', + 'Go home' => '', + 'Account' => '', + 'Personal Information' => '', + 'Change my account information' => '', + 'Change my password' => '', + 'My Address book' => '', + 'My Address Books' => '', + 'My Orders' => '', + 'List of orders' => '', + 'Order Number' => '', + 'Amount' => '', + 'Status' => '', + 'View' => '', + 'View order %ref as pdf document' => '', + 'Order details' => '', + 'You don\'t have orders yet.' => '', + 'Update Profil' => '', + 'Personal Informations' => '', + 'Select Title' => '', + 'Update' => '', + 'Change Password' => '', + 'Login Information' => '', + 'Create New Address' => '', + 'Address' => '', + 'Home address' => '', + 'Complementary address' => '', + 'Select Country' => '', + 'Create' => '', + 'Related' => '', +) +; \ No newline at end of file diff --git a/templates/default/I18n/it_IT.php b/templates/default/I18n/it_IT.php new file mode 100755 index 000000000..cbf0e3a78 --- /dev/null +++ b/templates/default/I18n/it_IT.php @@ -0,0 +1,156 @@ + '', + 'Thelia V2' => '', + 'Skip to content' => '', + 'Toggle navigation' => '', + 'Main Navigation' => '', + 'Register!' => '', + 'Log In!' => '', + 'Sign In' => '', + 'Register' => '', + 'Cart' => '', + 'View Cart' => '', + 'Checkout' => '', + 'You have no items in your shopping cart.' => '', + 'Home' => '', + 'Search a product' => '', + 'Search...' => '', + 'Minimum 2 characters.' => '', + 'Search' => '', + 'Language:' => '', + 'Currency:' => '', + 'Latest' => '', + 'Offers' => '', + 'Special Price:' => '', + 'Regular Price:' => '', + 'Free shipping' => '', + 'Orders over $50' => '', + 'Secure payment' => '', + 'Multi-payment plateform' => '', + 'Need help ?' => '', + 'Questions ? See or F.A.Q.' => '', + 'Latest articles' => '', + 'No articles currently' => '', + 'Usefull links' => '', + 'Login' => '', + 'Follow us' => '', + 'Newsletter' => '', + 'Sign up to receive our latest news.' => '', + 'Email address' => '', + 'Your email address' => '', + 'Subscribe' => '', + 'Contact Us' => '', + 'Copyright' => '', + 'You are here:' => '', + 'Show' => '', + 'per page' => '', + 'Sort By' => '', + 'Name ascending' => '', + 'Name descending' => '', + 'Price ascending' => '', + 'Price descending' => '', + 'View as' => '', + 'View product' => '', + 'Pagination' => '', + 'No products available in this category' => '', + 'Categories' => '', + 'Ref.' => '', + 'Availability' => '', + 'In stock' => '', + 'Out of stock' => '', + 'Add to cart' => '', + 'Description' => '', + 'Additional Info' => '', + 'View cart' => '', + 'Continue Shopping' => '', + 'Upsell Products' => '', + 'Your Cart' => '', + 'Billing and delivery' => '', + 'Check my order' => '', + 'Product Name' => '', + 'Name' => '', + 'Unit Price' => '', + 'Price' => '', + 'Quantity' => '', + 'Qty' => '', + 'Total' => '', + 'Tax Inclusive' => '', + 'TTC' => '', + 'Available' => '', + 'In Stock' => '', + 'No.' => '', + 'Remove' => '', + 'Proceed checkout' => '', + 'Warning' => '', + 'missing or invalid data' => '', + 'Do you have an account?' => '', + 'Forgot your Password?' => '', + 'Next' => '', + 'Log out!' => '', + 'My Account' => '', + 'Previous product' => '', + 'Next product' => '', + 'instead of' => '', + 'Add a new address' => '', + 'Choose your delivery address' => '', + 'Address %nb' => '', + 'Edit this address' => '', + 'Edit' => '', + 'Remove this address' => '', + 'Cancel' => '', + 'Choose your delivery method' => '', + 'Back' => '', + 'Next Step' => '', + 'Delete address' => '', + 'Do you really want to delete this address ?' => '', + 'No' => '', + 'Yes' => '', + 'Shipping Tax' => '', + 'You may have a coupon ?' => '', + 'Code :' => '', + 'Coupon code' => '', + 'Ok' => '', + 'Delivery address' => '', + 'Billing addres' => '', + 'Change address' => '', + 'Choose your payment method' => '', + 'Secure Payment' => '', + 'You chose to pay by' => '', + 'Thank you for the trust you place in us.' => '', + 'A summary of your order email has been sent to the following address' => '', + 'Your order will be confirmed by us upon receipt of your payment.' => '', + 'Order number' => '', + 'Date' => '', + 'Go home' => '', + 'Account' => '', + 'Personal Information' => '', + 'Change my account information' => '', + 'Change my password' => '', + 'My Address book' => '', + 'My Address Books' => '', + 'My Orders' => '', + 'List of orders' => '', + 'Order Number' => '', + 'Amount' => '', + 'Status' => '', + 'View' => '', + 'View order %ref as pdf document' => '', + 'Order details' => '', + 'You don\'t have orders yet.' => '', + 'Update Profil' => '', + 'Personal Informations' => '', + 'Select Title' => '', + 'Update' => '', + 'Change Password' => '', + 'Login Information' => '', + 'Create New Address' => '', + 'Address' => '', + 'Home address' => '', + 'Complementary address' => '', + 'Select Country' => '', + 'Create' => '', + 'Related' => '', +) +; \ No newline at end of file From 5110abe207a2334c33ef5c5e50ad924fb2077fcd Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Thu, 31 Oct 2013 15:46:36 +0100 Subject: [PATCH 48/59] create translation files for admin part --- templates/admin/default/I18n/en_US.php | 26 ++++++++++++++++++++++++++ templates/admin/default/I18n/es_ES.php | 26 ++++++++++++++++++++++++++ templates/admin/default/I18n/fr_FR.php | 26 ++++++++++++++++++++++++++ templates/admin/default/I18n/it_IT.php | 26 ++++++++++++++++++++++++++ 4 files changed, 104 insertions(+) create mode 100644 templates/admin/default/I18n/en_US.php create mode 100644 templates/admin/default/I18n/es_ES.php create mode 100644 templates/admin/default/I18n/fr_FR.php create mode 100644 templates/admin/default/I18n/it_IT.php diff --git a/templates/admin/default/I18n/en_US.php b/templates/admin/default/I18n/en_US.php new file mode 100644 index 000000000..7eb24949a --- /dev/null +++ b/templates/admin/default/I18n/en_US.php @@ -0,0 +1,26 @@ +. */ +/* */ +/*************************************************************************************/ + +return array( + +); \ No newline at end of file diff --git a/templates/admin/default/I18n/es_ES.php b/templates/admin/default/I18n/es_ES.php new file mode 100644 index 000000000..7eb24949a --- /dev/null +++ b/templates/admin/default/I18n/es_ES.php @@ -0,0 +1,26 @@ +. */ +/* */ +/*************************************************************************************/ + +return array( + +); \ No newline at end of file diff --git a/templates/admin/default/I18n/fr_FR.php b/templates/admin/default/I18n/fr_FR.php new file mode 100644 index 000000000..7eb24949a --- /dev/null +++ b/templates/admin/default/I18n/fr_FR.php @@ -0,0 +1,26 @@ +. */ +/* */ +/*************************************************************************************/ + +return array( + +); \ No newline at end of file diff --git a/templates/admin/default/I18n/it_IT.php b/templates/admin/default/I18n/it_IT.php new file mode 100644 index 000000000..7eb24949a --- /dev/null +++ b/templates/admin/default/I18n/it_IT.php @@ -0,0 +1,26 @@ +. */ +/* */ +/*************************************************************************************/ + +return array( + +); \ No newline at end of file From 99dc5594843d3873b557e0904d617ea50238d26f Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Thu, 31 Oct 2013 16:08:54 +0100 Subject: [PATCH 49/59] update translation files for admin part --- templates/admin/default/I18n/en_US.php | 830 ++++++++++++++++++++++++- templates/admin/default/I18n/es_ES.php | 830 ++++++++++++++++++++++++- templates/admin/default/I18n/fr_FR.php | 830 ++++++++++++++++++++++++- templates/admin/default/I18n/it_IT.php | 830 ++++++++++++++++++++++++- 4 files changed, 3224 insertions(+), 96 deletions(-) mode change 100644 => 100755 templates/admin/default/I18n/en_US.php mode change 100644 => 100755 templates/admin/default/I18n/es_ES.php mode change 100644 => 100755 templates/admin/default/I18n/fr_FR.php mode change 100644 => 100755 templates/admin/default/I18n/it_IT.php diff --git a/templates/admin/default/I18n/en_US.php b/templates/admin/default/I18n/en_US.php old mode 100644 new mode 100755 index 7eb24949a..3c7045751 --- a/templates/admin/default/I18n/en_US.php +++ b/templates/admin/default/I18n/en_US.php @@ -1,26 +1,808 @@ . */ -/* */ -/*************************************************************************************/ -return array( - -); \ No newline at end of file +return array ( + 'Lire la suite' => 'Lire la suite', + 'Back-office home' => 'Back-office home', + 'Thelia Back Office' => 'Thelia Back Office', + 'Version %ver' => 'Version %ver', + 'View site' => 'View site', + 'View shop' => 'View shop', + 'Profil' => 'Profil', + 'Close administation session' => 'Close administation session', + 'Logout' => 'Logout', + 'Home' => 'Home', + 'Customers' => 'Customers', + 'Orders' => 'Orders', + 'All orders' => 'All orders', + 'Catalog' => 'Catalog', + 'Folders' => 'Folders', + 'Coupons' => 'Coupons', + 'Configuration' => 'Configuration', + 'Modules' => 'Modules', + 'Search' => 'Search', + 'Thelia, solution e-commerce libre' => 'Thelia, solution e-commerce libre', + 'Dashboard' => 'Dashboard', + 'Sales' => 'Sales', + 'New customers' => 'New customers', + 'First orders' => 'First orders', + 'Aborted orders' => 'Aborted orders', + 'Shop Informations' => 'Shop Informations', + 'Categories' => 'Categories', + 'Products' => 'Products', + 'Online products' => 'Online products', + 'Offline products' => 'Offline products', + 'Pending orders' => 'Pending orders', + 'In process orderst' => 'In process orderst', + 'Shipped orders' => 'Shipped orders', + 'Canceled orders' => 'Canceled orders', + 'Sales statistics' => 'Sales statistics', + 'Today' => 'Today', + 'This month' => 'This month', + 'This year' => 'This year', + 'Overall sales' => 'Overall sales', + 'Sales excluding shipping' => 'Sales excluding shipping', + 'Yesterday sales' => 'Yesterday sales', + 'Waiting orders' => 'Waiting orders', + 'In process orders' => 'In process orders', + 'Average cart' => 'Average cart', + 'Previous month sales' => 'Previous month sales', + 'Previous year sales' => 'Previous year sales', + 'Thelia informations' => 'Thelia informations', + 'Current version' => 'Current version', + 'Latest version available' => 'Latest version available', + 'News' => 'News', + 'Click here' => 'Click here', + '© Thelia 2013' => '© Thelia 2013', + 'Édité par OpenStudio' => 'Édité par OpenStudio', + 'Forum Thelia' => 'Forum Thelia', + 'Contributions Thelia' => 'Contributions Thelia', + 'Customer' => 'Customer', + 'Customers list' => 'Customers list', + 'Add a new Customer' => 'Add a new Customer', + 'customer ref' => 'customer ref', + 'firstname & lastname' => 'firstname & lastname', + 'last order' => 'last order', + 'order amount' => 'order amount', + 'Actions' => 'Actions', + 'Edit this customer' => 'Edit this customer', + 'Send a mail to this customer' => 'Send a mail to this customer', + 'Delete this customer and all his orders' => 'Delete this customer and all his orders', + 'Company Name' => 'Company Name', + 'Company' => 'Company', + 'Title' => 'Title', + 'First Name' => 'First Name', + 'Firstname' => 'Firstname', + 'Last Name' => 'Last Name', + 'Lastname' => 'Lastname', + 'Street Address' => 'Street Address', + 'Address' => 'Address', + 'Address Line 2' => 'Address Line 2', + 'Additional address' => 'Additional address', + 'Address Line 3' => 'Address Line 3', + 'Zip code' => 'Zip code', + 'City' => 'City', + 'Country' => 'Country', + 'Email Address' => 'Email Address', + 'Email address' => 'Email address', + 'Create a new customer' => 'Create a new customer', + 'Create this customer' => 'Create this customer', + 'Cancel' => 'Cancel', + 'OK' => 'OK', + 'Delete customer' => 'Delete customer', + 'Do you really want to delete this customer ?' => 'Do you really want to delete this customer ?', + 'No' => 'No', + 'Yes' => 'Yes', + 'Thelia configuration' => 'Thelia configuration', + 'Product catalog configuration' => 'Product catalog configuration', + 'Product templates' => 'Product templates', + 'Product attributes' => 'Product attributes', + 'Product features' => 'Product features', + 'Mailing templates' => 'Mailing templates', + 'Currencies' => 'Currencies', + 'Taxes rules' => 'Taxes rules', + 'Shipping configuration' => 'Shipping configuration', + 'Countries' => 'Countries', + 'Shipping zones' => 'Shipping zones', + 'System parameters' => 'System parameters', + 'Modules activation' => 'Modules activation', + 'System variables' => 'System variables', + 'Administration profiles' => 'Administration profiles', + 'Administrators' => 'Administrators', + 'Languages & URLs' => 'Languages & URLs', + 'Mailing system' => 'Mailing system', + 'Administration logs' => 'Administration logs', + 'System logs' => 'System logs', + 'Thelia System Variables' => 'Thelia System Variables', + 'Thelia system variables' => 'Thelia system variables', + 'Add a new variable' => 'Add a new variable', + 'Save chages' => 'Save chages', + 'Save changes' => 'Save changes', + 'Purpose' => 'Purpose', + 'Name' => 'Name', + 'Value' => 'Value', + 'Action' => 'Action', + 'Change this variable' => 'Change this variable', + 'Cancel changes and revert to original value' => 'Cancel changes and revert to original value', + 'Delete this variable' => 'Delete this variable', + 'Name *' => 'Name *', + 'Variable name' => 'Variable name', + 'Value *' => 'Value *', + 'Variable value' => 'Variable value', + 'Purpose *' => 'Purpose *', + 'Variable purpose' => 'Variable purpose', + 'English' => 'English', + 'Enter here the category name in the default language (%title)' => 'Enter here the category name in the default language (%title)', + 'Create a new variable' => 'Create a new variable', + 'Create this variable' => 'Create this variable', + 'Delete a variable' => 'Delete a variable', + 'Do you really want to delete this variable ?' => 'Do you really want to delete this variable ?', + 'Coupon' => 'Coupon', + 'Browse' => 'Browse', + 'Coupons : ' => 'Coupons : ', + 'List' => 'List', + 'Create a new coupon' => 'Create a new coupon', + 'Enabled coupons' => 'Enabled coupons', + 'Code' => 'Code', + 'Days before expiration' => 'Days before expiration', + 'Usage left' => 'Usage left', + 'Edit' => 'Edit', + 'Unlimited' => 'Unlimited', + 'Disabled coupons' => 'Disabled coupons', + 'Expiration date' => 'Expiration date', + 'Update coupon' => 'Update coupon', + 'Update' => 'Update', + 'Code :' => 'Code :', + 'code' => 'code', + 'Title :' => 'Title :', + 'title' => 'title', + 'Is enabled' => 'Is enabled', + 'Is available on special offers' => 'Is available on special offers', + 'Is cumulative' => 'Is cumulative', + 'Is removing postage' => 'Is removing postage', + 'Expiration date :' => 'Expiration date :', + 'yyyy-mm-dd' => 'yyyy-mm-dd', + 'Is unlimited' => 'Is unlimited', + 'Max usage :' => 'Max usage :', + 'max usage' => 'max usage', + 'Type :' => 'Type :', + 'Please select a coupon type' => 'Please select a coupon type', + 'Amount :' => 'Amount :', + '14.50' => '14.50', + 'Short description :' => 'Short description :', + 'short description' => 'short description', + 'Long description :' => 'Long description :', + 'long description' => 'long description', + 'Save your modifications' => 'Save your modifications', + 'Conditions' => 'Conditions', + 'Delete' => 'Delete', + 'And' => 'And', + 'Save this condition' => 'Save this condition', + 'Condition\'s category :' => 'Condition\'s category :', + 'Please select a condition category' => 'Please select a condition category', + 'Files manager' => 'Files manager', + 'Please retry' => 'Please retry', + 'Please select another condition' => 'Please select another condition', + 'Edit a customer' => 'Edit a customer', + 'Editing customer "%name"' => 'Editing customer "%name"', + 'Edit customer thelia thelia' => 'Edit customer thelia thelia', + 'Save' => 'Save', + 'Save and close' => 'Save and close', + 'Customer informations' => 'Customer informations', + 'Default address' => 'Default address', + 'Other addresses' => 'Other addresses', + 'Add a new address' => 'Add a new address', + 'Phone' => 'Phone', + 'cell phone' => 'cell phone', + 'Edit this address' => 'Edit this address', + 'Use this address by default' => 'Use this address by default', + 'orders for this customer' => 'orders for this customer', + 'Order n°' => 'Order n°', + 'Date & Hour' => 'Date & Hour', + 'Amount' => 'Amount', + 'Status' => 'Status', + 'Sorry, customer ID=1 was not found.' => 'Sorry, customer ID=1 was not found.', + 'Address label' => 'Address label', + 'Label' => 'Label', + 'Create an address' => 'Create an address', + 'Create this address' => 'Create this address', + 'Use address by default' => 'Use address by default', + 'Do you really want to use this address by default ?' => 'Do you really want to use this address by default ?', + 'Delete address' => 'Delete address', + 'Do you really want to delete this address ?' => 'Do you really want to delete this address ?', + 'Edit an address' => 'Edit an address', + 'Edit this order' => 'Edit this order', + 'Cancel this order' => 'Cancel this order', + 'Delete an order' => 'Delete an order', + 'Do you really want to cancel this order ?' => 'Do you really want to cancel this order ?', + 'Edit an order' => 'Edit an order', + 'Ordered products' => 'Ordered products', + 'Invoice and Delivery' => 'Invoice and Delivery', + 'Cart' => 'Cart', + 'Product' => 'Product', + 'Unit. price' => 'Unit. price', + 'Tax' => 'Tax', + 'Unit taxed price' => 'Unit taxed price', + 'Quantity' => 'Quantity', + 'Taxed total' => 'Taxed total', + 'Total without discount' => 'Total without discount', + 'Discount' => 'Discount', + 'Coupon code' => 'Coupon code', + 'Total including discount' => 'Total including discount', + 'Postage' => 'Postage', + 'Total' => 'Total', + 'Payment information' => 'Payment information', + 'Payment module' => 'Payment module', + 'Transaction reference' => 'Transaction reference', + 'Delivery module' => 'Delivery module', + 'tracking reference' => 'tracking reference', + 'Description' => 'Description', + 'Invoice informations' => 'Invoice informations', + 'Download invoice as PDF' => 'Download invoice as PDF', + 'PDF | Invoice' => 'PDF | Invoice', + 'Edit invoice address' => 'Edit invoice address', + 'Invoice reference' => 'Invoice reference', + 'Invoice date' => 'Invoice date', + 'Street address' => 'Street address', + 'Delivery address' => 'Delivery address', + 'Download purchase order as PDF' => 'Download purchase order as PDF', + 'PDF | Purchase order' => 'PDF | Purchase order', + 'Edit delivery address' => 'Edit delivery address', + 'Compagny' => 'Compagny', + 'Edit order address' => 'Edit order address', + 'Confirm changes' => 'Confirm changes', + 'Top level categories' => 'Top level categories', + 'Add a new category' => 'Add a new category', + 'ID' => 'ID', + 'Category title' => 'Category title', + 'Online' => 'Online', + 'Position' => 'Position', + 'Browse this category' => 'Browse this category', + 'Edit this category' => 'Edit this category', + 'Delete this category and all its contents' => 'Delete this category and all its contents', + 'This category has no sub-categories. To create a new one, click the + button above.' => 'This category has no sub-categories. To create a new one, click the + button above.', + 'This category has no sub-categories.' => 'This category has no sub-categories.', + 'Top level Products' => 'Top level Products', + 'Add a new product' => 'Add a new product', + 'Reference' => 'Reference', + 'Product title' => 'Product title', + 'This category doesn\'t contains any products. To add a new product, click the + button above.' => 'This category doesn\'t contains any products. To add a new product, click the + button above.', + 'Create a new category' => 'Create a new category', + 'Create this category' => 'Create this category', + 'Enter here the product reference' => 'Enter here the product reference', + 'Enter here the product name in the default language (%title)' => 'Enter here the product name in the default language (%title)', + 'Product price' => 'Product price', + 'Enter here the product price in the default currency (%title)' => 'Enter here the product price in the default currency (%title)', + 'Select a tax tule' => 'Select a tax tule', + 'Select here the tax applicable to this product' => 'Select here the tax applicable to this product', + 'Product weight' => 'Product weight', + 'Kg' => 'Kg', + 'Enter here the product weight, in Kilogrammes' => 'Enter here the product weight, in Kilogrammes', + 'Create a new product' => 'Create a new product', + 'Create this product' => 'Create this product', + 'Delete category' => 'Delete category', + 'Do you really want to delete this category and all its content ?' => 'Do you really want to delete this category and all its content ?', + 'Delete product' => 'Delete product', + 'Do you really want to delete this product ?' => 'Do you really want to delete this product ?', + 'Enter new category position' => 'Enter new category position', + 'Enter new product position' => 'Enter new product position', + 'Edit category' => 'Edit category', + 'Editing %cat' => 'Editing %cat', + 'Edit category %title' => 'Edit category %title', + 'Preview category page' => 'Preview category page', + 'Edit next category' => 'Edit next category', + 'General description' => 'General description', + 'Associations' => 'Associations', + 'Images' => 'Images', + 'Documents' => 'Documents', + 'Edit information in %lng' => 'Edit information in %lng', + 'Français' => 'Français', + 'castellano' => 'castellano', + 'Italiano' => 'Italiano', + 'Close' => 'Close', + 'Category title *' => 'Category title *', + 'Summary' => 'Summary', + 'A short description, used when a summary or an introduction is required' => 'A short description, used when a summary or an introduction is required', + 'Short description' => 'Short description', + 'Detailed description' => 'Detailed description', + 'The detailed description.' => 'The detailed description.', + 'Conclusion' => 'Conclusion', + 'A short post-description information' => 'A short post-description information', + 'Short conclusion' => 'Short conclusion', + 'Rewriten URL *' => 'Rewriten URL *', + 'Rewritten URL' => 'Rewritten URL', + 'Rewriten URL' => 'Rewriten URL', + 'Parent category *' => 'Parent category *', + 'Top level' => 'Top level', + 'Visibility' => 'Visibility', + 'Category created on %date_create. Last modification: %date_change' => 'Category created on %date_create. Last modification: %date_change', + 'Related content' => 'Related content', + 'You can attach here some content to this category' => 'You can attach here some content to this category', + 'Select a folder...' => 'Select a folder...', + 'Select a folder to get its content' => 'Select a folder to get its content', + 'Select a folder content...' => 'Select a folder content...', + 'Select a content and click (+) to add it to this category' => 'Select a content and click (+) to add it to this category', + 'No available content in this folder' => 'No available content in this folder', + 'No folders found' => 'No folders found', + 'Content title' => 'Content title', + 'This category contains no contents' => 'This category contains no contents', + 'Send files' => 'Send files', + 'Drop files to upload' => 'Drop files to upload', + 'Browse files' => 'Browse files', + 'Update this image' => 'Update this image', + 'There is no images attached to this %type.' => 'There is no images attached to this %type.', + 'Can\'t load images, please refresh this page.' => 'Can\'t load images, please refresh this page.', + 'There is no documents attached to this %type.' => 'There is no documents attached to this %type.', + 'Can\'t load documents, please refresh this page.' => 'Can\'t load documents, please refresh this page.', + 'Remove related content' => 'Remove related content', + 'Do you really want to remove this related content ?' => 'Do you really want to remove this related content ?', + '(edit)' => '(edit)', + 'Categories in %cat' => 'Categories in %cat', + 'Products in %cat' => 'Products in %cat', + 'Edit this product' => 'Edit this product', + 'Delete this product' => 'Delete this product', + 'Edit product' => 'Edit product', + 'Editing %title' => 'Editing %title', + 'Edit product %title' => 'Edit product %title', + 'Preview product page' => 'Preview product page', + 'General' => 'General', + 'Details' => 'Details', + 'Attributes & Features' => 'Attributes & Features', + 'Product reference' => 'Product reference', + 'Product title *' => 'Product title *', + 'Default product category *' => 'Default product category *', + 'You can attach this product to more categories in the details tab.' => 'You can attach this product to more categories in the details tab.', + 'Product created on %date_create. Last modification: %date_change' => 'Product created on %date_create. Last modification: %date_change', + 'Edit prices in %curr' => 'Edit prices in %curr', + 'Attribute Combinations' => 'Attribute Combinations', + 'Quickly create combinations using the combination builder' => 'Quickly create combinations using the combination builder', + 'Combination builder' => 'Combination builder', + 'Add a new combination' => 'Add a new combination', + 'EAN Code' => 'EAN Code', + 'Price
w/o taxes (%currency)' => 'Price
w/o taxes (%currency)', + 'Price
w/ taxes (%currency)' => 'Price
w/ taxes (%currency)', + 'Weight
(Kg)' => 'Weight
(Kg)', + 'Default' => 'Default', + 'Sale' => 'Sale', + 'New' => 'New', + 'Sale price
w/o taxes (%currency)' => 'Sale price
w/o taxes (%currency)', + 'Sale price
w/ taxes (%currency)' => 'Sale price
w/ taxes (%currency)', + 'Delete this combination' => 'Delete this combination', + 'Attribute' => 'Attribute', + 'Select an attribute...' => 'Select an attribute...', + 'Select an attribute and click (+) to view available values' => 'Select an attribute and click (+) to view available values', + 'Select an attribute value...' => 'Select an attribute value...', + 'Select a value click (+) to add it to the combination' => 'Select a value click (+) to add it to the combination', + 'No available value for this attribute' => 'No available value for this attribute', + 'To remove a value from the combination, select it and click "remove"' => 'To remove a value from the combination, select it and click "remove"', + 'Remove selected values' => 'Remove selected values', + 'Create a new combination' => 'Create a new combination', + 'Create this combination' => 'Create this combination', + 'Delete a combination' => 'Delete a combination', + 'Do you really want to delete this combination ?' => 'Do you really want to delete this combination ?', + 'Select attribute values to combine. You may enter a default value for some of the fields of the generated combinations.' => 'Select attribute values to combine. You may enter a default value for some of the fields of the generated combinations.', + 'Price excl. taxes' => 'Price excl. taxes', + 'Combination reference' => 'Combination reference', + 'Combination EAN Code' => 'Combination EAN Code', + 'Current quantity' => 'Current quantity', + '0 combinations' => '0 combinations', + 'Create combinations' => 'Create combinations', + 'Please wait, loading' => 'Please wait, loading', + 'Failed to get converted prices. Please try again.' => 'Failed to get converted prices. Please try again.', + 'Failed to get prices. Please try again.' => 'Failed to get prices. Please try again.', + 'Existing combinations will be deleted. Do you want to continue ?' => 'Existing combinations will be deleted. Do you want to continue ?', + 'To use features or attributes on this product, please select a product template. You can define product templates in the configuration section of the administration.' => 'To use features or attributes on this product, please select a product template. You can define product templates in the configuration section of the administration.', + 'Current product template' => 'Current product template', + 'Do not use a product template' => 'Do not use a product template', + 'Apply' => 'Apply', + 'Product Attributes' => 'Product Attributes', + 'You can change template attributes and their positions in the template configuration page.' => 'You can change template attributes and their positions in the template configuration page.', + 'Attribute Name' => 'Attribute Name', + 'This product template does not contains any features' => 'This product template does not contains any features', + 'Product Features' => 'Product Features', + 'You can change templates features and their positions in the template configuration page.' => 'You can change templates features and their positions in the template configuration page.', + 'Feature Name' => 'Feature Name', + 'Feature value for this product' => 'Feature value for this product', + 'Use Ctrl+click to select more than one value. You can also clear selected values.' => 'Use Ctrl+click to select more than one value. You can also clear selected values.', + 'Enter here the feature value as free text' => 'Enter here the feature value as free text', + 'Feature value' => 'Feature value', + 'Top level folders' => 'Top level folders', + 'Add a new folder' => 'Add a new folder', + 'Folder title' => 'Folder title', + 'Browse this folder' => 'Browse this folder', + 'Edit this folder' => 'Edit this folder', + 'Delete this folder and all its contents' => 'Delete this folder and all its contents', + 'This folder has no sub-folders. To create a new one, click the + button above.' => 'This folder has no sub-folders. To create a new one, click the + button above.', + 'This folder has no sub-folders.' => 'This folder has no sub-folders.', + 'Top level Contents' => 'Top level Contents', + 'Add a new content' => 'Add a new content', + 'This folder doesn\'t contains any contents. To add a new content, click the + button above.' => 'This folder doesn\'t contains any contents. To add a new content, click the + button above.', + 'Enter here the folder name in the default language (%title)' => 'Enter here the folder name in the default language (%title)', + 'Create a new folder' => 'Create a new folder', + 'Create this folder' => 'Create this folder', + 'Enter here the content name in the default language (%title)' => 'Enter here the content name in the default language (%title)', + 'Create a new content' => 'Create a new content', + 'Create this content' => 'Create this content', + 'Delete folder' => 'Delete folder', + 'Do you really want to delete this folder and all its content ?' => 'Do you really want to delete this folder and all its content ?', + 'Delete content' => 'Delete content', + 'Do you really want to delete this content ?' => 'Do you really want to delete this content ?', + 'Enter new folder position' => 'Enter new folder position', + 'Enter new content position' => 'Enter new content position', + 'An error occured' => 'An error occured', + 'Oops! An Error Occurred' => 'Oops! An Error Occurred', + 'Go to administration home' => 'Go to administration home', + 'Folders in %fold' => 'Folders in %fold', + 'Contents in %fold' => 'Contents in %fold', + 'Edit this content' => 'Edit this content', + 'Delete this content' => 'Delete this content', + 'Edit content' => 'Edit content', + 'Edit content %title' => 'Edit content %title', + 'Preview folder page' => 'Preview folder page', + 'Content title *' => 'Content title *', + 'Default folder *' => 'Default folder *', + 'Folder created on %date_create. Last modification: %date_change' => 'Folder created on %date_create. Last modification: %date_change', + 'Additional Folders' => 'Additional Folders', + 'A content could be attached to more than one folder. Select here the additional fodlers for this content.' => 'A content could be attached to more than one folder. Select here the additional fodlers for this content.', + 'You can change the default folder (%title) in the "General" tab.' => 'You can change the default folder (%title) in the "General" tab.', + ' (default)' => ' (default)', + 'Select a folder and click (+) to add it to the additional folder list' => 'Select a folder and click (+) to add it to the additional folder list', + 'No Folders found' => 'No Folders found', + 'This product doesn\'t belong to any additional folder.' => 'This product doesn\'t belong to any additional folder.', + 'Remove associated folder' => 'Remove associated folder', + 'Do you really want to remove the content from this folder ?' => 'Do you really want to remove the content from this folder ?', + 'Remove the product from this category' => 'Remove the product from this category', + 'Coupon : ' => 'Coupon : ', + 'days left' => 'days left', + 'May be cumulative' => 'May be cumulative', + 'Won\'t remove postage' => 'Won\'t remove postage', + 'Will be available on special offers' => 'Will be available on special offers', + 'Application field' => 'Application field', + 'Do you really want to enable this element ?' => 'Do you really want to enable this element ?', + 'Confirmation' => 'Confirmation', + 'Confirm' => 'Confirm', + 'Create coupon' => 'Create coupon', + 'Create' => 'Create', + 'Please save your Coupon in oder to affect it some conditions' => 'Please save your Coupon in oder to affect it some conditions', + 'Do you really want to delete this element ?' => 'Do you really want to delete this element ?', + 'Thelia Product Templates' => 'Thelia Product Templates', + 'Thelia product templates' => 'Thelia product templates', + 'Add a new product template' => 'Add a new product template', + 'Change this template' => 'Change this template', + 'Change this product template' => 'Change this product template', + 'Delete this product template' => 'Delete this product template', + 'No product template has been created yet. Click the + button to create one.' => 'No product template has been created yet. Click the + button to create one.', + 'Template Name *' => 'Template Name *', + 'Template title' => 'Template title', + 'Enter here the template name in the default language (English)' => 'Enter here the template name in the default language (English)', + 'Create a new product template' => 'Create a new product template', + 'Create this product template' => 'Create this product template', + 'Delete template' => 'Delete template', + 'Do you really want to delete this template ? It will be removed from all products.' => 'Do you really want to delete this template ? It will be removed from all products.', + 'Select an feature...' => 'Select an feature...', + 'Select an feature and click (+) to add it to this template' => 'Select an feature and click (+) to add it to this template', + 'Feature title' => 'Feature title', + 'Delete this feature' => 'Delete this feature', + 'This template contains no features' => 'This template contains no features', + 'Remove feature' => 'Remove feature', + 'Do you really want to remove this feature from the template ?' => 'Do you really want to remove this feature from the template ?', + 'Thelia Product Attributes' => 'Thelia Product Attributes', + 'Thelia product attributes' => 'Thelia product attributes', + 'Add a new product attribute' => 'Add a new product attribute', + 'Change this attribute' => 'Change this attribute', + 'Remove this attribute from all product templates' => 'Remove this attribute from all product templates', + 'Add this attribute to all product templates' => 'Add this attribute to all product templates', + 'Change this product attribute' => 'Change this product attribute', + 'Delete this product attribute' => 'Delete this product attribute', + 'No product attribute has been created yet. Click the + button to create one.' => 'No product attribute has been created yet. Click the + button to create one.', + 'Title *' => 'Title *', + 'Attribute title' => 'Attribute title', + 'Enter here the attribute name in the default language (English)' => 'Enter here the attribute name in the default language (English)', + 'Check this box if you want to add this attributes to all product templates' => 'Check this box if you want to add this attributes to all product templates', + 'Create a new attribute' => 'Create a new attribute', + 'Create this attribute' => 'Create this attribute', + 'Delete attribute' => 'Delete attribute', + 'Do you really want to delete this attribute ? It will be removed from all product templates.' => 'Do you really want to delete this attribute ? It will be removed from all product templates.', + 'Add to all product templates' => 'Add to all product templates', + 'Do you really want to add this attribute to all product templates ?' => 'Do you really want to add this attribute to all product templates ?', + 'Remove from all product templates' => 'Remove from all product templates', + 'Do you really want to remove this attribute from all product templates ? You\'ll loose all product related data for this attribute.' => 'Do you really want to remove this attribute from all product templates ? You\'ll loose all product related data for this attribute.', + 'Enter new attribute position' => 'Enter new attribute position', + 'Edit an attribute' => 'Edit an attribute', + 'Attributes' => 'Attributes', + 'Editing attribute "%name"' => 'Editing attribute "%name"', + 'Edit attribute en_US : Officiis cumque.' => 'Edit attribute en_US : Officiis cumque.', + 'Attribute information' => 'Attribute information', + 'Attribute values' => 'Attribute values', + 'Enter here all possible attribute values.' => 'Enter here all possible attribute values.', + 'Delete this value' => 'Delete this value', + 'No value has been created yet. Click the + button to create one.' => 'No value has been created yet. Click the + button to create one.', + 'Sorry, attribute ID=1 was not found.' => 'Sorry, attribute ID=1 was not found.', + 'Enter here the value in the current edit language (English)' => 'Enter here the value in the current edit language (English)', + 'Create a new attribute value' => 'Create a new attribute value', + 'Create this value' => 'Create this value', + 'Delete attribute value' => 'Delete attribute value', + 'Do you really want to delete this attribute value ?' => 'Do you really want to delete this attribute value ?', + 'Enter new value position' => 'Enter new value position', + 'Thelia Product Features' => 'Thelia Product Features', + 'Thelia product features' => 'Thelia product features', + 'Add a new product feature' => 'Add a new product feature', + 'Change this feature' => 'Change this feature', + 'Remove this feature from all product templates' => 'Remove this feature from all product templates', + 'Add this feature to all product templates' => 'Add this feature to all product templates', + 'Change this product feature' => 'Change this product feature', + 'Delete this product feature' => 'Delete this product feature', + 'No product feature has been created yet. Click the + button to create one.' => 'No product feature has been created yet. Click the + button to create one.', + 'Enter here the feature name in the default language (English)' => 'Enter here the feature name in the default language (English)', + 'Check this box if you want to add this features to all product templates' => 'Check this box if you want to add this features to all product templates', + 'Create a new feature' => 'Create a new feature', + 'Create this feature' => 'Create this feature', + 'Delete feature' => 'Delete feature', + 'Do you really want to delete this feature ? It will be removed from all product templates.' => 'Do you really want to delete this feature ? It will be removed from all product templates.', + 'Do you really want to add this feature to all product templates ?' => 'Do you really want to add this feature to all product templates ?', + 'Do you really want to remove this feature from all product templates ? You\'ll loose all product related data for this feature.' => 'Do you really want to remove this feature from all product templates ? You\'ll loose all product related data for this feature.', + 'Enter new feature position' => 'Enter new feature position', + 'Edit a feature' => 'Edit a feature', + 'Features' => 'Features', + 'Editing feature "%name"' => 'Editing feature "%name"', + 'Edit feature en_US : Consectetur omnis.' => 'Edit feature en_US : Consectetur omnis.', + 'Feature information' => 'Feature information', + 'Feature values' => 'Feature values', + 'Enter here all possible feature values. To get a free text feature in product forms, don\'t add any value.' => 'Enter here all possible feature values. To get a free text feature in product forms, don\'t add any value.', + 'Sorry, feature ID=1 was not found.' => 'Sorry, feature ID=1 was not found.', + 'Create a new feature value' => 'Create a new feature value', + 'Delete feature value' => 'Delete feature value', + 'Do you really want to delete this feature value ?' => 'Do you really want to delete this feature value ?', + 'Thelia Mailing Templates' => 'Thelia Mailing Templates', + 'Thelia mailing templates' => 'Thelia mailing templates', + 'Add a new mailing template' => 'Add a new mailing template', + 'Change this mailing template' => 'Change this mailing template', + 'Delete this mailing template' => 'Delete this mailing template', + 'No mailing template has been created yet. Click the + button to create one.' => 'No mailing template has been created yet. Click the + button to create one.', + 'Mailing template name' => 'Mailing template name', + 'Mailing template purpose' => 'Mailing template purpose', + 'Enter here the mailing template purpose in the default language (English)' => 'Enter here the mailing template purpose in the default language (English)', + 'Create a new mailing template' => 'Create a new mailing template', + 'Create this mailing template' => 'Create this mailing template', + 'Delete mailing template' => 'Delete mailing template', + 'Do you really want to delete this mailing template ?' => 'Do you really want to delete this mailing template ?', + 'Edit a mailing template' => 'Edit a mailing template', + 'Editing mailing template "%name"' => 'Editing mailing template "%name"', + 'Edit mailing template order_confirmation' => 'Edit mailing template order_confirmation', + 'Prevent mailing template modification or deletion, except for super-admin' => 'Prevent mailing template modification or deletion, except for super-admin', + 'Message subject *' => 'Message subject *', + 'Subject' => 'Subject', + 'HTML Message' => 'HTML Message', + 'The mailing template in HTML format.' => 'The mailing template in HTML format.', + 'Text Message' => 'Text Message', + 'The mailing template in text-only format.' => 'The mailing template in text-only format.', + 'Message created on %date_create. Last modification: %date_change' => 'Message created on %date_create. Last modification: %date_change', + 'Sorry, message ID=1 was not found.' => 'Sorry, message ID=1 was not found.', + 'Update rates' => 'Update rates', + 'Add a new currency' => 'Add a new currency', + 'ISO 4217 Code' => 'ISO 4217 Code', + 'More information about ISO 4217' => 'More information about ISO 4217', + 'Symbol' => 'Symbol', + 'Rate in €' => 'Rate in €', + 'Change this currency' => 'Change this currency', + 'Delete this currency' => 'Delete this currency', + 'No currency has been created yet. Click the + button to create one.' => 'No currency has been created yet. Click the + button to create one.', + 'Currency name' => 'Currency name', + 'Enter here the currency name in the default language (English)' => 'Enter here the currency name in the default language (English)', + 'ISO 4217 code *' => 'ISO 4217 code *', + 'ISO 4217 code' => 'ISO 4217 code', + 'Symbol *' => 'Symbol *', + 'Currency symbol' => 'Currency symbol', + 'Rate from € *' => 'Rate from € *', + 'Currency rate' => 'Currency rate', + 'Rate' => 'Rate', + 'The rate from Euro (Price in Euro * rate = Price in this currency)' => 'The rate from Euro (Price in Euro * rate = Price in this currency)', + 'Create a new currency' => 'Create a new currency', + 'Create this currency' => 'Create this currency', + 'Delete currency' => 'Delete currency', + 'Do you really want to delete this currency ?' => 'Do you really want to delete this currency ?', + 'Enter new currency position' => 'Enter new currency position', + 'Edit a currency' => 'Edit a currency', + 'Editing currency "%name"' => 'Editing currency "%name"', + 'Edit currency Euro' => 'Edit currency Euro', + 'Currency ISO 4217 Code' => 'Currency ISO 4217 Code', + 'The symbol, such as $, £, €...' => 'The symbol, such as $, £, €...', + 'Rate from Euro' => 'Rate from Euro', + 'Sorry, currency ID=1 was not found.' => 'Sorry, currency ID=1 was not found.', + 'In order to manges your shop taxes you can manage' => 'In order to manges your shop taxes you can manage', + 'taxes' => 'taxes', + 'and' => 'and', + 'tax rules' => 'tax rules', + 'Taxes define the amount of money which is add to a bought product.' => 'Taxes define the amount of money which is add to a bought product.', + 'Example :' => 'Example :', + 'French 19.6% VAT is a tax which add a 19.6% tax to the product price.' => 'French 19.6% VAT is a tax which add a 19.6% tax to the product price.', + 'Ecotax is a tax wich add a defined amount (throug a product feature) to the product price.' => 'Ecotax is a tax wich add a defined amount (throug a product feature) to the product price.', + 'Tax rules are combination of different taxes.' => 'Tax rules are combination of different taxes.', + 'French 19.6% VAT with ecotax is the applicance of the ecotax (on the product price) then the applicance of the 19.6% tax (on the product price + the ecotax amount).' => 'French 19.6% VAT with ecotax is the applicance of the ecotax (on the product price) then the applicance of the 19.6% tax (on the product price + the ecotax amount).', + 'you can combine taxes in tax rules and chose if they are applied one after the other or at the same time : it allows to apply taxes on an already taxed price or not.' => 'you can combine taxes in tax rules and chose if they are applied one after the other or at the same time : it allows to apply taxes on an already taxed price or not.', + 'Taxes' => 'Taxes', + 'Create a new tax' => 'Create a new tax', + 'Change this tax' => 'Change this tax', + 'Delete this tax' => 'Delete this tax', + 'Create a new tax rule' => 'Create a new tax rule', + 'Change this tax rule' => 'Change this tax rule', + 'Set as default tax rule' => 'Set as default tax rule', + 'Delete this tax rule' => 'Delete this tax rule', + 'Type' => 'Type', + 'amount' => 'amount', + 'feature' => 'feature', + 'percent' => 'percent', + 'Delete tax' => 'Delete tax', + 'Do you really want to delete this tax ?' => 'Do you really want to delete this tax ?', + 'Delete tax rule' => 'Delete tax rule', + 'Do you really want to delete this tax rule ?' => 'Do you really want to delete this tax rule ?', + 'Edit a tax' => 'Edit a tax', + 'Editing tax' => 'Editing tax', + 'Tax created on %date_create. Last modification: %date_change' => 'Tax created on %date_create. Last modification: %date_change', + 'Edit a tax rule' => 'Edit a tax rule', + 'Editing tax rule' => 'Editing tax rule', + 'Tax rule created on %date_create. Last modification: %date_change' => 'Tax rule created on %date_create. Last modification: %date_change', + 'Manage taxes' => 'Manage taxes', + 'Choose a country' => 'Choose a country', + 'Countries that have the same tax rule' => 'Countries that have the same tax rule', + 'NONE' => 'NONE', + 'Manage the tax rule taxes appliance order' => 'Manage the tax rule taxes appliance order', + 'Add tax to this group' => 'Add tax to this group', + 'Drop tax here to create a tax group' => 'Drop tax here to create a tax group', + 'Drop tax here to delete from group' => 'Drop tax here to delete from group', + 'Tax rule taxes will be update for the following countries :' => 'Tax rule taxes will be update for the following countries :', + 'uncheck all' => 'uncheck all', + 'Update tax rule taxes' => 'Update tax rule taxes', + 'Edit tax rule taxes' => 'Edit tax rule taxes', + 'Add a new country' => 'Add a new country', + 'Shop' => 'Shop', + 'N° ISO' => 'N° ISO', + 'ISO Code' => 'ISO Code', + 'Change this country' => 'Change this country', + 'Delete this country' => 'Delete this country', + 'No country has been created yet. Click the + button to create one.' => 'No country has been created yet. Click the + button to create one.', + 'Country title *' => 'Country title *', + 'Country title' => 'Country title', + 'Country area' => 'Country area', + 'ISO Code *' => 'ISO Code *', + 'Alpha code 2 *' => 'Alpha code 2 *', + 'Alpha code 2' => 'Alpha code 2', + 'Alpha code 3 *' => 'Alpha code 3 *', + 'Alpha code 3' => 'Alpha code 3', + 'Create a new country' => 'Create a new country', + 'Create this country' => 'Create this country', + 'Delete country' => 'Delete country', + 'Do you really want to delete this country ?' => 'Do you really want to delete this country ?', + 'Error' => 'Error', + 'Impossible to change default country. Please contact your administrator or try later' => 'Impossible to change default country. Please contact your administrator or try later', + 'Edit a country' => 'Edit a country', + 'Editing country "%name"' => 'Editing country "%name"', + 'Edit country ' => 'Edit country ', + '' => '', + 'Country short description' => 'Country short description', + 'Country description' => 'Country description', + 'Sorry, country ID=190 was not found.' => 'Sorry, country ID=190 was not found.', + 'Edit country Afghanistan' => 'Edit country Afghanistan', + 'Sorry, country ID=1 was not found.' => 'Sorry, country ID=1 was not found.', + 'Thelia Shipping zones' => 'Thelia Shipping zones', + 'Change this shipping zone' => 'Change this shipping zone', + 'Edit a shipping zone' => 'Edit a shipping zone', + 'Editing shipping zone "%name"' => 'Editing shipping zone "%name"', + 'Edit shipping zone %title' => 'Edit shipping zone %title', + 'Add' => 'Add', + 'Zones' => 'Zones', + 'Delete this zone' => 'Delete this zone', + 'Remove zone' => 'Remove zone', + 'Do you really want to remove this zone ?' => 'Do you really want to remove this zone ?', + 'Thelia Shipping configuration' => 'Thelia Shipping configuration', + 'Add a new shipping configuration' => 'Add a new shipping configuration', + 'Change this shipping configuration' => 'Change this shipping configuration', + 'Delete this shipping configuration' => 'Delete this shipping configuration', + 'Shipping configuration name' => 'Shipping configuration name', + 'Create a new shipping configuration' => 'Create a new shipping configuration', + 'Create this shipping configuration' => 'Create this shipping configuration', + 'Delete shipping configuration' => 'Delete shipping configuration', + 'Do you really want to delete this shipping configuration ?' => 'Do you really want to delete this shipping configuration ?', + 'Edit a shipping configuration' => 'Edit a shipping configuration', + 'Editing shipping configuration "%name"' => 'Editing shipping configuration "%name"', + 'Edit shipping configuration %title' => 'Edit shipping configuration %title', + 'Add this country' => 'Add this country', + 'No area defined with this id' => 'No area defined with this id', + 'Remove country' => 'Remove country', + 'Do you really want to remove this country ?' => 'Do you really want to remove this country ?', + 'Classic modules' => 'Classic modules', + 'classic modules' => 'classic modules', + 'Enable/Disable' => 'Enable/Disable', + 'Deactivate %title module' => 'Deactivate %title module', + 'deactivation' => 'deactivation', + 'Edit this module' => 'Edit this module', + 'Delete this module' => 'Delete this module', + 'Delivery modules' => 'Delivery modules', + 'Payment modules' => 'Payment modules', + 'Delete a module' => 'Delete a module', + 'Do you really want to delete this module ?' => 'Do you really want to delete this module ?', + 'Edit a system variable' => 'Edit a system variable', + 'Editing variable "%name"' => 'Editing variable "%name"', + 'Edit variable active-template' => 'Edit variable active-template', + 'Prevent variable modification or deletion, except for super-admin' => 'Prevent variable modification or deletion, except for super-admin', + 'Variable created on %date_create. Last modification: %date_change' => 'Variable created on %date_create. Last modification: %date_change', + 'Sorry, variable ID=3 was not found.' => 'Sorry, variable ID=3 was not found.', + 'Profiles' => 'Profiles', + 'Create a new profile' => 'Create a new profile', + 'Profile Code' => 'Profile Code', + 'Profile code' => 'Profile code', + 'Postscriptum' => 'Postscriptum', + 'Delete profile' => 'Delete profile', + 'Do you really want to delete this profile ?' => 'Do you really want to delete this profile ?', + 'You can\'t delete this profile' => 'You can\'t delete this profile', + 'They are some administrator which are linked to this profile. Please edit/remove them before deleting this profile.' => 'They are some administrator which are linked to this profile. Please edit/remove them before deleting this profile.', + 'Create a new administrator' => 'Create a new administrator', + 'Login' => 'Login', + 'FirstName' => 'FirstName', + 'LastName' => 'LastName', + 'Profile' => 'Profile', + 'Superadministrator' => 'Superadministrator', + 'Change this administrator' => 'Change this administrator', + 'Password' => 'Password', + 'Password confirmation' => 'Password confirmation', + 'Leave empty to keep current password' => 'Leave empty to keep current password', + 'Update a new administrator' => 'Update a new administrator', + 'Delete administrator' => 'Delete administrator', + 'Do you really want to delete this administrator ?' => 'Do you really want to delete this administrator ?', + 'You can\'t delete this administrator' => 'You can\'t delete this administrator', + 'They are some administrator which are linked to this administrator. Please edit/remove them before deleting this administrator.' => 'They are some administrator which are linked to this administrator. Please edit/remove them before deleting this administrator.', + 'Thelia Languages' => 'Thelia Languages', + 'Languages' => 'Languages', + 'Languages management' => 'Languages management', + 'Add a new language' => 'Add a new language', + 'Language name' => 'Language name', + 'ISO 639 Code' => 'ISO 639 Code', + 'Locale' => 'Locale', + 'date form' => 'date form', + 'time form' => 'time form', + 'Change this language' => 'Change this language', + 'Delete this language' => 'Delete this language', + 'Parameters' => 'Parameters', + 'If a translation is missing or incomplete :' => 'If a translation is missing or incomplete :', + 'Using a domain or subdomain for each language' => 'Using a domain or subdomain for each language', + 'activate' => 'activate', + 'Language title' => 'Language title', + 'language locale' => 'language locale', + 'en_US' => 'en_US', + 'date format' => 'date format', + 'd-m-Y' => 'd-m-Y', + 'time format' => 'time format', + 'H:i:s' => 'H:i:s', + 'Create a new language' => 'Create a new language', + 'Create this language' => 'Create this language', + 'Delete language' => 'Delete language', + 'Do you really want to delete this language ?' => 'Do you really want to delete this language ?', + 'Impossible to change default languages. Please contact your administrator or try later' => 'Impossible to change default languages. Please contact your administrator or try later', + 'Edit a language' => 'Edit a language', + 'Edit this language' => 'Edit this language', + 'deactivate' => 'deactivate', + 'Thelia Mailing System' => 'Thelia Mailing System', + 'Configuration mailing system' => 'Configuration mailing system', + 'Enable remote SMTP use : ' => 'Enable remote SMTP use : ', + 'Host :' => 'Host :', + 'Host' => 'Host', + 'Port :' => 'Port :', + 'Port' => 'Port', + 'Encryption :' => 'Encryption :', + 'Encryption' => 'Encryption', + 'Username :' => 'Username :', + 'Username' => 'Username', + 'Password :' => 'Password :', + 'Auth Mode :' => 'Auth Mode :', + 'Auth Mode' => 'Auth Mode', + 'Timeout :' => 'Timeout :', + 'Timeout' => 'Timeout', + 'Source IP :' => 'Source IP :', + 'Source IP' => 'Source IP', + 'Show logs' => 'Show logs', + 'Period' => 'Period', + 'From' => 'From', + 'To' => 'To', + 'Resources' => 'Resources', + 'company' => 'company', +) +; \ No newline at end of file diff --git a/templates/admin/default/I18n/es_ES.php b/templates/admin/default/I18n/es_ES.php old mode 100644 new mode 100755 index 7eb24949a..6884502b9 --- a/templates/admin/default/I18n/es_ES.php +++ b/templates/admin/default/I18n/es_ES.php @@ -1,26 +1,808 @@ . */ -/* */ -/*************************************************************************************/ -return array( - -); \ No newline at end of file +return array ( + 'Lire la suite' => '', + 'Back-office home' => '', + 'Thelia Back Office' => '', + 'Version %ver' => '', + 'View site' => '', + 'View shop' => '', + 'Profil' => '', + 'Close administation session' => '', + 'Logout' => '', + 'Home' => '', + 'Customers' => '', + 'Orders' => '', + 'All orders' => '', + 'Catalog' => '', + 'Folders' => '', + 'Coupons' => '', + 'Configuration' => '', + 'Modules' => '', + 'Search' => '', + 'Thelia, solution e-commerce libre' => '', + 'Dashboard' => '', + 'Sales' => '', + 'New customers' => '', + 'First orders' => '', + 'Aborted orders' => '', + 'Shop Informations' => '', + 'Categories' => '', + 'Products' => '', + 'Online products' => '', + 'Offline products' => '', + 'Pending orders' => '', + 'In process orderst' => '', + 'Shipped orders' => '', + 'Canceled orders' => '', + 'Sales statistics' => '', + 'Today' => '', + 'This month' => '', + 'This year' => '', + 'Overall sales' => '', + 'Sales excluding shipping' => '', + 'Yesterday sales' => '', + 'Waiting orders' => '', + 'In process orders' => '', + 'Average cart' => '', + 'Previous month sales' => '', + 'Previous year sales' => '', + 'Thelia informations' => '', + 'Current version' => '', + 'Latest version available' => '', + 'News' => '', + 'Click here' => '', + '© Thelia 2013' => '', + 'Édité par OpenStudio' => '', + 'Forum Thelia' => '', + 'Contributions Thelia' => '', + 'Customer' => '', + 'Customers list' => '', + 'Add a new Customer' => '', + 'customer ref' => '', + 'firstname & lastname' => '', + 'last order' => '', + 'order amount' => '', + 'Actions' => '', + 'Edit this customer' => '', + 'Send a mail to this customer' => '', + 'Delete this customer and all his orders' => '', + 'Company Name' => '', + 'Company' => '', + 'Title' => '', + 'First Name' => '', + 'Firstname' => '', + 'Last Name' => '', + 'Lastname' => '', + 'Street Address' => '', + 'Address' => '', + 'Address Line 2' => '', + 'Additional address' => '', + 'Address Line 3' => '', + 'Zip code' => '', + 'City' => '', + 'Country' => '', + 'Email Address' => '', + 'Email address' => '', + 'Create a new customer' => '', + 'Create this customer' => '', + 'Cancel' => '', + 'OK' => '', + 'Delete customer' => '', + 'Do you really want to delete this customer ?' => '', + 'No' => '', + 'Yes' => '', + 'Thelia configuration' => '', + 'Product catalog configuration' => '', + 'Product templates' => '', + 'Product attributes' => '', + 'Product features' => '', + 'Mailing templates' => '', + 'Currencies' => '', + 'Taxes rules' => '', + 'Shipping configuration' => '', + 'Countries' => '', + 'Shipping zones' => '', + 'System parameters' => '', + 'Modules activation' => '', + 'System variables' => '', + 'Administration profiles' => '', + 'Administrators' => '', + 'Languages & URLs' => '', + 'Mailing system' => '', + 'Administration logs' => '', + 'System logs' => '', + 'Thelia System Variables' => '', + 'Thelia system variables' => '', + 'Add a new variable' => '', + 'Save chages' => '', + 'Save changes' => '', + 'Purpose' => '', + 'Name' => '', + 'Value' => '', + 'Action' => '', + 'Change this variable' => '', + 'Cancel changes and revert to original value' => '', + 'Delete this variable' => '', + 'Name *' => '', + 'Variable name' => '', + 'Value *' => '', + 'Variable value' => '', + 'Purpose *' => '', + 'Variable purpose' => '', + 'English' => '', + 'Enter here the category name in the default language (%title)' => '', + 'Create a new variable' => '', + 'Create this variable' => '', + 'Delete a variable' => '', + 'Do you really want to delete this variable ?' => '', + 'Coupon' => '', + 'Browse' => '', + 'Coupons : ' => '', + 'List' => '', + 'Create a new coupon' => '', + 'Enabled coupons' => '', + 'Code' => '', + 'Days before expiration' => '', + 'Usage left' => '', + 'Edit' => '', + 'Unlimited' => '', + 'Disabled coupons' => '', + 'Expiration date' => '', + 'Update coupon' => '', + 'Update' => '', + 'Code :' => '', + 'code' => '', + 'Title :' => '', + 'title' => '', + 'Is enabled' => '', + 'Is available on special offers' => '', + 'Is cumulative' => '', + 'Is removing postage' => '', + 'Expiration date :' => '', + 'yyyy-mm-dd' => '', + 'Is unlimited' => '', + 'Max usage :' => '', + 'max usage' => '', + 'Type :' => '', + 'Please select a coupon type' => '', + 'Amount :' => '', + '14.50' => '', + 'Short description :' => '', + 'short description' => '', + 'Long description :' => '', + 'long description' => '', + 'Save your modifications' => '', + 'Conditions' => '', + 'Delete' => '', + 'And' => '', + 'Save this condition' => '', + 'Condition\'s category :' => '', + 'Please select a condition category' => '', + 'Files manager' => '', + 'Please retry' => '', + 'Please select another condition' => '', + 'Edit a customer' => '', + 'Editing customer "%name"' => '', + 'Edit customer thelia thelia' => '', + 'Save' => '', + 'Save and close' => '', + 'Customer informations' => '', + 'Default address' => '', + 'Other addresses' => '', + 'Add a new address' => '', + 'Phone' => '', + 'cell phone' => '', + 'Edit this address' => '', + 'Use this address by default' => '', + 'orders for this customer' => '', + 'Order n°' => '', + 'Date & Hour' => '', + 'Amount' => '', + 'Status' => '', + 'Sorry, customer ID=1 was not found.' => '', + 'Address label' => '', + 'Label' => '', + 'Create an address' => '', + 'Create this address' => '', + 'Use address by default' => '', + 'Do you really want to use this address by default ?' => '', + 'Delete address' => '', + 'Do you really want to delete this address ?' => '', + 'Edit an address' => '', + 'Edit this order' => '', + 'Cancel this order' => '', + 'Delete an order' => '', + 'Do you really want to cancel this order ?' => '', + 'Edit an order' => '', + 'Ordered products' => '', + 'Invoice and Delivery' => '', + 'Cart' => '', + 'Product' => '', + 'Unit. price' => '', + 'Tax' => '', + 'Unit taxed price' => '', + 'Quantity' => '', + 'Taxed total' => '', + 'Total without discount' => '', + 'Discount' => '', + 'Coupon code' => '', + 'Total including discount' => '', + 'Postage' => '', + 'Total' => '', + 'Payment information' => '', + 'Payment module' => '', + 'Transaction reference' => '', + 'Delivery module' => '', + 'tracking reference' => '', + 'Description' => '', + 'Invoice informations' => '', + 'Download invoice as PDF' => '', + 'PDF | Invoice' => '', + 'Edit invoice address' => '', + 'Invoice reference' => '', + 'Invoice date' => '', + 'Street address' => '', + 'Delivery address' => '', + 'Download purchase order as PDF' => '', + 'PDF | Purchase order' => '', + 'Edit delivery address' => '', + 'Compagny' => '', + 'Edit order address' => '', + 'Confirm changes' => '', + 'Top level categories' => '', + 'Add a new category' => '', + 'ID' => '', + 'Category title' => '', + 'Online' => '', + 'Position' => '', + 'Browse this category' => '', + 'Edit this category' => '', + 'Delete this category and all its contents' => '', + 'This category has no sub-categories. To create a new one, click the + button above.' => '', + 'This category has no sub-categories.' => '', + 'Top level Products' => '', + 'Add a new product' => '', + 'Reference' => '', + 'Product title' => '', + 'This category doesn\'t contains any products. To add a new product, click the + button above.' => '', + 'Create a new category' => '', + 'Create this category' => '', + 'Enter here the product reference' => '', + 'Enter here the product name in the default language (%title)' => '', + 'Product price' => '', + 'Enter here the product price in the default currency (%title)' => '', + 'Select a tax tule' => '', + 'Select here the tax applicable to this product' => '', + 'Product weight' => '', + 'Kg' => '', + 'Enter here the product weight, in Kilogrammes' => '', + 'Create a new product' => '', + 'Create this product' => '', + 'Delete category' => '', + 'Do you really want to delete this category and all its content ?' => '', + 'Delete product' => '', + 'Do you really want to delete this product ?' => '', + 'Enter new category position' => '', + 'Enter new product position' => '', + 'Edit category' => '', + 'Editing %cat' => '', + 'Edit category %title' => '', + 'Preview category page' => '', + 'Edit next category' => '', + 'General description' => '', + 'Associations' => '', + 'Images' => '', + 'Documents' => '', + 'Edit information in %lng' => '', + 'Français' => '', + 'castellano' => '', + 'Italiano' => '', + 'Close' => '', + 'Category title *' => '', + 'Summary' => '', + 'A short description, used when a summary or an introduction is required' => '', + 'Short description' => '', + 'Detailed description' => '', + 'The detailed description.' => '', + 'Conclusion' => '', + 'A short post-description information' => '', + 'Short conclusion' => '', + 'Rewriten URL *' => '', + 'Rewritten URL' => '', + 'Rewriten URL' => '', + 'Parent category *' => '', + 'Top level' => '', + 'Visibility' => '', + 'Category created on %date_create. Last modification: %date_change' => '', + 'Related content' => '', + 'You can attach here some content to this category' => '', + 'Select a folder...' => '', + 'Select a folder to get its content' => '', + 'Select a folder content...' => '', + 'Select a content and click (+) to add it to this category' => '', + 'No available content in this folder' => '', + 'No folders found' => '', + 'Content title' => '', + 'This category contains no contents' => '', + 'Send files' => '', + 'Drop files to upload' => '', + 'Browse files' => '', + 'Update this image' => '', + 'There is no images attached to this %type.' => '', + 'Can\'t load images, please refresh this page.' => '', + 'There is no documents attached to this %type.' => '', + 'Can\'t load documents, please refresh this page.' => '', + 'Remove related content' => '', + 'Do you really want to remove this related content ?' => '', + '(edit)' => '', + 'Categories in %cat' => '', + 'Products in %cat' => '', + 'Edit this product' => '', + 'Delete this product' => '', + 'Edit product' => '', + 'Editing %title' => '', + 'Edit product %title' => '', + 'Preview product page' => '', + 'General' => '', + 'Details' => '', + 'Attributes & Features' => '', + 'Product reference' => '', + 'Product title *' => '', + 'Default product category *' => '', + 'You can attach this product to more categories in the details tab.' => '', + 'Product created on %date_create. Last modification: %date_change' => '', + 'Edit prices in %curr' => '', + 'Attribute Combinations' => '', + 'Quickly create combinations using the combination builder' => '', + 'Combination builder' => '', + 'Add a new combination' => '', + 'EAN Code' => '', + 'Price
w/o taxes (%currency)' => '', + 'Price
w/ taxes (%currency)' => '', + 'Weight
(Kg)' => '', + 'Default' => '', + 'Sale' => '', + 'New' => '', + 'Sale price
w/o taxes (%currency)' => '', + 'Sale price
w/ taxes (%currency)' => '', + 'Delete this combination' => '', + 'Attribute' => '', + 'Select an attribute...' => '', + 'Select an attribute and click (+) to view available values' => '', + 'Select an attribute value...' => '', + 'Select a value click (+) to add it to the combination' => '', + 'No available value for this attribute' => '', + 'To remove a value from the combination, select it and click "remove"' => '', + 'Remove selected values' => '', + 'Create a new combination' => '', + 'Create this combination' => '', + 'Delete a combination' => '', + 'Do you really want to delete this combination ?' => '', + 'Select attribute values to combine. You may enter a default value for some of the fields of the generated combinations.' => '', + 'Price excl. taxes' => '', + 'Combination reference' => '', + 'Combination EAN Code' => '', + 'Current quantity' => '', + '0 combinations' => '', + 'Create combinations' => '', + 'Please wait, loading' => '', + 'Failed to get converted prices. Please try again.' => '', + 'Failed to get prices. Please try again.' => '', + 'Existing combinations will be deleted. Do you want to continue ?' => '', + 'To use features or attributes on this product, please select a product template. You can define product templates in the configuration section of the administration.' => '', + 'Current product template' => '', + 'Do not use a product template' => '', + 'Apply' => '', + 'Product Attributes' => '', + 'You can change template attributes and their positions in the template configuration page.' => '', + 'Attribute Name' => '', + 'This product template does not contains any features' => '', + 'Product Features' => '', + 'You can change templates features and their positions in the template configuration page.' => '', + 'Feature Name' => '', + 'Feature value for this product' => '', + 'Use Ctrl+click to select more than one value. You can also clear selected values.' => '', + 'Enter here the feature value as free text' => '', + 'Feature value' => '', + 'Top level folders' => '', + 'Add a new folder' => '', + 'Folder title' => '', + 'Browse this folder' => '', + 'Edit this folder' => '', + 'Delete this folder and all its contents' => '', + 'This folder has no sub-folders. To create a new one, click the + button above.' => '', + 'This folder has no sub-folders.' => '', + 'Top level Contents' => '', + 'Add a new content' => '', + 'This folder doesn\'t contains any contents. To add a new content, click the + button above.' => '', + 'Enter here the folder name in the default language (%title)' => '', + 'Create a new folder' => '', + 'Create this folder' => '', + 'Enter here the content name in the default language (%title)' => '', + 'Create a new content' => '', + 'Create this content' => '', + 'Delete folder' => '', + 'Do you really want to delete this folder and all its content ?' => '', + 'Delete content' => '', + 'Do you really want to delete this content ?' => '', + 'Enter new folder position' => '', + 'Enter new content position' => '', + 'An error occured' => '', + 'Oops! An Error Occurred' => '', + 'Go to administration home' => '', + 'Folders in %fold' => '', + 'Contents in %fold' => '', + 'Edit this content' => '', + 'Delete this content' => '', + 'Edit content' => '', + 'Edit content %title' => '', + 'Preview folder page' => '', + 'Content title *' => '', + 'Default folder *' => '', + 'Folder created on %date_create. Last modification: %date_change' => '', + 'Additional Folders' => '', + 'A content could be attached to more than one folder. Select here the additional fodlers for this content.' => '', + 'You can change the default folder (%title) in the "General" tab.' => '', + ' (default)' => '', + 'Select a folder and click (+) to add it to the additional folder list' => '', + 'No Folders found' => '', + 'This product doesn\'t belong to any additional folder.' => '', + 'Remove associated folder' => '', + 'Do you really want to remove the content from this folder ?' => '', + 'Remove the product from this category' => '', + 'Coupon : ' => '', + 'days left' => '', + 'May be cumulative' => '', + 'Won\'t remove postage' => '', + 'Will be available on special offers' => '', + 'Application field' => '', + 'Do you really want to enable this element ?' => '', + 'Confirmation' => '', + 'Confirm' => '', + 'Create coupon' => '', + 'Create' => '', + 'Please save your Coupon in oder to affect it some conditions' => '', + 'Do you really want to delete this element ?' => '', + 'Thelia Product Templates' => '', + 'Thelia product templates' => '', + 'Add a new product template' => '', + 'Change this template' => '', + 'Change this product template' => '', + 'Delete this product template' => '', + 'No product template has been created yet. Click the + button to create one.' => '', + 'Template Name *' => '', + 'Template title' => '', + 'Enter here the template name in the default language (English)' => '', + 'Create a new product template' => '', + 'Create this product template' => '', + 'Delete template' => '', + 'Do you really want to delete this template ? It will be removed from all products.' => '', + 'Select an feature...' => '', + 'Select an feature and click (+) to add it to this template' => '', + 'Feature title' => '', + 'Delete this feature' => '', + 'This template contains no features' => '', + 'Remove feature' => '', + 'Do you really want to remove this feature from the template ?' => '', + 'Thelia Product Attributes' => '', + 'Thelia product attributes' => '', + 'Add a new product attribute' => '', + 'Change this attribute' => '', + 'Remove this attribute from all product templates' => '', + 'Add this attribute to all product templates' => '', + 'Change this product attribute' => '', + 'Delete this product attribute' => '', + 'No product attribute has been created yet. Click the + button to create one.' => '', + 'Title *' => '', + 'Attribute title' => '', + 'Enter here the attribute name in the default language (English)' => '', + 'Check this box if you want to add this attributes to all product templates' => '', + 'Create a new attribute' => '', + 'Create this attribute' => '', + 'Delete attribute' => '', + 'Do you really want to delete this attribute ? It will be removed from all product templates.' => '', + 'Add to all product templates' => '', + 'Do you really want to add this attribute to all product templates ?' => '', + 'Remove from all product templates' => '', + 'Do you really want to remove this attribute from all product templates ? You\'ll loose all product related data for this attribute.' => '', + 'Enter new attribute position' => '', + 'Edit an attribute' => '', + 'Attributes' => '', + 'Editing attribute "%name"' => '', + 'Edit attribute en_US : Officiis cumque.' => '', + 'Attribute information' => '', + 'Attribute values' => '', + 'Enter here all possible attribute values.' => '', + 'Delete this value' => '', + 'No value has been created yet. Click the + button to create one.' => '', + 'Sorry, attribute ID=1 was not found.' => '', + 'Enter here the value in the current edit language (English)' => '', + 'Create a new attribute value' => '', + 'Create this value' => '', + 'Delete attribute value' => '', + 'Do you really want to delete this attribute value ?' => '', + 'Enter new value position' => '', + 'Thelia Product Features' => '', + 'Thelia product features' => '', + 'Add a new product feature' => '', + 'Change this feature' => '', + 'Remove this feature from all product templates' => '', + 'Add this feature to all product templates' => '', + 'Change this product feature' => '', + 'Delete this product feature' => '', + 'No product feature has been created yet. Click the + button to create one.' => '', + 'Enter here the feature name in the default language (English)' => '', + 'Check this box if you want to add this features to all product templates' => '', + 'Create a new feature' => '', + 'Create this feature' => '', + 'Delete feature' => '', + 'Do you really want to delete this feature ? It will be removed from all product templates.' => '', + 'Do you really want to add this feature to all product templates ?' => '', + 'Do you really want to remove this feature from all product templates ? You\'ll loose all product related data for this feature.' => '', + 'Enter new feature position' => '', + 'Edit a feature' => '', + 'Features' => '', + 'Editing feature "%name"' => '', + 'Edit feature en_US : Consectetur omnis.' => '', + 'Feature information' => '', + 'Feature values' => '', + 'Enter here all possible feature values. To get a free text feature in product forms, don\'t add any value.' => '', + 'Sorry, feature ID=1 was not found.' => '', + 'Create a new feature value' => '', + 'Delete feature value' => '', + 'Do you really want to delete this feature value ?' => '', + 'Thelia Mailing Templates' => '', + 'Thelia mailing templates' => '', + 'Add a new mailing template' => '', + 'Change this mailing template' => '', + 'Delete this mailing template' => '', + 'No mailing template has been created yet. Click the + button to create one.' => '', + 'Mailing template name' => '', + 'Mailing template purpose' => '', + 'Enter here the mailing template purpose in the default language (English)' => '', + 'Create a new mailing template' => '', + 'Create this mailing template' => '', + 'Delete mailing template' => '', + 'Do you really want to delete this mailing template ?' => '', + 'Edit a mailing template' => '', + 'Editing mailing template "%name"' => '', + 'Edit mailing template order_confirmation' => '', + 'Prevent mailing template modification or deletion, except for super-admin' => '', + 'Message subject *' => '', + 'Subject' => '', + 'HTML Message' => '', + 'The mailing template in HTML format.' => '', + 'Text Message' => '', + 'The mailing template in text-only format.' => '', + 'Message created on %date_create. Last modification: %date_change' => '', + 'Sorry, message ID=1 was not found.' => '', + 'Update rates' => '', + 'Add a new currency' => '', + 'ISO 4217 Code' => '', + 'More information about ISO 4217' => '', + 'Symbol' => '', + 'Rate in €' => '', + 'Change this currency' => '', + 'Delete this currency' => '', + 'No currency has been created yet. Click the + button to create one.' => '', + 'Currency name' => '', + 'Enter here the currency name in the default language (English)' => '', + 'ISO 4217 code *' => '', + 'ISO 4217 code' => '', + 'Symbol *' => '', + 'Currency symbol' => '', + 'Rate from € *' => '', + 'Currency rate' => '', + 'Rate' => '', + 'The rate from Euro (Price in Euro * rate = Price in this currency)' => '', + 'Create a new currency' => '', + 'Create this currency' => '', + 'Delete currency' => '', + 'Do you really want to delete this currency ?' => '', + 'Enter new currency position' => '', + 'Edit a currency' => '', + 'Editing currency "%name"' => '', + 'Edit currency Euro' => '', + 'Currency ISO 4217 Code' => '', + 'The symbol, such as $, £, €...' => '', + 'Rate from Euro' => '', + 'Sorry, currency ID=1 was not found.' => '', + 'In order to manges your shop taxes you can manage' => '', + 'taxes' => '', + 'and' => '', + 'tax rules' => '', + 'Taxes define the amount of money which is add to a bought product.' => '', + 'Example :' => '', + 'French 19.6% VAT is a tax which add a 19.6% tax to the product price.' => '', + 'Ecotax is a tax wich add a defined amount (throug a product feature) to the product price.' => '', + 'Tax rules are combination of different taxes.' => '', + 'French 19.6% VAT with ecotax is the applicance of the ecotax (on the product price) then the applicance of the 19.6% tax (on the product price + the ecotax amount).' => '', + 'you can combine taxes in tax rules and chose if they are applied one after the other or at the same time : it allows to apply taxes on an already taxed price or not.' => '', + 'Taxes' => '', + 'Create a new tax' => '', + 'Change this tax' => '', + 'Delete this tax' => '', + 'Create a new tax rule' => '', + 'Change this tax rule' => '', + 'Set as default tax rule' => '', + 'Delete this tax rule' => '', + 'Type' => '', + 'amount' => '', + 'feature' => '', + 'percent' => '', + 'Delete tax' => '', + 'Do you really want to delete this tax ?' => '', + 'Delete tax rule' => '', + 'Do you really want to delete this tax rule ?' => '', + 'Edit a tax' => '', + 'Editing tax' => '', + 'Tax created on %date_create. Last modification: %date_change' => '', + 'Edit a tax rule' => '', + 'Editing tax rule' => '', + 'Tax rule created on %date_create. Last modification: %date_change' => '', + 'Manage taxes' => '', + 'Choose a country' => '', + 'Countries that have the same tax rule' => '', + 'NONE' => '', + 'Manage the tax rule taxes appliance order' => '', + 'Add tax to this group' => '', + 'Drop tax here to create a tax group' => '', + 'Drop tax here to delete from group' => '', + 'Tax rule taxes will be update for the following countries :' => '', + 'uncheck all' => '', + 'Update tax rule taxes' => '', + 'Edit tax rule taxes' => '', + 'Add a new country' => '', + 'Shop' => '', + 'N° ISO' => '', + 'ISO Code' => '', + 'Change this country' => '', + 'Delete this country' => '', + 'No country has been created yet. Click the + button to create one.' => '', + 'Country title *' => '', + 'Country title' => '', + 'Country area' => '', + 'ISO Code *' => '', + 'Alpha code 2 *' => '', + 'Alpha code 2' => '', + 'Alpha code 3 *' => '', + 'Alpha code 3' => '', + 'Create a new country' => '', + 'Create this country' => '', + 'Delete country' => '', + 'Do you really want to delete this country ?' => '', + 'Error' => '', + 'Impossible to change default country. Please contact your administrator or try later' => '', + 'Edit a country' => '', + 'Editing country "%name"' => '', + 'Edit country ' => '', + '' => '', + 'Country short description' => '', + 'Country description' => '', + 'Sorry, country ID=190 was not found.' => '', + 'Edit country Afghanistan' => '', + 'Sorry, country ID=1 was not found.' => '', + 'Thelia Shipping zones' => '', + 'Change this shipping zone' => '', + 'Edit a shipping zone' => '', + 'Editing shipping zone "%name"' => '', + 'Edit shipping zone %title' => '', + 'Add' => '', + 'Zones' => '', + 'Delete this zone' => '', + 'Remove zone' => '', + 'Do you really want to remove this zone ?' => '', + 'Thelia Shipping configuration' => '', + 'Add a new shipping configuration' => '', + 'Change this shipping configuration' => '', + 'Delete this shipping configuration' => '', + 'Shipping configuration name' => '', + 'Create a new shipping configuration' => '', + 'Create this shipping configuration' => '', + 'Delete shipping configuration' => '', + 'Do you really want to delete this shipping configuration ?' => '', + 'Edit a shipping configuration' => '', + 'Editing shipping configuration "%name"' => '', + 'Edit shipping configuration %title' => '', + 'Add this country' => '', + 'No area defined with this id' => '', + 'Remove country' => '', + 'Do you really want to remove this country ?' => '', + 'Classic modules' => '', + 'classic modules' => '', + 'Enable/Disable' => '', + 'Deactivate %title module' => '', + 'deactivation' => '', + 'Edit this module' => '', + 'Delete this module' => '', + 'Delivery modules' => '', + 'Payment modules' => '', + 'Delete a module' => '', + 'Do you really want to delete this module ?' => '', + 'Edit a system variable' => '', + 'Editing variable "%name"' => '', + 'Edit variable active-template' => '', + 'Prevent variable modification or deletion, except for super-admin' => '', + 'Variable created on %date_create. Last modification: %date_change' => '', + 'Sorry, variable ID=3 was not found.' => '', + 'Profiles' => '', + 'Create a new profile' => '', + 'Profile Code' => '', + 'Profile code' => '', + 'Postscriptum' => '', + 'Delete profile' => '', + 'Do you really want to delete this profile ?' => '', + 'You can\'t delete this profile' => '', + 'They are some administrator which are linked to this profile. Please edit/remove them before deleting this profile.' => '', + 'Create a new administrator' => '', + 'Login' => '', + 'FirstName' => '', + 'LastName' => '', + 'Profile' => '', + 'Superadministrator' => '', + 'Change this administrator' => '', + 'Password' => '', + 'Password confirmation' => '', + 'Leave empty to keep current password' => '', + 'Update a new administrator' => '', + 'Delete administrator' => '', + 'Do you really want to delete this administrator ?' => '', + 'You can\'t delete this administrator' => '', + 'They are some administrator which are linked to this administrator. Please edit/remove them before deleting this administrator.' => '', + 'Thelia Languages' => '', + 'Languages' => '', + 'Languages management' => '', + 'Add a new language' => '', + 'Language name' => '', + 'ISO 639 Code' => '', + 'Locale' => '', + 'date form' => '', + 'time form' => '', + 'Change this language' => '', + 'Delete this language' => '', + 'Parameters' => '', + 'If a translation is missing or incomplete :' => '', + 'Using a domain or subdomain for each language' => '', + 'activate' => '', + 'Language title' => '', + 'language locale' => '', + 'en_US' => '', + 'date format' => '', + 'd-m-Y' => '', + 'time format' => '', + 'H:i:s' => '', + 'Create a new language' => '', + 'Create this language' => '', + 'Delete language' => '', + 'Do you really want to delete this language ?' => '', + 'Impossible to change default languages. Please contact your administrator or try later' => '', + 'Edit a language' => '', + 'Edit this language' => '', + 'deactivate' => '', + 'Thelia Mailing System' => '', + 'Configuration mailing system' => '', + 'Enable remote SMTP use : ' => '', + 'Host :' => '', + 'Host' => '', + 'Port :' => '', + 'Port' => '', + 'Encryption :' => '', + 'Encryption' => '', + 'Username :' => '', + 'Username' => '', + 'Password :' => '', + 'Auth Mode :' => '', + 'Auth Mode' => '', + 'Timeout :' => '', + 'Timeout' => '', + 'Source IP :' => '', + 'Source IP' => '', + 'Show logs' => '', + 'Period' => '', + 'From' => '', + 'To' => '', + 'Resources' => '', + 'company' => '', +) +; \ No newline at end of file diff --git a/templates/admin/default/I18n/fr_FR.php b/templates/admin/default/I18n/fr_FR.php old mode 100644 new mode 100755 index 7eb24949a..6884502b9 --- a/templates/admin/default/I18n/fr_FR.php +++ b/templates/admin/default/I18n/fr_FR.php @@ -1,26 +1,808 @@ . */ -/* */ -/*************************************************************************************/ -return array( - -); \ No newline at end of file +return array ( + 'Lire la suite' => '', + 'Back-office home' => '', + 'Thelia Back Office' => '', + 'Version %ver' => '', + 'View site' => '', + 'View shop' => '', + 'Profil' => '', + 'Close administation session' => '', + 'Logout' => '', + 'Home' => '', + 'Customers' => '', + 'Orders' => '', + 'All orders' => '', + 'Catalog' => '', + 'Folders' => '', + 'Coupons' => '', + 'Configuration' => '', + 'Modules' => '', + 'Search' => '', + 'Thelia, solution e-commerce libre' => '', + 'Dashboard' => '', + 'Sales' => '', + 'New customers' => '', + 'First orders' => '', + 'Aborted orders' => '', + 'Shop Informations' => '', + 'Categories' => '', + 'Products' => '', + 'Online products' => '', + 'Offline products' => '', + 'Pending orders' => '', + 'In process orderst' => '', + 'Shipped orders' => '', + 'Canceled orders' => '', + 'Sales statistics' => '', + 'Today' => '', + 'This month' => '', + 'This year' => '', + 'Overall sales' => '', + 'Sales excluding shipping' => '', + 'Yesterday sales' => '', + 'Waiting orders' => '', + 'In process orders' => '', + 'Average cart' => '', + 'Previous month sales' => '', + 'Previous year sales' => '', + 'Thelia informations' => '', + 'Current version' => '', + 'Latest version available' => '', + 'News' => '', + 'Click here' => '', + '© Thelia 2013' => '', + 'Édité par OpenStudio' => '', + 'Forum Thelia' => '', + 'Contributions Thelia' => '', + 'Customer' => '', + 'Customers list' => '', + 'Add a new Customer' => '', + 'customer ref' => '', + 'firstname & lastname' => '', + 'last order' => '', + 'order amount' => '', + 'Actions' => '', + 'Edit this customer' => '', + 'Send a mail to this customer' => '', + 'Delete this customer and all his orders' => '', + 'Company Name' => '', + 'Company' => '', + 'Title' => '', + 'First Name' => '', + 'Firstname' => '', + 'Last Name' => '', + 'Lastname' => '', + 'Street Address' => '', + 'Address' => '', + 'Address Line 2' => '', + 'Additional address' => '', + 'Address Line 3' => '', + 'Zip code' => '', + 'City' => '', + 'Country' => '', + 'Email Address' => '', + 'Email address' => '', + 'Create a new customer' => '', + 'Create this customer' => '', + 'Cancel' => '', + 'OK' => '', + 'Delete customer' => '', + 'Do you really want to delete this customer ?' => '', + 'No' => '', + 'Yes' => '', + 'Thelia configuration' => '', + 'Product catalog configuration' => '', + 'Product templates' => '', + 'Product attributes' => '', + 'Product features' => '', + 'Mailing templates' => '', + 'Currencies' => '', + 'Taxes rules' => '', + 'Shipping configuration' => '', + 'Countries' => '', + 'Shipping zones' => '', + 'System parameters' => '', + 'Modules activation' => '', + 'System variables' => '', + 'Administration profiles' => '', + 'Administrators' => '', + 'Languages & URLs' => '', + 'Mailing system' => '', + 'Administration logs' => '', + 'System logs' => '', + 'Thelia System Variables' => '', + 'Thelia system variables' => '', + 'Add a new variable' => '', + 'Save chages' => '', + 'Save changes' => '', + 'Purpose' => '', + 'Name' => '', + 'Value' => '', + 'Action' => '', + 'Change this variable' => '', + 'Cancel changes and revert to original value' => '', + 'Delete this variable' => '', + 'Name *' => '', + 'Variable name' => '', + 'Value *' => '', + 'Variable value' => '', + 'Purpose *' => '', + 'Variable purpose' => '', + 'English' => '', + 'Enter here the category name in the default language (%title)' => '', + 'Create a new variable' => '', + 'Create this variable' => '', + 'Delete a variable' => '', + 'Do you really want to delete this variable ?' => '', + 'Coupon' => '', + 'Browse' => '', + 'Coupons : ' => '', + 'List' => '', + 'Create a new coupon' => '', + 'Enabled coupons' => '', + 'Code' => '', + 'Days before expiration' => '', + 'Usage left' => '', + 'Edit' => '', + 'Unlimited' => '', + 'Disabled coupons' => '', + 'Expiration date' => '', + 'Update coupon' => '', + 'Update' => '', + 'Code :' => '', + 'code' => '', + 'Title :' => '', + 'title' => '', + 'Is enabled' => '', + 'Is available on special offers' => '', + 'Is cumulative' => '', + 'Is removing postage' => '', + 'Expiration date :' => '', + 'yyyy-mm-dd' => '', + 'Is unlimited' => '', + 'Max usage :' => '', + 'max usage' => '', + 'Type :' => '', + 'Please select a coupon type' => '', + 'Amount :' => '', + '14.50' => '', + 'Short description :' => '', + 'short description' => '', + 'Long description :' => '', + 'long description' => '', + 'Save your modifications' => '', + 'Conditions' => '', + 'Delete' => '', + 'And' => '', + 'Save this condition' => '', + 'Condition\'s category :' => '', + 'Please select a condition category' => '', + 'Files manager' => '', + 'Please retry' => '', + 'Please select another condition' => '', + 'Edit a customer' => '', + 'Editing customer "%name"' => '', + 'Edit customer thelia thelia' => '', + 'Save' => '', + 'Save and close' => '', + 'Customer informations' => '', + 'Default address' => '', + 'Other addresses' => '', + 'Add a new address' => '', + 'Phone' => '', + 'cell phone' => '', + 'Edit this address' => '', + 'Use this address by default' => '', + 'orders for this customer' => '', + 'Order n°' => '', + 'Date & Hour' => '', + 'Amount' => '', + 'Status' => '', + 'Sorry, customer ID=1 was not found.' => '', + 'Address label' => '', + 'Label' => '', + 'Create an address' => '', + 'Create this address' => '', + 'Use address by default' => '', + 'Do you really want to use this address by default ?' => '', + 'Delete address' => '', + 'Do you really want to delete this address ?' => '', + 'Edit an address' => '', + 'Edit this order' => '', + 'Cancel this order' => '', + 'Delete an order' => '', + 'Do you really want to cancel this order ?' => '', + 'Edit an order' => '', + 'Ordered products' => '', + 'Invoice and Delivery' => '', + 'Cart' => '', + 'Product' => '', + 'Unit. price' => '', + 'Tax' => '', + 'Unit taxed price' => '', + 'Quantity' => '', + 'Taxed total' => '', + 'Total without discount' => '', + 'Discount' => '', + 'Coupon code' => '', + 'Total including discount' => '', + 'Postage' => '', + 'Total' => '', + 'Payment information' => '', + 'Payment module' => '', + 'Transaction reference' => '', + 'Delivery module' => '', + 'tracking reference' => '', + 'Description' => '', + 'Invoice informations' => '', + 'Download invoice as PDF' => '', + 'PDF | Invoice' => '', + 'Edit invoice address' => '', + 'Invoice reference' => '', + 'Invoice date' => '', + 'Street address' => '', + 'Delivery address' => '', + 'Download purchase order as PDF' => '', + 'PDF | Purchase order' => '', + 'Edit delivery address' => '', + 'Compagny' => '', + 'Edit order address' => '', + 'Confirm changes' => '', + 'Top level categories' => '', + 'Add a new category' => '', + 'ID' => '', + 'Category title' => '', + 'Online' => '', + 'Position' => '', + 'Browse this category' => '', + 'Edit this category' => '', + 'Delete this category and all its contents' => '', + 'This category has no sub-categories. To create a new one, click the + button above.' => '', + 'This category has no sub-categories.' => '', + 'Top level Products' => '', + 'Add a new product' => '', + 'Reference' => '', + 'Product title' => '', + 'This category doesn\'t contains any products. To add a new product, click the + button above.' => '', + 'Create a new category' => '', + 'Create this category' => '', + 'Enter here the product reference' => '', + 'Enter here the product name in the default language (%title)' => '', + 'Product price' => '', + 'Enter here the product price in the default currency (%title)' => '', + 'Select a tax tule' => '', + 'Select here the tax applicable to this product' => '', + 'Product weight' => '', + 'Kg' => '', + 'Enter here the product weight, in Kilogrammes' => '', + 'Create a new product' => '', + 'Create this product' => '', + 'Delete category' => '', + 'Do you really want to delete this category and all its content ?' => '', + 'Delete product' => '', + 'Do you really want to delete this product ?' => '', + 'Enter new category position' => '', + 'Enter new product position' => '', + 'Edit category' => '', + 'Editing %cat' => '', + 'Edit category %title' => '', + 'Preview category page' => '', + 'Edit next category' => '', + 'General description' => '', + 'Associations' => '', + 'Images' => '', + 'Documents' => '', + 'Edit information in %lng' => '', + 'Français' => '', + 'castellano' => '', + 'Italiano' => '', + 'Close' => '', + 'Category title *' => '', + 'Summary' => '', + 'A short description, used when a summary or an introduction is required' => '', + 'Short description' => '', + 'Detailed description' => '', + 'The detailed description.' => '', + 'Conclusion' => '', + 'A short post-description information' => '', + 'Short conclusion' => '', + 'Rewriten URL *' => '', + 'Rewritten URL' => '', + 'Rewriten URL' => '', + 'Parent category *' => '', + 'Top level' => '', + 'Visibility' => '', + 'Category created on %date_create. Last modification: %date_change' => '', + 'Related content' => '', + 'You can attach here some content to this category' => '', + 'Select a folder...' => '', + 'Select a folder to get its content' => '', + 'Select a folder content...' => '', + 'Select a content and click (+) to add it to this category' => '', + 'No available content in this folder' => '', + 'No folders found' => '', + 'Content title' => '', + 'This category contains no contents' => '', + 'Send files' => '', + 'Drop files to upload' => '', + 'Browse files' => '', + 'Update this image' => '', + 'There is no images attached to this %type.' => '', + 'Can\'t load images, please refresh this page.' => '', + 'There is no documents attached to this %type.' => '', + 'Can\'t load documents, please refresh this page.' => '', + 'Remove related content' => '', + 'Do you really want to remove this related content ?' => '', + '(edit)' => '', + 'Categories in %cat' => '', + 'Products in %cat' => '', + 'Edit this product' => '', + 'Delete this product' => '', + 'Edit product' => '', + 'Editing %title' => '', + 'Edit product %title' => '', + 'Preview product page' => '', + 'General' => '', + 'Details' => '', + 'Attributes & Features' => '', + 'Product reference' => '', + 'Product title *' => '', + 'Default product category *' => '', + 'You can attach this product to more categories in the details tab.' => '', + 'Product created on %date_create. Last modification: %date_change' => '', + 'Edit prices in %curr' => '', + 'Attribute Combinations' => '', + 'Quickly create combinations using the combination builder' => '', + 'Combination builder' => '', + 'Add a new combination' => '', + 'EAN Code' => '', + 'Price
w/o taxes (%currency)' => '', + 'Price
w/ taxes (%currency)' => '', + 'Weight
(Kg)' => '', + 'Default' => '', + 'Sale' => '', + 'New' => '', + 'Sale price
w/o taxes (%currency)' => '', + 'Sale price
w/ taxes (%currency)' => '', + 'Delete this combination' => '', + 'Attribute' => '', + 'Select an attribute...' => '', + 'Select an attribute and click (+) to view available values' => '', + 'Select an attribute value...' => '', + 'Select a value click (+) to add it to the combination' => '', + 'No available value for this attribute' => '', + 'To remove a value from the combination, select it and click "remove"' => '', + 'Remove selected values' => '', + 'Create a new combination' => '', + 'Create this combination' => '', + 'Delete a combination' => '', + 'Do you really want to delete this combination ?' => '', + 'Select attribute values to combine. You may enter a default value for some of the fields of the generated combinations.' => '', + 'Price excl. taxes' => '', + 'Combination reference' => '', + 'Combination EAN Code' => '', + 'Current quantity' => '', + '0 combinations' => '', + 'Create combinations' => '', + 'Please wait, loading' => '', + 'Failed to get converted prices. Please try again.' => '', + 'Failed to get prices. Please try again.' => '', + 'Existing combinations will be deleted. Do you want to continue ?' => '', + 'To use features or attributes on this product, please select a product template. You can define product templates in the configuration section of the administration.' => '', + 'Current product template' => '', + 'Do not use a product template' => '', + 'Apply' => '', + 'Product Attributes' => '', + 'You can change template attributes and their positions in the template configuration page.' => '', + 'Attribute Name' => '', + 'This product template does not contains any features' => '', + 'Product Features' => '', + 'You can change templates features and their positions in the template configuration page.' => '', + 'Feature Name' => '', + 'Feature value for this product' => '', + 'Use Ctrl+click to select more than one value. You can also clear selected values.' => '', + 'Enter here the feature value as free text' => '', + 'Feature value' => '', + 'Top level folders' => '', + 'Add a new folder' => '', + 'Folder title' => '', + 'Browse this folder' => '', + 'Edit this folder' => '', + 'Delete this folder and all its contents' => '', + 'This folder has no sub-folders. To create a new one, click the + button above.' => '', + 'This folder has no sub-folders.' => '', + 'Top level Contents' => '', + 'Add a new content' => '', + 'This folder doesn\'t contains any contents. To add a new content, click the + button above.' => '', + 'Enter here the folder name in the default language (%title)' => '', + 'Create a new folder' => '', + 'Create this folder' => '', + 'Enter here the content name in the default language (%title)' => '', + 'Create a new content' => '', + 'Create this content' => '', + 'Delete folder' => '', + 'Do you really want to delete this folder and all its content ?' => '', + 'Delete content' => '', + 'Do you really want to delete this content ?' => '', + 'Enter new folder position' => '', + 'Enter new content position' => '', + 'An error occured' => '', + 'Oops! An Error Occurred' => '', + 'Go to administration home' => '', + 'Folders in %fold' => '', + 'Contents in %fold' => '', + 'Edit this content' => '', + 'Delete this content' => '', + 'Edit content' => '', + 'Edit content %title' => '', + 'Preview folder page' => '', + 'Content title *' => '', + 'Default folder *' => '', + 'Folder created on %date_create. Last modification: %date_change' => '', + 'Additional Folders' => '', + 'A content could be attached to more than one folder. Select here the additional fodlers for this content.' => '', + 'You can change the default folder (%title) in the "General" tab.' => '', + ' (default)' => '', + 'Select a folder and click (+) to add it to the additional folder list' => '', + 'No Folders found' => '', + 'This product doesn\'t belong to any additional folder.' => '', + 'Remove associated folder' => '', + 'Do you really want to remove the content from this folder ?' => '', + 'Remove the product from this category' => '', + 'Coupon : ' => '', + 'days left' => '', + 'May be cumulative' => '', + 'Won\'t remove postage' => '', + 'Will be available on special offers' => '', + 'Application field' => '', + 'Do you really want to enable this element ?' => '', + 'Confirmation' => '', + 'Confirm' => '', + 'Create coupon' => '', + 'Create' => '', + 'Please save your Coupon in oder to affect it some conditions' => '', + 'Do you really want to delete this element ?' => '', + 'Thelia Product Templates' => '', + 'Thelia product templates' => '', + 'Add a new product template' => '', + 'Change this template' => '', + 'Change this product template' => '', + 'Delete this product template' => '', + 'No product template has been created yet. Click the + button to create one.' => '', + 'Template Name *' => '', + 'Template title' => '', + 'Enter here the template name in the default language (English)' => '', + 'Create a new product template' => '', + 'Create this product template' => '', + 'Delete template' => '', + 'Do you really want to delete this template ? It will be removed from all products.' => '', + 'Select an feature...' => '', + 'Select an feature and click (+) to add it to this template' => '', + 'Feature title' => '', + 'Delete this feature' => '', + 'This template contains no features' => '', + 'Remove feature' => '', + 'Do you really want to remove this feature from the template ?' => '', + 'Thelia Product Attributes' => '', + 'Thelia product attributes' => '', + 'Add a new product attribute' => '', + 'Change this attribute' => '', + 'Remove this attribute from all product templates' => '', + 'Add this attribute to all product templates' => '', + 'Change this product attribute' => '', + 'Delete this product attribute' => '', + 'No product attribute has been created yet. Click the + button to create one.' => '', + 'Title *' => '', + 'Attribute title' => '', + 'Enter here the attribute name in the default language (English)' => '', + 'Check this box if you want to add this attributes to all product templates' => '', + 'Create a new attribute' => '', + 'Create this attribute' => '', + 'Delete attribute' => '', + 'Do you really want to delete this attribute ? It will be removed from all product templates.' => '', + 'Add to all product templates' => '', + 'Do you really want to add this attribute to all product templates ?' => '', + 'Remove from all product templates' => '', + 'Do you really want to remove this attribute from all product templates ? You\'ll loose all product related data for this attribute.' => '', + 'Enter new attribute position' => '', + 'Edit an attribute' => '', + 'Attributes' => '', + 'Editing attribute "%name"' => '', + 'Edit attribute en_US : Officiis cumque.' => '', + 'Attribute information' => '', + 'Attribute values' => '', + 'Enter here all possible attribute values.' => '', + 'Delete this value' => '', + 'No value has been created yet. Click the + button to create one.' => '', + 'Sorry, attribute ID=1 was not found.' => '', + 'Enter here the value in the current edit language (English)' => '', + 'Create a new attribute value' => '', + 'Create this value' => '', + 'Delete attribute value' => '', + 'Do you really want to delete this attribute value ?' => '', + 'Enter new value position' => '', + 'Thelia Product Features' => '', + 'Thelia product features' => '', + 'Add a new product feature' => '', + 'Change this feature' => '', + 'Remove this feature from all product templates' => '', + 'Add this feature to all product templates' => '', + 'Change this product feature' => '', + 'Delete this product feature' => '', + 'No product feature has been created yet. Click the + button to create one.' => '', + 'Enter here the feature name in the default language (English)' => '', + 'Check this box if you want to add this features to all product templates' => '', + 'Create a new feature' => '', + 'Create this feature' => '', + 'Delete feature' => '', + 'Do you really want to delete this feature ? It will be removed from all product templates.' => '', + 'Do you really want to add this feature to all product templates ?' => '', + 'Do you really want to remove this feature from all product templates ? You\'ll loose all product related data for this feature.' => '', + 'Enter new feature position' => '', + 'Edit a feature' => '', + 'Features' => '', + 'Editing feature "%name"' => '', + 'Edit feature en_US : Consectetur omnis.' => '', + 'Feature information' => '', + 'Feature values' => '', + 'Enter here all possible feature values. To get a free text feature in product forms, don\'t add any value.' => '', + 'Sorry, feature ID=1 was not found.' => '', + 'Create a new feature value' => '', + 'Delete feature value' => '', + 'Do you really want to delete this feature value ?' => '', + 'Thelia Mailing Templates' => '', + 'Thelia mailing templates' => '', + 'Add a new mailing template' => '', + 'Change this mailing template' => '', + 'Delete this mailing template' => '', + 'No mailing template has been created yet. Click the + button to create one.' => '', + 'Mailing template name' => '', + 'Mailing template purpose' => '', + 'Enter here the mailing template purpose in the default language (English)' => '', + 'Create a new mailing template' => '', + 'Create this mailing template' => '', + 'Delete mailing template' => '', + 'Do you really want to delete this mailing template ?' => '', + 'Edit a mailing template' => '', + 'Editing mailing template "%name"' => '', + 'Edit mailing template order_confirmation' => '', + 'Prevent mailing template modification or deletion, except for super-admin' => '', + 'Message subject *' => '', + 'Subject' => '', + 'HTML Message' => '', + 'The mailing template in HTML format.' => '', + 'Text Message' => '', + 'The mailing template in text-only format.' => '', + 'Message created on %date_create. Last modification: %date_change' => '', + 'Sorry, message ID=1 was not found.' => '', + 'Update rates' => '', + 'Add a new currency' => '', + 'ISO 4217 Code' => '', + 'More information about ISO 4217' => '', + 'Symbol' => '', + 'Rate in €' => '', + 'Change this currency' => '', + 'Delete this currency' => '', + 'No currency has been created yet. Click the + button to create one.' => '', + 'Currency name' => '', + 'Enter here the currency name in the default language (English)' => '', + 'ISO 4217 code *' => '', + 'ISO 4217 code' => '', + 'Symbol *' => '', + 'Currency symbol' => '', + 'Rate from € *' => '', + 'Currency rate' => '', + 'Rate' => '', + 'The rate from Euro (Price in Euro * rate = Price in this currency)' => '', + 'Create a new currency' => '', + 'Create this currency' => '', + 'Delete currency' => '', + 'Do you really want to delete this currency ?' => '', + 'Enter new currency position' => '', + 'Edit a currency' => '', + 'Editing currency "%name"' => '', + 'Edit currency Euro' => '', + 'Currency ISO 4217 Code' => '', + 'The symbol, such as $, £, €...' => '', + 'Rate from Euro' => '', + 'Sorry, currency ID=1 was not found.' => '', + 'In order to manges your shop taxes you can manage' => '', + 'taxes' => '', + 'and' => '', + 'tax rules' => '', + 'Taxes define the amount of money which is add to a bought product.' => '', + 'Example :' => '', + 'French 19.6% VAT is a tax which add a 19.6% tax to the product price.' => '', + 'Ecotax is a tax wich add a defined amount (throug a product feature) to the product price.' => '', + 'Tax rules are combination of different taxes.' => '', + 'French 19.6% VAT with ecotax is the applicance of the ecotax (on the product price) then the applicance of the 19.6% tax (on the product price + the ecotax amount).' => '', + 'you can combine taxes in tax rules and chose if they are applied one after the other or at the same time : it allows to apply taxes on an already taxed price or not.' => '', + 'Taxes' => '', + 'Create a new tax' => '', + 'Change this tax' => '', + 'Delete this tax' => '', + 'Create a new tax rule' => '', + 'Change this tax rule' => '', + 'Set as default tax rule' => '', + 'Delete this tax rule' => '', + 'Type' => '', + 'amount' => '', + 'feature' => '', + 'percent' => '', + 'Delete tax' => '', + 'Do you really want to delete this tax ?' => '', + 'Delete tax rule' => '', + 'Do you really want to delete this tax rule ?' => '', + 'Edit a tax' => '', + 'Editing tax' => '', + 'Tax created on %date_create. Last modification: %date_change' => '', + 'Edit a tax rule' => '', + 'Editing tax rule' => '', + 'Tax rule created on %date_create. Last modification: %date_change' => '', + 'Manage taxes' => '', + 'Choose a country' => '', + 'Countries that have the same tax rule' => '', + 'NONE' => '', + 'Manage the tax rule taxes appliance order' => '', + 'Add tax to this group' => '', + 'Drop tax here to create a tax group' => '', + 'Drop tax here to delete from group' => '', + 'Tax rule taxes will be update for the following countries :' => '', + 'uncheck all' => '', + 'Update tax rule taxes' => '', + 'Edit tax rule taxes' => '', + 'Add a new country' => '', + 'Shop' => '', + 'N° ISO' => '', + 'ISO Code' => '', + 'Change this country' => '', + 'Delete this country' => '', + 'No country has been created yet. Click the + button to create one.' => '', + 'Country title *' => '', + 'Country title' => '', + 'Country area' => '', + 'ISO Code *' => '', + 'Alpha code 2 *' => '', + 'Alpha code 2' => '', + 'Alpha code 3 *' => '', + 'Alpha code 3' => '', + 'Create a new country' => '', + 'Create this country' => '', + 'Delete country' => '', + 'Do you really want to delete this country ?' => '', + 'Error' => '', + 'Impossible to change default country. Please contact your administrator or try later' => '', + 'Edit a country' => '', + 'Editing country "%name"' => '', + 'Edit country ' => '', + '' => '', + 'Country short description' => '', + 'Country description' => '', + 'Sorry, country ID=190 was not found.' => '', + 'Edit country Afghanistan' => '', + 'Sorry, country ID=1 was not found.' => '', + 'Thelia Shipping zones' => '', + 'Change this shipping zone' => '', + 'Edit a shipping zone' => '', + 'Editing shipping zone "%name"' => '', + 'Edit shipping zone %title' => '', + 'Add' => '', + 'Zones' => '', + 'Delete this zone' => '', + 'Remove zone' => '', + 'Do you really want to remove this zone ?' => '', + 'Thelia Shipping configuration' => '', + 'Add a new shipping configuration' => '', + 'Change this shipping configuration' => '', + 'Delete this shipping configuration' => '', + 'Shipping configuration name' => '', + 'Create a new shipping configuration' => '', + 'Create this shipping configuration' => '', + 'Delete shipping configuration' => '', + 'Do you really want to delete this shipping configuration ?' => '', + 'Edit a shipping configuration' => '', + 'Editing shipping configuration "%name"' => '', + 'Edit shipping configuration %title' => '', + 'Add this country' => '', + 'No area defined with this id' => '', + 'Remove country' => '', + 'Do you really want to remove this country ?' => '', + 'Classic modules' => '', + 'classic modules' => '', + 'Enable/Disable' => '', + 'Deactivate %title module' => '', + 'deactivation' => '', + 'Edit this module' => '', + 'Delete this module' => '', + 'Delivery modules' => '', + 'Payment modules' => '', + 'Delete a module' => '', + 'Do you really want to delete this module ?' => '', + 'Edit a system variable' => '', + 'Editing variable "%name"' => '', + 'Edit variable active-template' => '', + 'Prevent variable modification or deletion, except for super-admin' => '', + 'Variable created on %date_create. Last modification: %date_change' => '', + 'Sorry, variable ID=3 was not found.' => '', + 'Profiles' => '', + 'Create a new profile' => '', + 'Profile Code' => '', + 'Profile code' => '', + 'Postscriptum' => '', + 'Delete profile' => '', + 'Do you really want to delete this profile ?' => '', + 'You can\'t delete this profile' => '', + 'They are some administrator which are linked to this profile. Please edit/remove them before deleting this profile.' => '', + 'Create a new administrator' => '', + 'Login' => '', + 'FirstName' => '', + 'LastName' => '', + 'Profile' => '', + 'Superadministrator' => '', + 'Change this administrator' => '', + 'Password' => '', + 'Password confirmation' => '', + 'Leave empty to keep current password' => '', + 'Update a new administrator' => '', + 'Delete administrator' => '', + 'Do you really want to delete this administrator ?' => '', + 'You can\'t delete this administrator' => '', + 'They are some administrator which are linked to this administrator. Please edit/remove them before deleting this administrator.' => '', + 'Thelia Languages' => '', + 'Languages' => '', + 'Languages management' => '', + 'Add a new language' => '', + 'Language name' => '', + 'ISO 639 Code' => '', + 'Locale' => '', + 'date form' => '', + 'time form' => '', + 'Change this language' => '', + 'Delete this language' => '', + 'Parameters' => '', + 'If a translation is missing or incomplete :' => '', + 'Using a domain or subdomain for each language' => '', + 'activate' => '', + 'Language title' => '', + 'language locale' => '', + 'en_US' => '', + 'date format' => '', + 'd-m-Y' => '', + 'time format' => '', + 'H:i:s' => '', + 'Create a new language' => '', + 'Create this language' => '', + 'Delete language' => '', + 'Do you really want to delete this language ?' => '', + 'Impossible to change default languages. Please contact your administrator or try later' => '', + 'Edit a language' => '', + 'Edit this language' => '', + 'deactivate' => '', + 'Thelia Mailing System' => '', + 'Configuration mailing system' => '', + 'Enable remote SMTP use : ' => '', + 'Host :' => '', + 'Host' => '', + 'Port :' => '', + 'Port' => '', + 'Encryption :' => '', + 'Encryption' => '', + 'Username :' => '', + 'Username' => '', + 'Password :' => '', + 'Auth Mode :' => '', + 'Auth Mode' => '', + 'Timeout :' => '', + 'Timeout' => '', + 'Source IP :' => '', + 'Source IP' => '', + 'Show logs' => '', + 'Period' => '', + 'From' => '', + 'To' => '', + 'Resources' => '', + 'company' => '', +) +; \ No newline at end of file diff --git a/templates/admin/default/I18n/it_IT.php b/templates/admin/default/I18n/it_IT.php old mode 100644 new mode 100755 index 7eb24949a..6884502b9 --- a/templates/admin/default/I18n/it_IT.php +++ b/templates/admin/default/I18n/it_IT.php @@ -1,26 +1,808 @@ . */ -/* */ -/*************************************************************************************/ -return array( - -); \ No newline at end of file +return array ( + 'Lire la suite' => '', + 'Back-office home' => '', + 'Thelia Back Office' => '', + 'Version %ver' => '', + 'View site' => '', + 'View shop' => '', + 'Profil' => '', + 'Close administation session' => '', + 'Logout' => '', + 'Home' => '', + 'Customers' => '', + 'Orders' => '', + 'All orders' => '', + 'Catalog' => '', + 'Folders' => '', + 'Coupons' => '', + 'Configuration' => '', + 'Modules' => '', + 'Search' => '', + 'Thelia, solution e-commerce libre' => '', + 'Dashboard' => '', + 'Sales' => '', + 'New customers' => '', + 'First orders' => '', + 'Aborted orders' => '', + 'Shop Informations' => '', + 'Categories' => '', + 'Products' => '', + 'Online products' => '', + 'Offline products' => '', + 'Pending orders' => '', + 'In process orderst' => '', + 'Shipped orders' => '', + 'Canceled orders' => '', + 'Sales statistics' => '', + 'Today' => '', + 'This month' => '', + 'This year' => '', + 'Overall sales' => '', + 'Sales excluding shipping' => '', + 'Yesterday sales' => '', + 'Waiting orders' => '', + 'In process orders' => '', + 'Average cart' => '', + 'Previous month sales' => '', + 'Previous year sales' => '', + 'Thelia informations' => '', + 'Current version' => '', + 'Latest version available' => '', + 'News' => '', + 'Click here' => '', + '© Thelia 2013' => '', + 'Édité par OpenStudio' => '', + 'Forum Thelia' => '', + 'Contributions Thelia' => '', + 'Customer' => '', + 'Customers list' => '', + 'Add a new Customer' => '', + 'customer ref' => '', + 'firstname & lastname' => '', + 'last order' => '', + 'order amount' => '', + 'Actions' => '', + 'Edit this customer' => '', + 'Send a mail to this customer' => '', + 'Delete this customer and all his orders' => '', + 'Company Name' => '', + 'Company' => '', + 'Title' => '', + 'First Name' => '', + 'Firstname' => '', + 'Last Name' => '', + 'Lastname' => '', + 'Street Address' => '', + 'Address' => '', + 'Address Line 2' => '', + 'Additional address' => '', + 'Address Line 3' => '', + 'Zip code' => '', + 'City' => '', + 'Country' => '', + 'Email Address' => '', + 'Email address' => '', + 'Create a new customer' => '', + 'Create this customer' => '', + 'Cancel' => '', + 'OK' => '', + 'Delete customer' => '', + 'Do you really want to delete this customer ?' => '', + 'No' => '', + 'Yes' => '', + 'Thelia configuration' => '', + 'Product catalog configuration' => '', + 'Product templates' => '', + 'Product attributes' => '', + 'Product features' => '', + 'Mailing templates' => '', + 'Currencies' => '', + 'Taxes rules' => '', + 'Shipping configuration' => '', + 'Countries' => '', + 'Shipping zones' => '', + 'System parameters' => '', + 'Modules activation' => '', + 'System variables' => '', + 'Administration profiles' => '', + 'Administrators' => '', + 'Languages & URLs' => '', + 'Mailing system' => '', + 'Administration logs' => '', + 'System logs' => '', + 'Thelia System Variables' => '', + 'Thelia system variables' => '', + 'Add a new variable' => '', + 'Save chages' => '', + 'Save changes' => '', + 'Purpose' => '', + 'Name' => '', + 'Value' => '', + 'Action' => '', + 'Change this variable' => '', + 'Cancel changes and revert to original value' => '', + 'Delete this variable' => '', + 'Name *' => '', + 'Variable name' => '', + 'Value *' => '', + 'Variable value' => '', + 'Purpose *' => '', + 'Variable purpose' => '', + 'English' => '', + 'Enter here the category name in the default language (%title)' => '', + 'Create a new variable' => '', + 'Create this variable' => '', + 'Delete a variable' => '', + 'Do you really want to delete this variable ?' => '', + 'Coupon' => '', + 'Browse' => '', + 'Coupons : ' => '', + 'List' => '', + 'Create a new coupon' => '', + 'Enabled coupons' => '', + 'Code' => '', + 'Days before expiration' => '', + 'Usage left' => '', + 'Edit' => '', + 'Unlimited' => '', + 'Disabled coupons' => '', + 'Expiration date' => '', + 'Update coupon' => '', + 'Update' => '', + 'Code :' => '', + 'code' => '', + 'Title :' => '', + 'title' => '', + 'Is enabled' => '', + 'Is available on special offers' => '', + 'Is cumulative' => '', + 'Is removing postage' => '', + 'Expiration date :' => '', + 'yyyy-mm-dd' => '', + 'Is unlimited' => '', + 'Max usage :' => '', + 'max usage' => '', + 'Type :' => '', + 'Please select a coupon type' => '', + 'Amount :' => '', + '14.50' => '', + 'Short description :' => '', + 'short description' => '', + 'Long description :' => '', + 'long description' => '', + 'Save your modifications' => '', + 'Conditions' => '', + 'Delete' => '', + 'And' => '', + 'Save this condition' => '', + 'Condition\'s category :' => '', + 'Please select a condition category' => '', + 'Files manager' => '', + 'Please retry' => '', + 'Please select another condition' => '', + 'Edit a customer' => '', + 'Editing customer "%name"' => '', + 'Edit customer thelia thelia' => '', + 'Save' => '', + 'Save and close' => '', + 'Customer informations' => '', + 'Default address' => '', + 'Other addresses' => '', + 'Add a new address' => '', + 'Phone' => '', + 'cell phone' => '', + 'Edit this address' => '', + 'Use this address by default' => '', + 'orders for this customer' => '', + 'Order n°' => '', + 'Date & Hour' => '', + 'Amount' => '', + 'Status' => '', + 'Sorry, customer ID=1 was not found.' => '', + 'Address label' => '', + 'Label' => '', + 'Create an address' => '', + 'Create this address' => '', + 'Use address by default' => '', + 'Do you really want to use this address by default ?' => '', + 'Delete address' => '', + 'Do you really want to delete this address ?' => '', + 'Edit an address' => '', + 'Edit this order' => '', + 'Cancel this order' => '', + 'Delete an order' => '', + 'Do you really want to cancel this order ?' => '', + 'Edit an order' => '', + 'Ordered products' => '', + 'Invoice and Delivery' => '', + 'Cart' => '', + 'Product' => '', + 'Unit. price' => '', + 'Tax' => '', + 'Unit taxed price' => '', + 'Quantity' => '', + 'Taxed total' => '', + 'Total without discount' => '', + 'Discount' => '', + 'Coupon code' => '', + 'Total including discount' => '', + 'Postage' => '', + 'Total' => '', + 'Payment information' => '', + 'Payment module' => '', + 'Transaction reference' => '', + 'Delivery module' => '', + 'tracking reference' => '', + 'Description' => '', + 'Invoice informations' => '', + 'Download invoice as PDF' => '', + 'PDF | Invoice' => '', + 'Edit invoice address' => '', + 'Invoice reference' => '', + 'Invoice date' => '', + 'Street address' => '', + 'Delivery address' => '', + 'Download purchase order as PDF' => '', + 'PDF | Purchase order' => '', + 'Edit delivery address' => '', + 'Compagny' => '', + 'Edit order address' => '', + 'Confirm changes' => '', + 'Top level categories' => '', + 'Add a new category' => '', + 'ID' => '', + 'Category title' => '', + 'Online' => '', + 'Position' => '', + 'Browse this category' => '', + 'Edit this category' => '', + 'Delete this category and all its contents' => '', + 'This category has no sub-categories. To create a new one, click the + button above.' => '', + 'This category has no sub-categories.' => '', + 'Top level Products' => '', + 'Add a new product' => '', + 'Reference' => '', + 'Product title' => '', + 'This category doesn\'t contains any products. To add a new product, click the + button above.' => '', + 'Create a new category' => '', + 'Create this category' => '', + 'Enter here the product reference' => '', + 'Enter here the product name in the default language (%title)' => '', + 'Product price' => '', + 'Enter here the product price in the default currency (%title)' => '', + 'Select a tax tule' => '', + 'Select here the tax applicable to this product' => '', + 'Product weight' => '', + 'Kg' => '', + 'Enter here the product weight, in Kilogrammes' => '', + 'Create a new product' => '', + 'Create this product' => '', + 'Delete category' => '', + 'Do you really want to delete this category and all its content ?' => '', + 'Delete product' => '', + 'Do you really want to delete this product ?' => '', + 'Enter new category position' => '', + 'Enter new product position' => '', + 'Edit category' => '', + 'Editing %cat' => '', + 'Edit category %title' => '', + 'Preview category page' => '', + 'Edit next category' => '', + 'General description' => '', + 'Associations' => '', + 'Images' => '', + 'Documents' => '', + 'Edit information in %lng' => '', + 'Français' => '', + 'castellano' => '', + 'Italiano' => '', + 'Close' => '', + 'Category title *' => '', + 'Summary' => '', + 'A short description, used when a summary or an introduction is required' => '', + 'Short description' => '', + 'Detailed description' => '', + 'The detailed description.' => '', + 'Conclusion' => '', + 'A short post-description information' => '', + 'Short conclusion' => '', + 'Rewriten URL *' => '', + 'Rewritten URL' => '', + 'Rewriten URL' => '', + 'Parent category *' => '', + 'Top level' => '', + 'Visibility' => '', + 'Category created on %date_create. Last modification: %date_change' => '', + 'Related content' => '', + 'You can attach here some content to this category' => '', + 'Select a folder...' => '', + 'Select a folder to get its content' => '', + 'Select a folder content...' => '', + 'Select a content and click (+) to add it to this category' => '', + 'No available content in this folder' => '', + 'No folders found' => '', + 'Content title' => '', + 'This category contains no contents' => '', + 'Send files' => '', + 'Drop files to upload' => '', + 'Browse files' => '', + 'Update this image' => '', + 'There is no images attached to this %type.' => '', + 'Can\'t load images, please refresh this page.' => '', + 'There is no documents attached to this %type.' => '', + 'Can\'t load documents, please refresh this page.' => '', + 'Remove related content' => '', + 'Do you really want to remove this related content ?' => '', + '(edit)' => '', + 'Categories in %cat' => '', + 'Products in %cat' => '', + 'Edit this product' => '', + 'Delete this product' => '', + 'Edit product' => '', + 'Editing %title' => '', + 'Edit product %title' => '', + 'Preview product page' => '', + 'General' => '', + 'Details' => '', + 'Attributes & Features' => '', + 'Product reference' => '', + 'Product title *' => '', + 'Default product category *' => '', + 'You can attach this product to more categories in the details tab.' => '', + 'Product created on %date_create. Last modification: %date_change' => '', + 'Edit prices in %curr' => '', + 'Attribute Combinations' => '', + 'Quickly create combinations using the combination builder' => '', + 'Combination builder' => '', + 'Add a new combination' => '', + 'EAN Code' => '', + 'Price
w/o taxes (%currency)' => '', + 'Price
w/ taxes (%currency)' => '', + 'Weight
(Kg)' => '', + 'Default' => '', + 'Sale' => '', + 'New' => '', + 'Sale price
w/o taxes (%currency)' => '', + 'Sale price
w/ taxes (%currency)' => '', + 'Delete this combination' => '', + 'Attribute' => '', + 'Select an attribute...' => '', + 'Select an attribute and click (+) to view available values' => '', + 'Select an attribute value...' => '', + 'Select a value click (+) to add it to the combination' => '', + 'No available value for this attribute' => '', + 'To remove a value from the combination, select it and click "remove"' => '', + 'Remove selected values' => '', + 'Create a new combination' => '', + 'Create this combination' => '', + 'Delete a combination' => '', + 'Do you really want to delete this combination ?' => '', + 'Select attribute values to combine. You may enter a default value for some of the fields of the generated combinations.' => '', + 'Price excl. taxes' => '', + 'Combination reference' => '', + 'Combination EAN Code' => '', + 'Current quantity' => '', + '0 combinations' => '', + 'Create combinations' => '', + 'Please wait, loading' => '', + 'Failed to get converted prices. Please try again.' => '', + 'Failed to get prices. Please try again.' => '', + 'Existing combinations will be deleted. Do you want to continue ?' => '', + 'To use features or attributes on this product, please select a product template. You can define product templates in the configuration section of the administration.' => '', + 'Current product template' => '', + 'Do not use a product template' => '', + 'Apply' => '', + 'Product Attributes' => '', + 'You can change template attributes and their positions in the template configuration page.' => '', + 'Attribute Name' => '', + 'This product template does not contains any features' => '', + 'Product Features' => '', + 'You can change templates features and their positions in the template configuration page.' => '', + 'Feature Name' => '', + 'Feature value for this product' => '', + 'Use Ctrl+click to select more than one value. You can also clear selected values.' => '', + 'Enter here the feature value as free text' => '', + 'Feature value' => '', + 'Top level folders' => '', + 'Add a new folder' => '', + 'Folder title' => '', + 'Browse this folder' => '', + 'Edit this folder' => '', + 'Delete this folder and all its contents' => '', + 'This folder has no sub-folders. To create a new one, click the + button above.' => '', + 'This folder has no sub-folders.' => '', + 'Top level Contents' => '', + 'Add a new content' => '', + 'This folder doesn\'t contains any contents. To add a new content, click the + button above.' => '', + 'Enter here the folder name in the default language (%title)' => '', + 'Create a new folder' => '', + 'Create this folder' => '', + 'Enter here the content name in the default language (%title)' => '', + 'Create a new content' => '', + 'Create this content' => '', + 'Delete folder' => '', + 'Do you really want to delete this folder and all its content ?' => '', + 'Delete content' => '', + 'Do you really want to delete this content ?' => '', + 'Enter new folder position' => '', + 'Enter new content position' => '', + 'An error occured' => '', + 'Oops! An Error Occurred' => '', + 'Go to administration home' => '', + 'Folders in %fold' => '', + 'Contents in %fold' => '', + 'Edit this content' => '', + 'Delete this content' => '', + 'Edit content' => '', + 'Edit content %title' => '', + 'Preview folder page' => '', + 'Content title *' => '', + 'Default folder *' => '', + 'Folder created on %date_create. Last modification: %date_change' => '', + 'Additional Folders' => '', + 'A content could be attached to more than one folder. Select here the additional fodlers for this content.' => '', + 'You can change the default folder (%title) in the "General" tab.' => '', + ' (default)' => '', + 'Select a folder and click (+) to add it to the additional folder list' => '', + 'No Folders found' => '', + 'This product doesn\'t belong to any additional folder.' => '', + 'Remove associated folder' => '', + 'Do you really want to remove the content from this folder ?' => '', + 'Remove the product from this category' => '', + 'Coupon : ' => '', + 'days left' => '', + 'May be cumulative' => '', + 'Won\'t remove postage' => '', + 'Will be available on special offers' => '', + 'Application field' => '', + 'Do you really want to enable this element ?' => '', + 'Confirmation' => '', + 'Confirm' => '', + 'Create coupon' => '', + 'Create' => '', + 'Please save your Coupon in oder to affect it some conditions' => '', + 'Do you really want to delete this element ?' => '', + 'Thelia Product Templates' => '', + 'Thelia product templates' => '', + 'Add a new product template' => '', + 'Change this template' => '', + 'Change this product template' => '', + 'Delete this product template' => '', + 'No product template has been created yet. Click the + button to create one.' => '', + 'Template Name *' => '', + 'Template title' => '', + 'Enter here the template name in the default language (English)' => '', + 'Create a new product template' => '', + 'Create this product template' => '', + 'Delete template' => '', + 'Do you really want to delete this template ? It will be removed from all products.' => '', + 'Select an feature...' => '', + 'Select an feature and click (+) to add it to this template' => '', + 'Feature title' => '', + 'Delete this feature' => '', + 'This template contains no features' => '', + 'Remove feature' => '', + 'Do you really want to remove this feature from the template ?' => '', + 'Thelia Product Attributes' => '', + 'Thelia product attributes' => '', + 'Add a new product attribute' => '', + 'Change this attribute' => '', + 'Remove this attribute from all product templates' => '', + 'Add this attribute to all product templates' => '', + 'Change this product attribute' => '', + 'Delete this product attribute' => '', + 'No product attribute has been created yet. Click the + button to create one.' => '', + 'Title *' => '', + 'Attribute title' => '', + 'Enter here the attribute name in the default language (English)' => '', + 'Check this box if you want to add this attributes to all product templates' => '', + 'Create a new attribute' => '', + 'Create this attribute' => '', + 'Delete attribute' => '', + 'Do you really want to delete this attribute ? It will be removed from all product templates.' => '', + 'Add to all product templates' => '', + 'Do you really want to add this attribute to all product templates ?' => '', + 'Remove from all product templates' => '', + 'Do you really want to remove this attribute from all product templates ? You\'ll loose all product related data for this attribute.' => '', + 'Enter new attribute position' => '', + 'Edit an attribute' => '', + 'Attributes' => '', + 'Editing attribute "%name"' => '', + 'Edit attribute en_US : Officiis cumque.' => '', + 'Attribute information' => '', + 'Attribute values' => '', + 'Enter here all possible attribute values.' => '', + 'Delete this value' => '', + 'No value has been created yet. Click the + button to create one.' => '', + 'Sorry, attribute ID=1 was not found.' => '', + 'Enter here the value in the current edit language (English)' => '', + 'Create a new attribute value' => '', + 'Create this value' => '', + 'Delete attribute value' => '', + 'Do you really want to delete this attribute value ?' => '', + 'Enter new value position' => '', + 'Thelia Product Features' => '', + 'Thelia product features' => '', + 'Add a new product feature' => '', + 'Change this feature' => '', + 'Remove this feature from all product templates' => '', + 'Add this feature to all product templates' => '', + 'Change this product feature' => '', + 'Delete this product feature' => '', + 'No product feature has been created yet. Click the + button to create one.' => '', + 'Enter here the feature name in the default language (English)' => '', + 'Check this box if you want to add this features to all product templates' => '', + 'Create a new feature' => '', + 'Create this feature' => '', + 'Delete feature' => '', + 'Do you really want to delete this feature ? It will be removed from all product templates.' => '', + 'Do you really want to add this feature to all product templates ?' => '', + 'Do you really want to remove this feature from all product templates ? You\'ll loose all product related data for this feature.' => '', + 'Enter new feature position' => '', + 'Edit a feature' => '', + 'Features' => '', + 'Editing feature "%name"' => '', + 'Edit feature en_US : Consectetur omnis.' => '', + 'Feature information' => '', + 'Feature values' => '', + 'Enter here all possible feature values. To get a free text feature in product forms, don\'t add any value.' => '', + 'Sorry, feature ID=1 was not found.' => '', + 'Create a new feature value' => '', + 'Delete feature value' => '', + 'Do you really want to delete this feature value ?' => '', + 'Thelia Mailing Templates' => '', + 'Thelia mailing templates' => '', + 'Add a new mailing template' => '', + 'Change this mailing template' => '', + 'Delete this mailing template' => '', + 'No mailing template has been created yet. Click the + button to create one.' => '', + 'Mailing template name' => '', + 'Mailing template purpose' => '', + 'Enter here the mailing template purpose in the default language (English)' => '', + 'Create a new mailing template' => '', + 'Create this mailing template' => '', + 'Delete mailing template' => '', + 'Do you really want to delete this mailing template ?' => '', + 'Edit a mailing template' => '', + 'Editing mailing template "%name"' => '', + 'Edit mailing template order_confirmation' => '', + 'Prevent mailing template modification or deletion, except for super-admin' => '', + 'Message subject *' => '', + 'Subject' => '', + 'HTML Message' => '', + 'The mailing template in HTML format.' => '', + 'Text Message' => '', + 'The mailing template in text-only format.' => '', + 'Message created on %date_create. Last modification: %date_change' => '', + 'Sorry, message ID=1 was not found.' => '', + 'Update rates' => '', + 'Add a new currency' => '', + 'ISO 4217 Code' => '', + 'More information about ISO 4217' => '', + 'Symbol' => '', + 'Rate in €' => '', + 'Change this currency' => '', + 'Delete this currency' => '', + 'No currency has been created yet. Click the + button to create one.' => '', + 'Currency name' => '', + 'Enter here the currency name in the default language (English)' => '', + 'ISO 4217 code *' => '', + 'ISO 4217 code' => '', + 'Symbol *' => '', + 'Currency symbol' => '', + 'Rate from € *' => '', + 'Currency rate' => '', + 'Rate' => '', + 'The rate from Euro (Price in Euro * rate = Price in this currency)' => '', + 'Create a new currency' => '', + 'Create this currency' => '', + 'Delete currency' => '', + 'Do you really want to delete this currency ?' => '', + 'Enter new currency position' => '', + 'Edit a currency' => '', + 'Editing currency "%name"' => '', + 'Edit currency Euro' => '', + 'Currency ISO 4217 Code' => '', + 'The symbol, such as $, £, €...' => '', + 'Rate from Euro' => '', + 'Sorry, currency ID=1 was not found.' => '', + 'In order to manges your shop taxes you can manage' => '', + 'taxes' => '', + 'and' => '', + 'tax rules' => '', + 'Taxes define the amount of money which is add to a bought product.' => '', + 'Example :' => '', + 'French 19.6% VAT is a tax which add a 19.6% tax to the product price.' => '', + 'Ecotax is a tax wich add a defined amount (throug a product feature) to the product price.' => '', + 'Tax rules are combination of different taxes.' => '', + 'French 19.6% VAT with ecotax is the applicance of the ecotax (on the product price) then the applicance of the 19.6% tax (on the product price + the ecotax amount).' => '', + 'you can combine taxes in tax rules and chose if they are applied one after the other or at the same time : it allows to apply taxes on an already taxed price or not.' => '', + 'Taxes' => '', + 'Create a new tax' => '', + 'Change this tax' => '', + 'Delete this tax' => '', + 'Create a new tax rule' => '', + 'Change this tax rule' => '', + 'Set as default tax rule' => '', + 'Delete this tax rule' => '', + 'Type' => '', + 'amount' => '', + 'feature' => '', + 'percent' => '', + 'Delete tax' => '', + 'Do you really want to delete this tax ?' => '', + 'Delete tax rule' => '', + 'Do you really want to delete this tax rule ?' => '', + 'Edit a tax' => '', + 'Editing tax' => '', + 'Tax created on %date_create. Last modification: %date_change' => '', + 'Edit a tax rule' => '', + 'Editing tax rule' => '', + 'Tax rule created on %date_create. Last modification: %date_change' => '', + 'Manage taxes' => '', + 'Choose a country' => '', + 'Countries that have the same tax rule' => '', + 'NONE' => '', + 'Manage the tax rule taxes appliance order' => '', + 'Add tax to this group' => '', + 'Drop tax here to create a tax group' => '', + 'Drop tax here to delete from group' => '', + 'Tax rule taxes will be update for the following countries :' => '', + 'uncheck all' => '', + 'Update tax rule taxes' => '', + 'Edit tax rule taxes' => '', + 'Add a new country' => '', + 'Shop' => '', + 'N° ISO' => '', + 'ISO Code' => '', + 'Change this country' => '', + 'Delete this country' => '', + 'No country has been created yet. Click the + button to create one.' => '', + 'Country title *' => '', + 'Country title' => '', + 'Country area' => '', + 'ISO Code *' => '', + 'Alpha code 2 *' => '', + 'Alpha code 2' => '', + 'Alpha code 3 *' => '', + 'Alpha code 3' => '', + 'Create a new country' => '', + 'Create this country' => '', + 'Delete country' => '', + 'Do you really want to delete this country ?' => '', + 'Error' => '', + 'Impossible to change default country. Please contact your administrator or try later' => '', + 'Edit a country' => '', + 'Editing country "%name"' => '', + 'Edit country ' => '', + '' => '', + 'Country short description' => '', + 'Country description' => '', + 'Sorry, country ID=190 was not found.' => '', + 'Edit country Afghanistan' => '', + 'Sorry, country ID=1 was not found.' => '', + 'Thelia Shipping zones' => '', + 'Change this shipping zone' => '', + 'Edit a shipping zone' => '', + 'Editing shipping zone "%name"' => '', + 'Edit shipping zone %title' => '', + 'Add' => '', + 'Zones' => '', + 'Delete this zone' => '', + 'Remove zone' => '', + 'Do you really want to remove this zone ?' => '', + 'Thelia Shipping configuration' => '', + 'Add a new shipping configuration' => '', + 'Change this shipping configuration' => '', + 'Delete this shipping configuration' => '', + 'Shipping configuration name' => '', + 'Create a new shipping configuration' => '', + 'Create this shipping configuration' => '', + 'Delete shipping configuration' => '', + 'Do you really want to delete this shipping configuration ?' => '', + 'Edit a shipping configuration' => '', + 'Editing shipping configuration "%name"' => '', + 'Edit shipping configuration %title' => '', + 'Add this country' => '', + 'No area defined with this id' => '', + 'Remove country' => '', + 'Do you really want to remove this country ?' => '', + 'Classic modules' => '', + 'classic modules' => '', + 'Enable/Disable' => '', + 'Deactivate %title module' => '', + 'deactivation' => '', + 'Edit this module' => '', + 'Delete this module' => '', + 'Delivery modules' => '', + 'Payment modules' => '', + 'Delete a module' => '', + 'Do you really want to delete this module ?' => '', + 'Edit a system variable' => '', + 'Editing variable "%name"' => '', + 'Edit variable active-template' => '', + 'Prevent variable modification or deletion, except for super-admin' => '', + 'Variable created on %date_create. Last modification: %date_change' => '', + 'Sorry, variable ID=3 was not found.' => '', + 'Profiles' => '', + 'Create a new profile' => '', + 'Profile Code' => '', + 'Profile code' => '', + 'Postscriptum' => '', + 'Delete profile' => '', + 'Do you really want to delete this profile ?' => '', + 'You can\'t delete this profile' => '', + 'They are some administrator which are linked to this profile. Please edit/remove them before deleting this profile.' => '', + 'Create a new administrator' => '', + 'Login' => '', + 'FirstName' => '', + 'LastName' => '', + 'Profile' => '', + 'Superadministrator' => '', + 'Change this administrator' => '', + 'Password' => '', + 'Password confirmation' => '', + 'Leave empty to keep current password' => '', + 'Update a new administrator' => '', + 'Delete administrator' => '', + 'Do you really want to delete this administrator ?' => '', + 'You can\'t delete this administrator' => '', + 'They are some administrator which are linked to this administrator. Please edit/remove them before deleting this administrator.' => '', + 'Thelia Languages' => '', + 'Languages' => '', + 'Languages management' => '', + 'Add a new language' => '', + 'Language name' => '', + 'ISO 639 Code' => '', + 'Locale' => '', + 'date form' => '', + 'time form' => '', + 'Change this language' => '', + 'Delete this language' => '', + 'Parameters' => '', + 'If a translation is missing or incomplete :' => '', + 'Using a domain or subdomain for each language' => '', + 'activate' => '', + 'Language title' => '', + 'language locale' => '', + 'en_US' => '', + 'date format' => '', + 'd-m-Y' => '', + 'time format' => '', + 'H:i:s' => '', + 'Create a new language' => '', + 'Create this language' => '', + 'Delete language' => '', + 'Do you really want to delete this language ?' => '', + 'Impossible to change default languages. Please contact your administrator or try later' => '', + 'Edit a language' => '', + 'Edit this language' => '', + 'deactivate' => '', + 'Thelia Mailing System' => '', + 'Configuration mailing system' => '', + 'Enable remote SMTP use : ' => '', + 'Host :' => '', + 'Host' => '', + 'Port :' => '', + 'Port' => '', + 'Encryption :' => '', + 'Encryption' => '', + 'Username :' => '', + 'Username' => '', + 'Password :' => '', + 'Auth Mode :' => '', + 'Auth Mode' => '', + 'Timeout :' => '', + 'Timeout' => '', + 'Source IP :' => '', + 'Source IP' => '', + 'Show logs' => '', + 'Period' => '', + 'From' => '', + 'To' => '', + 'Resources' => '', + 'company' => '', +) +; \ No newline at end of file From bc454124f3dc9c5ec16535c2cb19620d4b087c1e Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Wed, 30 Oct 2013 16:32:24 +0100 Subject: [PATCH 50/59] admin home stats --- .../Thelia/Config/Resources/routing/admin.xml | 12 +++ .../Controller/Admin/HomeController.php | 102 ++++++++++++++++++ core/lib/Thelia/Model/CustomerQuery.php | 17 +++ core/lib/Thelia/Model/OrderQuery.php | 68 ++++++++++++ templates/admin/default/home.html | 20 ++-- 5 files changed, 209 insertions(+), 10 deletions(-) create mode 100644 core/lib/Thelia/Controller/Admin/HomeController.php diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index 7805f4e05..03ec1856d 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -9,6 +9,18 @@ Thelia\Controller\Admin\AdminController::indexAction + + + + Thelia\Controller\Admin\HomeController::defaultAction + + + + Thelia\Controller\Admin\HomeController::loadStatsAjaxAction + + + + Thelia\Controller\Admin\SessionController::showLoginAction diff --git a/core/lib/Thelia/Controller/Admin/HomeController.php b/core/lib/Thelia/Controller/Admin/HomeController.php new file mode 100644 index 000000000..90b0c6655 --- /dev/null +++ b/core/lib/Thelia/Controller/Admin/HomeController.php @@ -0,0 +1,102 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Controller\Admin; + +use Thelia\Core\Security\AccessManager; +use Thelia\Model\CustomerQuery; +use Thelia\Model\OrderQuery; + +class HomeController extends BaseAdminController +{ + const RESOURCE_CODE = "admin.home"; + + public function defaultAction() + { + if (null !== $response = $this->checkAuth(self::RESOURCE_CODE, AccessManager::VIEW)) return $response; + + // Render the edition template. + return $this->render('home'); + } + + public function loadStatsAjaxAction() + { + $data = new \stdClass(); + + $data->title = "Stats on [...]"; + + /* sales */ + $saleSeries = new \stdClass(); + $saleSeries->color = $this->getRequest()->request->get('sales_color', '#adadad'); + $saleSeries->data = OrderQuery::getSaleStats( + $this->getRequest()->request->get('month', date('m')), + $this->getRequest()->request->get('year', date('Y')) + ); + + /* new customers */ + $newCustomerSeries = new \stdClass(); + $newCustomerSeries->color = $this->getRequest()->request->get('customers_color', '#f39922'); + $newCustomerSeries->data = CustomerQuery::getNewCustomersStats( + $this->getRequest()->request->get('month', date('m')), + $this->getRequest()->request->get('year', date('Y')) + ); + + /* orders */ + $orderSeries = new \stdClass(); + $orderSeries->color = $this->getRequest()->request->get('orders_color', '#5cb85c'); + $orderSeries->data = OrderQuery::getOrdersStats( + $this->getRequest()->request->get('month', date('m')), + $this->getRequest()->request->get('year', date('Y')) + ); + + /* first order */ + $firstOrderSeries = new \stdClass(); + $firstOrderSeries->color = $this->getRequest()->request->get('first_orders_color', '#5bc0de'); + $firstOrderSeries->data = OrderQuery::getFirstOrdersStats( + $this->getRequest()->request->get('month', date('m')), + $this->getRequest()->request->get('year', date('Y')) + ); + + /* cancelled orders */ + $cancelledOrderSeries = new \stdClass(); + $cancelledOrderSeries->color = $this->getRequest()->request->get('cancelled_orders_color', '#d9534f'); + $cancelledOrderSeries->data = OrderQuery::getOrdersStats( + $this->getRequest()->request->get('month', date('m')), + $this->getRequest()->request->get('year', date('Y')), + array(5) + ); + + + $data->series = array( + $saleSeries, + $newCustomerSeries, + $orderSeries, + $firstOrderSeries, + $cancelledOrderSeries, + ); + + $json = json_encode($data); + + return $this->jsonResponse($json); + } +} diff --git a/core/lib/Thelia/Model/CustomerQuery.php b/core/lib/Thelia/Model/CustomerQuery.php index 359d072bd..5c225510b 100755 --- a/core/lib/Thelia/Model/CustomerQuery.php +++ b/core/lib/Thelia/Model/CustomerQuery.php @@ -2,6 +2,7 @@ namespace Thelia\Model; +use Propel\Runtime\ActiveQuery\Criteria; use Thelia\Model\Base\CustomerQuery as BaseCustomerQuery; @@ -21,4 +22,20 @@ class CustomerQuery extends BaseCustomerQuery { { return self::create()->findOneByEmail($email); } + + public static function getNewCustomersStats($month, $year) + { + $numberOfDay = cal_days_in_month(CAL_GREGORIAN, $month, $year); + + $stats = array(); + for($day=1; $day<=$numberOfDay; $day++) { + $dayCustomers = self::create() + ->filterByCreatedAt(sprintf("%s-%s-%s 00:00:00", $year, $month, $day), Criteria::GREATER_EQUAL) + ->filterByCreatedAt(sprintf("%s-%s-%s 23:59:59", $year, $month, $day), Criteria::LESS_EQUAL) + ->count(); + $stats[] = array($day-1, $dayCustomers); + } + + return $stats; + } } // CustomerQuery diff --git a/core/lib/Thelia/Model/OrderQuery.php b/core/lib/Thelia/Model/OrderQuery.php index 0fff5dba1..6eee6a81b 100755 --- a/core/lib/Thelia/Model/OrderQuery.php +++ b/core/lib/Thelia/Model/OrderQuery.php @@ -3,6 +3,7 @@ namespace Thelia\Model; use Propel\Runtime\ActiveQuery\Criteria; +use Propel\Runtime\ActiveQuery\Join; use Propel\Runtime\Exception\PropelException; use Propel\Runtime\Propel; use Thelia\Model\Base\OrderQuery as BaseOrderQuery; @@ -54,4 +55,71 @@ class OrderQuery extends BaseOrderQuery return $obj; } + public static function getSaleStats($month, $year) + { + $numberOfDay = cal_days_in_month(CAL_GREGORIAN, $month, $year); + + $stats = array(); + for($day=1; $day<=$numberOfDay; $day++) { + $dayAmount = 0; + foreach(self::create() + ->filterByStatusId(array(2,3,4), Criteria::IN) + ->filterByCreatedAt(sprintf("%s-%s-%s 00:00:00", $year, $month, $day), Criteria::GREATER_EQUAL) + ->filterByCreatedAt(sprintf("%s-%s-%s 23:59:59", $year, $month, $day), Criteria::LESS_EQUAL) + ->find() as $dayOrders) { + $dayAmount += $dayOrders->getTotalAmount(); + } + $stats[] = array($day-1, $dayAmount); + } + + return $stats; + } + + public static function getOrdersStats($month, $year, $status = null) + { + $numberOfDay = cal_days_in_month(CAL_GREGORIAN, $month, $year); + + $stats = array(); + for($day=1; $day<=$numberOfDay; $day++) { + $dayOrdersQuery = self::create() + ->filterByCreatedAt(sprintf("%s-%s-%s 00:00:00", $year, $month, $day), Criteria::GREATER_EQUAL) + ->filterByCreatedAt(sprintf("%s-%s-%s 23:59:59", $year, $month, $day), Criteria::LESS_EQUAL); + if(null !== $status) { + $dayOrdersQuery->filterByStatusId($status, Criteria::IN); + } + $dayOrders = $dayOrdersQuery->count(); + $stats[] = array($day-1, $dayOrders); + } + + return $stats; + } + + public static function getFirstOrdersStats($month, $year) + { + $numberOfDay = cal_days_in_month(CAL_GREGORIAN, $month, $year); + + $stats = array(); + for($day=1; $day<=$numberOfDay; $day++) { + $dayOrdersQuery = self::create('matching_order') + ->filterByCreatedAt(sprintf("%s-%s-%s 00:00:00", $year, $month, $day), Criteria::GREATER_EQUAL) + ->filterByCreatedAt(sprintf("%s-%s-%s 23:59:59", $year, $month, $day), Criteria::LESS_EQUAL); + + $otherOrderJoin = new Join(); + $otherOrderJoin->addExplicitCondition(OrderTableMap::TABLE_NAME, 'CUSTOMER_ID', 'matching_order', OrderTableMap::TABLE_NAME, 'CUSTOMER_ID', 'other_order'); + $otherOrderJoin->setJoinType(Criteria::LEFT_JOIN); + + $dayOrdersQuery->addJoinObject($otherOrderJoin, 'other_order_join') + ->addJoinCondition('other_order_join', '`matching_order`.`ID` <> `other_order`.`ID`') + ->addJoinCondition('other_order_join', '`matching_order`.`CREATED_AT` > `other_order`.`CREATED_AT`'); + + $dayOrdersQuery->where('ISNULL(`other_order`.`ID`)'); + + $dayOrders = $dayOrdersQuery->count(); + $stats[] = array($day-1, $dayOrders); + } + + return $stats; + } + + } // OrderQuery diff --git a/templates/admin/default/home.html b/templates/admin/default/home.html index 22989d8fb..378c75354 100755 --- a/templates/admin/default/home.html +++ b/templates/admin/default/home.html @@ -274,7 +274,7 @@ var $elem = $('#jqplot'); - var url = "{url file='/test_to_remove/admin-stats.json'}", + var url = "{url path='/admin/home/stats'}", series = [], seriesColors = [], ticks = [], @@ -318,12 +318,12 @@ } }; - // Get datas Json + // Get data Json $.getJSON(url) .done(function(data) { - // Init series datas and colors - initJqplotDatas(series, seriesColors, options, data); + // Init series data and colors + initJqplotData(series, seriesColors, options, data); // Add days to xaxis for(var i = 1; i < (days+1); i++){ @@ -350,8 +350,8 @@ series = []; seriesColors = []; - // Init series datas and colors - initJqplotDatas(series, seriesColors, options, data); + // Init series data and colors + initJqplotData(series, seriesColors, options, data); // Restart jqplot jqplot.destroy(); @@ -372,15 +372,15 @@ }); - function initJqplotDatas(series, seriesColors, options, json){ + function initJqplotData(series, seriesColors, options, json){ $('[data-toggle="jqplot-serie"].active').each(function(i){ var position = $(this).index() - 1; - series.push(json.series[position].datas); + series.push(json.series[position].data); seriesColors.push(json.series[position].color); }); - // Number of days to display ( = datas.length in one serie) - days = json.series[0].datas.length; + // Number of days to display ( = data.length in one serie) + days = json.series[0].data.length; // Graph title options.title = json.title; From 689de106c7842ca9a07bea28a1f643008682971e Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Wed, 30 Oct 2013 17:00:38 +0100 Subject: [PATCH 51/59] admin home stats --- .../Controller/Admin/HomeController.php | 2 +- templates/admin/default/home.html | 228 +++++++++--------- 2 files changed, 115 insertions(+), 115 deletions(-) diff --git a/core/lib/Thelia/Controller/Admin/HomeController.php b/core/lib/Thelia/Controller/Admin/HomeController.php index 90b0c6655..c30e61985 100644 --- a/core/lib/Thelia/Controller/Admin/HomeController.php +++ b/core/lib/Thelia/Controller/Admin/HomeController.php @@ -43,7 +43,7 @@ class HomeController extends BaseAdminController { $data = new \stdClass(); - $data->title = "Stats on [...]"; + $data->title = "Stats on " . $this->getRequest()->request->get('month', date('m')) . "/" . $this->getRequest()->request->get('month', date('Y')); /* sales */ $saleSeries = new \stdClass(); diff --git a/templates/admin/default/home.html b/templates/admin/default/home.html index 378c75354..fd6d85a4a 100755 --- a/templates/admin/default/home.html +++ b/templates/admin/default/home.html @@ -266,133 +266,133 @@ {/javascripts} - + // Init series data and colors + initJqplotData(series, seriesColors, options, data); + + // Add days to xaxis + for(var i = 1; i < (days+1); i++){ + ticks.push([i-1, i]); + } + + // Start jqplot + var elementId = $elem.attr('id'); + jqplot = $.jqplot(elementId, series, options); + + $('[data-toggle="jqplot"]').each(function(){ + + $(this).click(function(){ + + if($('[data-toggle="jqplot-serie"].active').length > 1 || !$(this).hasClass('active')){ + + // Active button and jqplot-serie management + $(this).toggleClass('active'); + + var id = $(this).data('target'); + $('[data-toggle="jqplot-serie"]#' + id).toggleClass('active'); + + // Reinit variables + series = []; + seriesColors = []; + + // Init series data and colors + initJqplotData(series, seriesColors, options, data); + + // Restart jqplot + jqplot.destroy(); + jqplot = $.jqplot(elementId, series, options); + } + + }); + + }); + + $(window).bind('resize', function(event, ui) { + jqplot.replot( { resetAxes: true } ); + }); + + } + + }); + + {/javascripts} {/block} \ No newline at end of file From 95be087b9016b73cf39a2840720e96fc7611e01c Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Thu, 31 Oct 2013 11:20:51 +0100 Subject: [PATCH 52/59] review jqplot --- .../Controller/Admin/HomeController.php | 32 +-- templates/admin/default/home.html | 271 +++++++++--------- 2 files changed, 151 insertions(+), 152 deletions(-) diff --git a/core/lib/Thelia/Controller/Admin/HomeController.php b/core/lib/Thelia/Controller/Admin/HomeController.php index c30e61985..dbd0a5d30 100644 --- a/core/lib/Thelia/Controller/Admin/HomeController.php +++ b/core/lib/Thelia/Controller/Admin/HomeController.php @@ -43,46 +43,46 @@ class HomeController extends BaseAdminController { $data = new \stdClass(); - $data->title = "Stats on " . $this->getRequest()->request->get('month', date('m')) . "/" . $this->getRequest()->request->get('month', date('Y')); + $data->title = "Stats on " . $this->getRequest()->query->get('month', date('m')) . "/" . $this->getRequest()->query->get('year', date('Y')); /* sales */ $saleSeries = new \stdClass(); - $saleSeries->color = $this->getRequest()->request->get('sales_color', '#adadad'); + $saleSeries->color = $this->getRequest()->query->get('sales_color', '#adadad'); $saleSeries->data = OrderQuery::getSaleStats( - $this->getRequest()->request->get('month', date('m')), - $this->getRequest()->request->get('year', date('Y')) + $this->getRequest()->query->get('month', date('m')), + $this->getRequest()->query->get('year', date('Y')) ); /* new customers */ $newCustomerSeries = new \stdClass(); - $newCustomerSeries->color = $this->getRequest()->request->get('customers_color', '#f39922'); + $newCustomerSeries->color = $this->getRequest()->query->get('customers_color', '#f39922'); $newCustomerSeries->data = CustomerQuery::getNewCustomersStats( - $this->getRequest()->request->get('month', date('m')), - $this->getRequest()->request->get('year', date('Y')) + $this->getRequest()->query->get('month', date('m')), + $this->getRequest()->query->get('year', date('Y')) ); /* orders */ $orderSeries = new \stdClass(); - $orderSeries->color = $this->getRequest()->request->get('orders_color', '#5cb85c'); + $orderSeries->color = $this->getRequest()->query->get('orders_color', '#5cb85c'); $orderSeries->data = OrderQuery::getOrdersStats( - $this->getRequest()->request->get('month', date('m')), - $this->getRequest()->request->get('year', date('Y')) + $this->getRequest()->query->get('month', date('m')), + $this->getRequest()->query->get('year', date('Y')) ); /* first order */ $firstOrderSeries = new \stdClass(); - $firstOrderSeries->color = $this->getRequest()->request->get('first_orders_color', '#5bc0de'); + $firstOrderSeries->color = $this->getRequest()->query->get('first_orders_color', '#5bc0de'); $firstOrderSeries->data = OrderQuery::getFirstOrdersStats( - $this->getRequest()->request->get('month', date('m')), - $this->getRequest()->request->get('year', date('Y')) + $this->getRequest()->query->get('month', date('m')), + $this->getRequest()->query->get('year', date('Y')) ); /* cancelled orders */ $cancelledOrderSeries = new \stdClass(); - $cancelledOrderSeries->color = $this->getRequest()->request->get('cancelled_orders_color', '#d9534f'); + $cancelledOrderSeries->color = $this->getRequest()->query->get('cancelled_orders_color', '#d9534f'); $cancelledOrderSeries->data = OrderQuery::getOrdersStats( - $this->getRequest()->request->get('month', date('m')), - $this->getRequest()->request->get('year', date('Y')), + $this->getRequest()->query->get('month', date('m')), + $this->getRequest()->query->get('year', date('Y')), array(5) ); diff --git a/templates/admin/default/home.html b/templates/admin/default/home.html index fd6d85a4a..105c640c5 100755 --- a/templates/admin/default/home.html +++ b/templates/admin/default/home.html @@ -12,10 +12,10 @@
{intl l='Dashboard'} -
- - - +
+ + +
@@ -33,12 +33,6 @@
- -
-
-
-
-
@@ -255,144 +249,149 @@ {javascripts file='assets/js/jqplot/jquery.jqplot.min.js'} - - {javascripts file='assets/js/jqplot/plugins/jqplot.highlighter.min.js'} - - {/javascripts} - {javascripts file='assets/js/jqplot/plugins/jqplot.barRenderer.min.js'} - - {/javascripts} - {javascripts file='assets/js/jqplot/plugins/jqplot.pieRenderer.min.js'} - - {/javascripts} + {/javascripts} + {javascripts file='assets/js/jqplot/plugins/jqplot.highlighter.min.js'} + + {/javascripts} + {javascripts file='assets/js/jqplot/plugins/jqplot.barRenderer.min.js'} + + {/javascripts} + {javascripts file='assets/js/jqplot/plugins/jqplot.pieRenderer.min.js'} + + {/javascripts} - {/javascripts} {/block} \ No newline at end of file From 26c7acbeaa57ff8ccf972bcc8dbb58d40dda8f11 Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Thu, 31 Oct 2013 11:59:25 +0100 Subject: [PATCH 53/59] admoin home stats navigation --- templates/admin/default/home.html | 44 ++++++++++++++++++------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/templates/admin/default/home.html b/templates/admin/default/home.html index 105c640c5..c1fbfa7c6 100755 --- a/templates/admin/default/home.html +++ b/templates/admin/default/home.html @@ -13,9 +13,9 @@
{intl l='Dashboard'}
- + - +
@@ -264,6 +264,8 @@ jQuery(function($){ + var jQplotDate = new Date(); + jQplotDate.setDate(1); // Set day to 1 so we can add month without 30/31 days of month troubles. var url = "{url path='/admin/home/stats'}"; var jQplotData; // json data var jQPlotInstance; // global instance @@ -306,13 +308,10 @@ jQuery(function($){ } }; + {literal} + // Get initial data Json - $.getJSON(url) - .done(function(data) { - jQplotData = data; - jsonSuccessLoad(); - }) - .fail(jsonFailLoad); + retrieveJQPlotJson(jQplotDate.getMonth()+1, jQplotDate.getFullYear()); $('[data-toggle="jqplot"]').click(function(){ @@ -323,21 +322,26 @@ jQuery(function($){ $('.js-stats-change-month').click(function(e){ $('.js-stats-change-month').attr('disabled', true); + jQplotDate.setMonth(parseInt(jQplotDate.getMonth()) + parseInt($(this).data('month-offset'))); + retrieveJQPlotJson(jQplotDate.getMonth()+1, jQplotDate.getFullYear(), function(){$('.js-stats-change-month').attr('disabled', false);}); - $('#jqplot'); - - {literal} - $.getJSON(url, {month: 9, year: 2010}) - .done(function(data) { - jQplotData = data; - jsonSuccessLoad(); - }) - .fail(jsonFailLoad); - {/literal} }); + function retrieveJQPlotJson(month, year, callback) { + console.log(month, year); - function initJqplotData(json){ + $.getJSON(url, {month: month, year: year}) + .done(function(data) { + jQplotData = data; + jsonSuccessLoad(); + if(callback) { + callback(); + } + }) + .fail(jsonFailLoad); + } + + function initJqplotData(json) { var series = []; var seriesColors = []; $('[data-toggle="jqplot"].active').each(function(i){ @@ -391,6 +395,8 @@ jQuery(function($){ } + {/literal} + }); From 1bcec288413d6be5868abfbc71afa8cdea3e44e1 Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Thu, 31 Oct 2013 16:24:57 +0100 Subject: [PATCH 54/59] remove tax js in profiles --- templates/admin/default/profile-edit.html | 146 ---------------------- templates/admin/default/profiles.html | 4 +- 2 files changed, 2 insertions(+), 148 deletions(-) diff --git a/templates/admin/default/profile-edit.html b/templates/admin/default/profile-edit.html index a7c2e0f9d..8eb104cd0 100644 --- a/templates/admin/default/profile-edit.html +++ b/templates/admin/default/profile-edit.html @@ -295,10 +295,6 @@ {block name="javascript-initialization"} - {javascripts file='assets/js/bootstrap-select/bootstrap-select.js'} - - {/javascripts} - {javascripts file='assets/js/bootstrap-switch/bootstrap-switch.js'} {/javascripts} @@ -307,146 +303,4 @@ {/javascripts} - - - - {/block} \ No newline at end of file diff --git a/templates/admin/default/profiles.html b/templates/admin/default/profiles.html index 7c4950b02..418037cc1 100644 --- a/templates/admin/default/profiles.html +++ b/templates/admin/default/profiles.html @@ -1,6 +1,6 @@ {extends file="admin-layout.tpl"} -{block name="page-title"}{intl l='Taxes rules'}{/block} +{block name="page-title"}{intl l='Administration profiles'}{/block} {block name="check-resource"}admin.configuration.profile{/block} {block name="check-access"}view{/block} @@ -27,7 +27,7 @@
- - + + {/loop} diff --git a/templates/admin/default/includes/inner-form-toolbar.html b/templates/admin/default/includes/inner-form-toolbar.html index 96e0e65ab..1b2be1ff7 100755 --- a/templates/admin/default/includes/inner-form-toolbar.html +++ b/templates/admin/default/includes/inner-form-toolbar.html @@ -3,6 +3,7 @@ A toolbar displayed in forms, to display language change flags, submit and close Parameters: + - hide_flags: true / false. If true, the flags will not be visible - hide_submit_buttons: true / false. If true, only the close button will be deplayed. - show_currencies: true/false. If true, show the currency selection bar - page_url: the current page URL. Dafault id $current_url. Used to switchedition anguage. @@ -11,6 +12,7 @@ Parameters:
+ {if $hide_flags != true} + {/if}
diff --git a/templates/admin/default/includes/module-block.html b/templates/admin/default/includes/module-block.html index dd3e1ddb8..527e9bf6a 100644 --- a/templates/admin/default/includes/module-block.html +++ b/templates/admin/default/includes/module-block.html @@ -36,7 +36,7 @@ {module_include location='modules_table_row'} -
- {loop name="list" type="template" backend_context="1" lang=$lang_id order=$order} + {loop name="list" type="product-template" backend_context="1" lang=$lang_id order=$order} From d7012af3e27e264bead699ebbca1146caac032d7 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Mon, 4 Nov 2013 09:28:12 +0100 Subject: [PATCH 59/59] add translation files for thelia core system --- core/lib/Thelia/Config/I18n/en_US.php | 26 ++++++++++++++++++++++++++ core/lib/Thelia/Config/I18n/es_ES.php | 26 ++++++++++++++++++++++++++ core/lib/Thelia/Config/I18n/fr_FR.php | 26 ++++++++++++++++++++++++++ core/lib/Thelia/Config/I18n/it_IT.php | 26 ++++++++++++++++++++++++++ core/lib/Thelia/Core/Thelia.php | 3 +++ 5 files changed, 107 insertions(+) create mode 100644 core/lib/Thelia/Config/I18n/en_US.php create mode 100644 core/lib/Thelia/Config/I18n/es_ES.php create mode 100644 core/lib/Thelia/Config/I18n/fr_FR.php create mode 100644 core/lib/Thelia/Config/I18n/it_IT.php diff --git a/core/lib/Thelia/Config/I18n/en_US.php b/core/lib/Thelia/Config/I18n/en_US.php new file mode 100644 index 000000000..7eb24949a --- /dev/null +++ b/core/lib/Thelia/Config/I18n/en_US.php @@ -0,0 +1,26 @@ +. */ +/* */ +/*************************************************************************************/ + +return array( + +); \ No newline at end of file diff --git a/core/lib/Thelia/Config/I18n/es_ES.php b/core/lib/Thelia/Config/I18n/es_ES.php new file mode 100644 index 000000000..7eb24949a --- /dev/null +++ b/core/lib/Thelia/Config/I18n/es_ES.php @@ -0,0 +1,26 @@ +. */ +/* */ +/*************************************************************************************/ + +return array( + +); \ No newline at end of file diff --git a/core/lib/Thelia/Config/I18n/fr_FR.php b/core/lib/Thelia/Config/I18n/fr_FR.php new file mode 100644 index 000000000..7eb24949a --- /dev/null +++ b/core/lib/Thelia/Config/I18n/fr_FR.php @@ -0,0 +1,26 @@ +. */ +/* */ +/*************************************************************************************/ + +return array( + +); \ No newline at end of file diff --git a/core/lib/Thelia/Config/I18n/it_IT.php b/core/lib/Thelia/Config/I18n/it_IT.php new file mode 100644 index 000000000..7eb24949a --- /dev/null +++ b/core/lib/Thelia/Config/I18n/it_IT.php @@ -0,0 +1,26 @@ +. */ +/* */ +/*************************************************************************************/ + +return array( + +); \ No newline at end of file diff --git a/core/lib/Thelia/Core/Thelia.php b/core/lib/Thelia/Core/Thelia.php index 3d476ad30..2b4229f3c 100755 --- a/core/lib/Thelia/Core/Thelia.php +++ b/core/lib/Thelia/Core/Thelia.php @@ -150,6 +150,9 @@ class Thelia extends Kernel } //Load translation from templates + //core translation + $dirs[] = THELIA_ROOT . "/core/lib/Thelia/Config/I18n"; + //admin template if(is_dir($dir = THELIA_TEMPLATE_DIR . '/admin/default/I18n')) { $dirs[] = $dir;
- {intl l="Taxes"} + {intl l="Administration profiles"} {loop type="auth" name="can_create" role="ADMIN" resource="admin.profile" access="CREATE"} From a0855cda4ca90d4c688f3c8a5a3476b332cc0275 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Thu, 31 Oct 2013 16:46:04 +0100 Subject: [PATCH 55/59] Added System Log configuration routes --- core/lib/Thelia/Config/Resources/routing/admin.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index 7805f4e05..2ca43e472 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -504,6 +504,16 @@ Thelia\Controller\Admin\ConfigController::deleteAction + + + + Thelia\Controller\Admin\SystemLogController::defaultAction + + + + Thelia\Controller\Admin\SystemLogController::saveAction + + From 2aefb87db79755acfc0fe2a33c880bbbe578c507 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 1 Nov 2013 16:15:19 +0100 Subject: [PATCH 56/59] Finished log configuration. All loggers are currentrly working --- core/bootstrap.php | 4 +- core/lib/Thelia/Action/HttpException.php | 2 +- core/lib/Thelia/Config/Resources/config.xml | 2 - core/lib/Thelia/Config/Resources/form.xml | 2 + .../Admin/AbstractCrudController.php | 12 +- .../Controller/Admin/BaseAdminController.php | 10 +- .../Controller/Admin/CategoryController.php | 4 +- .../Controller/Admin/ConfigController.php | 2 +- .../Controller/Admin/ContentController.php | 4 +- .../Controller/Admin/CouponController.php | 12 +- .../Controller/Admin/CustomerController.php | 2 +- .../Controller/Admin/FileController.php | 2 +- .../Controller/Admin/LangController.php | 2 +- .../Controller/Admin/OrderController.php | 2 +- .../Admin/ShippingZoneController.php | 2 +- .../Controller/Admin/SystemLogController.php | 182 ++ core/lib/Thelia/Controller/BaseController.php | 4 +- core/lib/Thelia/Core/Bundle/TheliaBundle.php | 3 +- .../Core/Controller/ControllerResolver.php | 1 + .../Core/EventListener/ViewListener.php | 2 +- .../Thelia/Core/HttpFoundation/Response.php | 48 + .../Core/Security/Resource/AdminResources.php | 2 + .../Smarty/Plugins/DataAccessFunctions.php | 10 +- .../Template/Smarty/Plugins/FlashMessage.php | 17 +- .../Core/Template/Smarty/Plugins/Module.php | 10 +- .../Core/Template/Smarty/SmartyParser.php | 4 +- core/lib/Thelia/Core/Thelia.php | 4 +- .../Exception/CouponExpiredException.php | 2 +- .../Thelia/Form/AdministratorCreationForm.php | 4 +- core/lib/Thelia/Form/ConfigCreationForm.php | 11 +- .../Thelia/Form/ConfigModificationForm.php | 7 +- core/lib/Thelia/Form/ContentCreationForm.php | 2 +- core/lib/Thelia/Form/CurrencyCreationForm.php | 11 +- .../Form/CustomerPasswordUpdateForm.php | 2 +- .../Thelia/Form/CustomerProfilUpdateForm.php | 2 +- core/lib/Thelia/Form/MessageCreationForm.php | 7 +- .../Thelia/Form/MessageModificationForm.php | 13 +- core/lib/Thelia/Form/ProductCreationForm.php | 4 +- .../Form/SystemLogConfigurationForm.php | 86 + .../Thelia/Log/AbstractTlogDestination.php | 30 +- .../Log/Destination/TlogDestinationFile.php | 15 +- .../Log/Destination/TlogDestinationHtml.php | 11 +- .../TlogDestinationJavascriptConsole.php | 51 + .../Log/Destination/TlogDestinationNull.php | 4 +- .../Log/Destination/TlogDestinationPopup.php | 111 + .../Log/Destination/TlogDestinationPopup.tpl | 52 + .../Log/Destination/TlogDestinationText.php | 4 +- core/lib/Thelia/Log/Tlog.php | 41 +- core/lib/Thelia/Log/TlogDestinationConfig.php | 84 +- core/lib/Thelia/Model/ConfigQuery.php | 7 +- core/lib/Thelia/Tools/Redirect.php | 7 +- core/lib/Thelia/Tools/Rest/ResponseRest.php | 2 +- local/config/schema.xml | 2528 ++++++++--------- templates/admin/default/configuration.html | 4 +- .../default/includes/inner-form-toolbar.html | 3 + .../admin/default/includes/module-block.html | 2 +- templates/admin/default/system-logs.html | 213 ++ web/index_dev.php | 3 +- 58 files changed, 2236 insertions(+), 1438 deletions(-) create mode 100644 core/lib/Thelia/Controller/Admin/SystemLogController.php create mode 100644 core/lib/Thelia/Core/HttpFoundation/Response.php create mode 100644 core/lib/Thelia/Form/SystemLogConfigurationForm.php create mode 100644 core/lib/Thelia/Log/Destination/TlogDestinationJavascriptConsole.php create mode 100644 core/lib/Thelia/Log/Destination/TlogDestinationPopup.php create mode 100644 core/lib/Thelia/Log/Destination/TlogDestinationPopup.tpl create mode 100644 templates/admin/default/system-logs.html diff --git a/core/bootstrap.php b/core/bootstrap.php index 468df2eac..0cc61ceaa 100755 --- a/core/bootstrap.php +++ b/core/bootstrap.php @@ -11,12 +11,10 @@ define('THELIA_CONF_DIR' , THELIA_LOCAL_DIR . 'config/'); define('THELIA_MODULE_DIR' , THELIA_LOCAL_DIR . 'modules/'); define('THELIA_WEB_DIR' , THELIA_ROOT . 'web/'); define('THELIA_TEMPLATE_DIR' , THELIA_ROOT . 'templates/'); -define('DS', DIRECTORY_SEPARATOR); +define('DS' , DIRECTORY_SEPARATOR); $loader = require __DIR__ . "/vendor/autoload.php"; - - if (!file_exists(THELIA_ROOT . '/local/config/database.yml') && !defined('THELIA_INSTALL_MODE')) { $request = \Thelia\Core\HttpFoundation\Request::createFromGlobals(); header('location: '.$request->getSchemeAndHttpHost() . '/install'); diff --git a/core/lib/Thelia/Action/HttpException.php b/core/lib/Thelia/Action/HttpException.php index 50ee92d5e..10e0dad37 100755 --- a/core/lib/Thelia/Action/HttpException.php +++ b/core/lib/Thelia/Action/HttpException.php @@ -24,7 +24,7 @@ namespace Thelia\Action; use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Symfony\Component\HttpFoundation\Response; +use Thelia\Core\HttpFoundation\Response; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index e75ab8ebb..198f9f999 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -55,8 +55,6 @@ %kernel.debug% - - diff --git a/core/lib/Thelia/Config/Resources/form.xml b/core/lib/Thelia/Config/Resources/form.xml index 8577bf145..dda9be749 100644 --- a/core/lib/Thelia/Config/Resources/form.xml +++ b/core/lib/Thelia/Config/Resources/form.xml @@ -120,6 +120,8 @@ + + diff --git a/core/lib/Thelia/Controller/Admin/AbstractCrudController.php b/core/lib/Thelia/Controller/Admin/AbstractCrudController.php index 46760eba9..689ac9b1b 100644 --- a/core/lib/Thelia/Controller/Admin/AbstractCrudController.php +++ b/core/lib/Thelia/Controller/Admin/AbstractCrudController.php @@ -253,7 +253,7 @@ abstract class AbstractCrudController extends BaseAdminController /** * Render the object list, ensuring the sort order is set. * - * @return Symfony\Component\HttpFoundation\Response the response + * @return Thelia\Core\HttpFoundation\Response the response */ protected function renderList() { @@ -263,7 +263,7 @@ abstract class AbstractCrudController extends BaseAdminController /** * The default action is displaying the list. * - * @return Symfony\Component\HttpFoundation\Response the response + * @return Thelia\Core\HttpFoundation\Response the response */ public function defaultAction() { @@ -274,7 +274,7 @@ abstract class AbstractCrudController extends BaseAdminController /** * Create a new object * - * @return Symfony\Component\HttpFoundation\Response the response + * @return Thelia\Core\HttpFoundation\Response the response */ public function createAction() { @@ -335,7 +335,7 @@ abstract class AbstractCrudController extends BaseAdminController /** * Load a object for modification, and display the edit template. * - * @return Symfony\Component\HttpFoundation\Response the response + * @return Thelia\Core\HttpFoundation\Response the response */ public function updateAction() { @@ -361,7 +361,7 @@ abstract class AbstractCrudController extends BaseAdminController /** * Save changes on a modified object, and either go back to the object list, or stay on the edition page. * - * @return Symfony\Component\HttpFoundation\Response the response + * @return Thelia\Core\HttpFoundation\Response the response */ public function processUpdateAction() { @@ -516,7 +516,7 @@ abstract class AbstractCrudController extends BaseAdminController /** * Delete an object * - * @return Symfony\Component\HttpFoundation\Response the response + * @return Thelia\Core\HttpFoundation\Response the response */ public function deleteAction() { diff --git a/core/lib/Thelia/Controller/Admin/BaseAdminController.php b/core/lib/Thelia/Controller/Admin/BaseAdminController.php index 5fc11c814..d34f2ce82 100755 --- a/core/lib/Thelia/Controller/Admin/BaseAdminController.php +++ b/core/lib/Thelia/Controller/Admin/BaseAdminController.php @@ -26,7 +26,7 @@ use Symfony\Component\Routing\Exception\InvalidParameterException; use Symfony\Component\Routing\Exception\MissingMandatoryParametersException; use Symfony\Component\Routing\Exception\RouteNotFoundException; use Thelia\Controller\BaseController; -use Symfony\Component\HttpFoundation\Response; +use Thelia\Core\HttpFoundation\Response; use Thelia\Core\Security\Exception\AuthorizationException; use Thelia\Model\ConfigQuery; use Symfony\Component\HttpKernel\HttpKernelInterface; @@ -85,7 +85,7 @@ class BaseAdminController extends BaseController /** * Return a 404 error * - * @return \Symfony\Component\HttpFoundation\Response + * @return \Thelia\Core\HttpFoundation\Response */ protected function pageNotFound() { @@ -97,7 +97,7 @@ class BaseAdminController extends BaseController * * @param mixed $message a message string, or an exception instance * - * @return \Symfony\Component\HttpFoundation\Response + * @return \Thelia\Core\HttpFoundation\Response */ protected function errorPage($message, $status = 500) { @@ -373,7 +373,7 @@ class BaseAdminController extends BaseController * @param $templateName the complete template name, with extension * @param array $args the template arguments * @param int $status http code status - * @return \Symfony\Component\HttpFoundation\Response + * @return \Thelia\Core\HttpFoundation\Response */ protected function render($templateName, $args = array(), $status = 200) { @@ -387,7 +387,7 @@ class BaseAdminController extends BaseController * @param array $args the template arguments * @param null $templateDir * - * @return \Symfony\Component\HttpFoundation\Response + * @return \Thelia\Core\HttpFoundation\Response */ protected function renderRaw($templateName, $args = array(), $templateDir = null) { diff --git a/core/lib/Thelia/Controller/Admin/CategoryController.php b/core/lib/Thelia/Controller/Admin/CategoryController.php index 86e4bb00c..018aa3586 100755 --- a/core/lib/Thelia/Controller/Admin/CategoryController.php +++ b/core/lib/Thelia/Controller/Admin/CategoryController.php @@ -23,7 +23,7 @@ namespace Thelia\Controller\Admin; -use Symfony\Component\HttpFoundation\Response; +use Thelia\Core\HttpFoundation\Response; use Thelia\Core\Security\Resource\AdminResources; use Thelia\Core\Event\Category\CategoryDeleteEvent; use Thelia\Core\Event\TheliaEvents; @@ -320,7 +320,7 @@ class CategoryController extends AbstractCrudController /** * Add category pictures * - * @return \Symfony\Component\HttpFoundation\Response + * @return \Thelia\Core\HttpFoundation\Response */ public function addRelatedPictureAction() { diff --git a/core/lib/Thelia/Controller/Admin/ConfigController.php b/core/lib/Thelia/Controller/Admin/ConfigController.php index f8eafe820..67aec848a 100644 --- a/core/lib/Thelia/Controller/Admin/ConfigController.php +++ b/core/lib/Thelia/Controller/Admin/ConfigController.php @@ -181,7 +181,7 @@ class ConfigController extends AbstractCrudController /** * Change values modified directly from the variable list * - * @return Symfony\Component\HttpFoundation\Response the response + * @return Thelia\Core\HttpFoundation\Response the response */ public function changeValuesAction() { diff --git a/core/lib/Thelia/Controller/Admin/ContentController.php b/core/lib/Thelia/Controller/Admin/ContentController.php index adf3cc697..0b850734c 100644 --- a/core/lib/Thelia/Controller/Admin/ContentController.php +++ b/core/lib/Thelia/Controller/Admin/ContentController.php @@ -64,7 +64,7 @@ class ContentController extends AbstractCrudController /** * controller adding content to additional folder * - * @return mixed|\Symfony\Component\HttpFoundation\Response + * @return mixed|\Thelia\Core\HttpFoundation\Response */ public function addAdditionalFolderAction() { @@ -92,7 +92,7 @@ class ContentController extends AbstractCrudController /** * controller removing additional folder to a content * - * @return mixed|\Symfony\Component\HttpFoundation\Response + * @return mixed|\Thelia\Core\HttpFoundation\Response */ public function removeAdditionalFolderAction() { diff --git a/core/lib/Thelia/Controller/Admin/CouponController.php b/core/lib/Thelia/Controller/Admin/CouponController.php index 5cc71ac00..0169a16b9 100755 --- a/core/lib/Thelia/Controller/Admin/CouponController.php +++ b/core/lib/Thelia/Controller/Admin/CouponController.php @@ -58,7 +58,7 @@ class CouponController extends BaseAdminController /** * Manage Coupons list display * - * @return \Symfony\Component\HttpFoundation\Response + * @return \Thelia\Core\HttpFoundation\Response */ public function browseAction() { @@ -90,7 +90,7 @@ class CouponController extends BaseAdminController * * @param int $couponId Coupon Id * - * @return \Symfony\Component\HttpFoundation\Response + * @return \Thelia\Core\HttpFoundation\Response */ public function readAction($couponId) { @@ -117,7 +117,7 @@ class CouponController extends BaseAdminController /** * Manage Coupons creation display * - * @return \Symfony\Component\HttpFoundation\Response + * @return \Thelia\Core\HttpFoundation\Response */ public function createAction() { @@ -165,7 +165,7 @@ class CouponController extends BaseAdminController * * @param int $couponId Coupon id * - * @return \Symfony\Component\HttpFoundation\Response + * @return \Thelia\Core\HttpFoundation\Response */ public function updateAction($couponId) { @@ -270,7 +270,7 @@ class CouponController extends BaseAdminController * * @param string $conditionId Condition service id * - * @return \Symfony\Component\HttpFoundation\Response + * @return \Thelia\Core\HttpFoundation\Response */ public function getConditionInputAction($conditionId) { @@ -300,7 +300,7 @@ class CouponController extends BaseAdminController * * @param int $couponId Coupon id * - * @return \Symfony\Component\HttpFoundation\Response + * @return \Thelia\Core\HttpFoundation\Response */ public function updateConditionsAction($couponId) { diff --git a/core/lib/Thelia/Controller/Admin/CustomerController.php b/core/lib/Thelia/Controller/Admin/CustomerController.php index 93a007426..9719748fc 100644 --- a/core/lib/Thelia/Controller/Admin/CustomerController.php +++ b/core/lib/Thelia/Controller/Admin/CustomerController.php @@ -61,7 +61,7 @@ class CustomerController extends BaseAdminController * update customer action * * @param $customer_id - * @return mixed|\Symfony\Component\HttpFoundation\Response + * @return mixed|\Thelia\Core\HttpFoundation\Response */ public function updateAction($customer_id) { diff --git a/core/lib/Thelia/Controller/Admin/FileController.php b/core/lib/Thelia/Controller/Admin/FileController.php index ced780181..5c712898a 100755 --- a/core/lib/Thelia/Controller/Admin/FileController.php +++ b/core/lib/Thelia/Controller/Admin/FileController.php @@ -25,7 +25,7 @@ namespace Thelia\Controller\Admin; use Propel\Runtime\Exception\PropelException; use Symfony\Component\HttpFoundation\File\UploadedFile; -use Symfony\Component\HttpFoundation\Response; +use Thelia\Core\HttpFoundation\Response; use Thelia\Core\Security\Resource\AdminResources; use Thelia\Core\Event\Document\DocumentCreateOrUpdateEvent; use Thelia\Core\Event\Document\DocumentDeleteEvent; diff --git a/core/lib/Thelia/Controller/Admin/LangController.php b/core/lib/Thelia/Controller/Admin/LangController.php index 7c9eefad5..ccf980c81 100644 --- a/core/lib/Thelia/Controller/Admin/LangController.php +++ b/core/lib/Thelia/Controller/Admin/LangController.php @@ -117,7 +117,7 @@ class LangController extends BaseAdminController $changedObject = $event->getLang(); $this->adminLogAppend(AdminResources::LANGUAGE, AccessManager::UPDATE, sprintf("%s %s (ID %s) modified", 'Lang', $changedObject->getTitle(), $changedObject->getId())); - $this->redirectToRoute('/admin/configuration/languages'); + $this->redirectToRoute('admin.configuration.languages'); } catch (\Exception $e) { $error_msg = $e->getMessage(); } diff --git a/core/lib/Thelia/Controller/Admin/OrderController.php b/core/lib/Thelia/Controller/Admin/OrderController.php index 429d9837e..ff075b0e4 100644 --- a/core/lib/Thelia/Controller/Admin/OrderController.php +++ b/core/lib/Thelia/Controller/Admin/OrderController.php @@ -23,7 +23,7 @@ namespace Thelia\Controller\Admin; -use Symfony\Component\HttpFoundation\Response; +use Thelia\Core\HttpFoundation\Response; use Thelia\Core\Security\Resource\AdminResources; use Thelia\Core\Event\Order\OrderAddressEvent; use Thelia\Core\Event\Order\OrderEvent; diff --git a/core/lib/Thelia/Controller/Admin/ShippingZoneController.php b/core/lib/Thelia/Controller/Admin/ShippingZoneController.php index 2bd6363cc..8e8f38eec 100644 --- a/core/lib/Thelia/Controller/Admin/ShippingZoneController.php +++ b/core/lib/Thelia/Controller/Admin/ShippingZoneController.php @@ -55,7 +55,7 @@ class ShippingZoneController extends BaseAdminController } /** - * @return mixed|\Symfony\Component\HttpFoundation\Response + * @return mixed|\Thelia\Core\HttpFoundation\Response */ public function addArea() { diff --git a/core/lib/Thelia/Controller/Admin/SystemLogController.php b/core/lib/Thelia/Controller/Admin/SystemLogController.php new file mode 100644 index 000000000..96621717c --- /dev/null +++ b/core/lib/Thelia/Controller/Admin/SystemLogController.php @@ -0,0 +1,182 @@ +. */ +/* */ +/*************************************************************************************/ + +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; +/** + * Class LangController + * @package Thelia\Controller\Admin + * @author Manuel Raynaud + */ +class SystemLogController extends BaseAdminController +{ + + protected function renderTemplate() + { + $destinations = array(); + + $destination_directories = Tlog::getInstance()->getDestinationsDirectories(); + + foreach($destination_directories as $dir) { + $this->loadDefinedDestinations($dir, $destinations); + } + + $active_destinations = explode(";", ConfigQuery::read(Tlog::VAR_DESTINATIONS, Tlog::DEFAUT_DESTINATIONS)); + + return $this->render('system-logs', + array( + 'ip_address' => $this->getRequest()->getClientIp(), + 'destinations' => $destinations, + 'active_destinations' => $active_destinations + ) + ); + } + + protected function loadDefinedDestinations($directory, &$destinations) { + + try { + foreach (new \DirectoryIterator($directory) as $fileInfo) { + + if ($fileInfo->isDot()) continue; + + $matches = array(); + + if (preg_match("/([^\.]+)\.php/", $fileInfo->getFilename(), $matches)) { + + $classname = $matches[1]; + + if (! isset($destinations[$classname])) { + + $full_class_name = "Thelia\\Log\\Destination\\".$classname; + + $destinations[$classname] = new $full_class_name(); + } + } + } + } catch (\UnexpectedValueException $ex) { + // Directory does no exists -> Nothing to do + } + } + + public function defaultAction() + { + if (null !== $response = $this->checkAuth(AdminResources::SYSTEM_LOG, AccessManager::VIEW)) return $response; + + /* + const VAR_LEVEL = "tlog_level"; + const VAR_DESTINATIONS = "tlog_destinations"; + const VAR_PREFIXE = "tlog_prefix"; + const VAR_FILES = "tlog_files"; + const VAR_IP = "tlog_ip"; + const VAR_SHOW_REDIRECT = "tlog_show_redirect"; + + const DEFAULT_LEVEL = self::DEBUG; + const DEFAUT_DESTINATIONS = "Thelia\Log\Destination\TlogDestinationFile"; + const DEFAUT_PREFIXE = "#NUM: #NIVEAU [#FICHIER:#FONCTION()] {#LIGNE} #DATE #HEURE: "; + const DEFAUT_FILES = "*"; + const DEFAUT_IP = ""; + const DEFAUT_SHOW_REDIRECT = 0; + + */ + + // Hydrate the general configuration form + $systemLogForm = new SystemLogConfigurationForm($this->getRequest(), 'form', array( + 'level' => ConfigQuery::read(Tlog::VAR_LEVEL, Tlog::DEFAULT_LEVEL), + 'format' => ConfigQuery::read(Tlog::VAR_PREFIXE, Tlog::DEFAUT_PREFIXE), + 'show_redirections' => ConfigQuery::read(Tlog::VAR_SHOW_REDIRECT, Tlog::DEFAUT_SHOW_REDIRECT), + 'files' => ConfigQuery::read(Tlog::VAR_FILES, Tlog::DEFAUT_FILES), + 'ip_addresses' => ConfigQuery::read(Tlog::VAR_IP, Tlog::DEFAUT_IP), + )); + + $this->getParserContext()->addForm($systemLogForm); + + return $this->renderTemplate(); + } + + public function saveAction() + { + if (null !== $response = $this->checkAuth(AdminResources::LANGUAGE, AccessManager::UPDATE)) return $response; + + $error_msg = false; + + $systemLogForm = new SystemLogConfigurationForm($this->getRequest()); + + try { + $form = $this->validateForm($systemLogForm); + + $data = $form->getData(); + + ConfigQuery::write(Tlog::VAR_LEVEL , $data['level']); + ConfigQuery::write(Tlog::VAR_PREFIXE , $data['format']); + ConfigQuery::write(Tlog::VAR_SHOW_REDIRECT , $data['show_redirections']); + ConfigQuery::write(Tlog::VAR_FILES , $data['files']); + ConfigQuery::write(Tlog::VAR_IP , $data['ip_addresses']); + + // Save destination configuration + $destinations = $this->getRequest()->get('destinations'); + $configs = $this->getRequest()->get('config'); + + $active_destinations = array(); + + foreach($destinations as $classname => $destination) { + + if (isset($destination['active'])) { + $active_destinations[] = $destination['classname']; + } + + if (isset($configs[$classname])) { + + // Update destinations configuration + foreach($configs[$classname] as $var => $value) { + ConfigQuery::write($var, $value, true, true); + } + } + } + + // Update active destinations list + ConfigQuery::write(Tlog::VAR_DESTINATIONS, implode(';', $active_destinations)); + + $this->adminLogAppend(AdminResources::SYSTEM_LOG, AccessManager::UPDATE, "System log configuration changed"); + + $this->redirectToRoute('admin.configuration.system-logs.default'); + + } catch (\Exception $ex) { + $error_msg = $ex->getMessage(); + } + + $this->setupFormErrorContext( + $this->getTranslator()->trans("System log configuration failed."), + $error_msg, + $systemLogForm, + $ex + ); + + return $this->renderTemplate(); + } +} diff --git a/core/lib/Thelia/Controller/BaseController.php b/core/lib/Thelia/Controller/BaseController.php index 4bfc3c65f..d5868b8d2 100755 --- a/core/lib/Thelia/Controller/BaseController.php +++ b/core/lib/Thelia/Controller/BaseController.php @@ -22,7 +22,7 @@ /*************************************************************************************/ namespace Thelia\Controller; -use Symfony\Component\HttpFoundation\Response; +use Thelia\Core\HttpFoundation\Response; use Symfony\Component\DependencyInjection\ContainerAware; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; @@ -58,7 +58,7 @@ class BaseController extends ContainerAware /** * Return an empty response (after an ajax request, for example) * @param int $status - * @return \Symfony\Component\HttpFoundation\Response + * @return \Thelia\Core\HttpFoundation\Response */ protected function nullResponse($status = 200) { diff --git a/core/lib/Thelia/Core/Bundle/TheliaBundle.php b/core/lib/Thelia/Core/Bundle/TheliaBundle.php index 9a536f88d..3df5e4345 100755 --- a/core/lib/Thelia/Core/Bundle/TheliaBundle.php +++ b/core/lib/Thelia/Core/Bundle/TheliaBundle.php @@ -60,13 +60,12 @@ class TheliaBundle extends Bundle $container->addScope(new Scope('request')); $container + ->addCompilerPass(new TranslatorPass()) ->addCompilerPass(new RegisterListenersPass()) ->addCompilerPass(new RegisterParserPluginPass()) ->addCompilerPass(new RegisterRouterPass()) ->addCompilerPass(new RegisterCouponPass()) ->addCompilerPass(new RegisterCouponConditionPass()) - ->addCompilerPass(new TranslatorPass()) - ; } } diff --git a/core/lib/Thelia/Core/Controller/ControllerResolver.php b/core/lib/Thelia/Core/Controller/ControllerResolver.php index ebf0eff86..a9cd30feb 100755 --- a/core/lib/Thelia/Core/Controller/ControllerResolver.php +++ b/core/lib/Thelia/Core/Controller/ControllerResolver.php @@ -26,6 +26,7 @@ namespace Thelia\Core\Controller; use Symfony\Component\HttpKernel\Controller\ControllerResolver as BaseControllerResolver; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerAwareInterface; +use Psr\Log\LoggerInterface; /** * ControllerResolver that supports "a:b:c", "service:method" and class::method" notations in routes definition diff --git a/core/lib/Thelia/Core/EventListener/ViewListener.php b/core/lib/Thelia/Core/EventListener/ViewListener.php index db036f111..667a3d42c 100755 --- a/core/lib/Thelia/Core/EventListener/ViewListener.php +++ b/core/lib/Thelia/Core/EventListener/ViewListener.php @@ -27,7 +27,7 @@ use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; +use Thelia\Core\HttpFoundation\Response; use Symfony\Component\Routing\Router; use Thelia\Core\Template\Exception\ResourceNotFoundException; use Thelia\Core\Template\ParserInterface; diff --git a/core/lib/Thelia/Core/HttpFoundation/Response.php b/core/lib/Thelia/Core/HttpFoundation/Response.php new file mode 100644 index 000000000..277c16cc2 --- /dev/null +++ b/core/lib/Thelia/Core/HttpFoundation/Response.php @@ -0,0 +1,48 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Core\HttpFoundation; + +use Symfony\Component\HttpFoundation\Response as BaseResponse; +use Thelia\Log\Tlog; + +/** + * extends Thelia\Core\HttpFoundation\Response for adding some helpers + * + * Class Response + * @package Thelia\Core\HttpFoundation + * @author Franck Allimant + */ +class Response extends BaseResponse +{ + /** + * Allow Tlog to write log stuff in the fina content. + * + * @see \Thelia\Core\HttpFoundation\Response::sendContent() + */ + public function sendContent() { + + Tlog::getInstance()->write($this->content); + + parent::sendContent(); + } +} diff --git a/core/lib/Thelia/Core/Security/Resource/AdminResources.php b/core/lib/Thelia/Core/Security/Resource/AdminResources.php index 6efcf89c2..295de1fe8 100644 --- a/core/lib/Thelia/Core/Security/Resource/AdminResources.php +++ b/core/lib/Thelia/Core/Security/Resource/AdminResources.php @@ -97,4 +97,6 @@ final class AdminResources const TAX = "admin.configuration.tax"; const TEMPLATE = "admin.configuration.template"; + + const SYSTEM_LOG = "admin.configuration.system-log"; } diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php index a401755a4..ba6f1d1f9 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php @@ -238,13 +238,13 @@ class DataAccessFunctions extends AbstractSmartyPlugin public function ConfigDataAccess($params, $smarty) { - if (false === array_key_exists("key", $params)) { - return null; - } + $key = $this->getParam($params, 'key', false); - $key = $params['key']; + if ($key === false) return null; - return ConfigQuery::read($key); + $default = $this->getParam($params, 'default', ''); + + return ConfigQuery::read($key, $default); } /** diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/FlashMessage.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/FlashMessage.php index 61a68fdc7..e89898af6 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/FlashMessage.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/FlashMessage.php @@ -74,13 +74,18 @@ class FlashMessage extends AbstractSmartyPlugin public function getFlashMessage($params, $content, \Smarty_Internal_Template $template, &$repeat) { if ($repeat) { - $key = $params['key']; - $flashBag = $this->request->getSession()->get('flashMessage'); - $template->assign('value', $flashBag[$key]); - // Reset flash message (can be read once) - unset($flashBag[$key]); - $this->request->getSession()->set('flashMessage', $flashBag); + if (false !== $key = $this->getParam($params, 'key', false)) { + + $flashBag = $this->request->getSession()->get('flashMessage'); + + $template->assign('value', $flashBag[$key]); + + // Reset flash message (can be read once) + unset($flashBag[$key]); + + $this->request->getSession()->set('flashMessage', $flashBag); + } } else { return $content; } diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/Module.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/Module.php index beb9a6b25..2dfbb08fc 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/Module.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/Module.php @@ -41,14 +41,16 @@ class Module extends AbstractSmartyPlugin public function theliaModule($params, \Smarty_Internal_Template $template) { $content = null; - if (array_key_exists('location', $params)) { - $location = $params['location']; + + if (false !== $location = $this->getParam($params, 'location', false)) { + $modules = ModuleQuery::getActivated(); foreach ($modules as $module) { - $file = THELIA_MODULE_DIR . "/". ucfirst($module->getCode()) . "/AdminIncludes/".$location.".html"; - if(file_exists($file)) { + $file = sprintf("%s/%s/AdminIncludes/%s.html", THELIA_MODULE_DIR, ucfirst($module->getCode()), $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 92c1377ce..272f6787c 100755 --- a/core/lib/Thelia/Core/Template/Smarty/SmartyParser.php +++ b/core/lib/Thelia/Core/Template/Smarty/SmartyParser.php @@ -7,7 +7,7 @@ use \Symfony\Component\EventDispatcher\EventDispatcherInterface; use \Smarty; -use Symfony\Component\HttpFoundation\Response; +use Thelia\Core\HttpFoundation\Response; use Thelia\Core\Template\ParserInterface; use Thelia\Core\Template\Smarty\AbstractSmartyPlugin; @@ -155,7 +155,7 @@ class SmartyParser extends Smarty implements ParserInterface * * set $content with the body of the response or the Response object directly * - * @param string|Symfony\Component\HttpFoundation\Response $content + * @param string|Thelia\Core\HttpFoundation\Response $content */ public function setContent($content) { diff --git a/core/lib/Thelia/Core/Thelia.php b/core/lib/Thelia/Core/Thelia.php index 3d476ad30..cc9f4bae4 100755 --- a/core/lib/Thelia/Core/Thelia.php +++ b/core/lib/Thelia/Core/Thelia.php @@ -69,7 +69,7 @@ class Thelia extends Kernel protected function initPropel() { - if (file_exists(THELIA_ROOT . '/local/config/database.yml') === false) { + if (file_exists(THELIA_CONF_DIR . 'database.yml') === false) { return ; } @@ -96,7 +96,7 @@ class Thelia extends Kernel { parent::boot(); - if (file_exists(THELIA_ROOT . '/local/config/database.yml') === true) { + if (file_exists(THELIA_CONF_DIR . 'database.yml') === true) { $this->getContainer()->get("event_dispatcher")->dispatch(TheliaEvents::BOOT); } diff --git a/core/lib/Thelia/Exception/CouponExpiredException.php b/core/lib/Thelia/Exception/CouponExpiredException.php index c1ccace0a..271927cb4 100644 --- a/core/lib/Thelia/Exception/CouponExpiredException.php +++ b/core/lib/Thelia/Exception/CouponExpiredException.php @@ -46,7 +46,7 @@ class CouponExpiredException extends \Exception public function __construct($couponCode) { $message = 'Expired Coupon ' . $couponCode . 'attempt'; - Tlog::getInstance()->addInfo($message); + Tlog::getInstance()->addWarning($message); parent::__construct($message); } diff --git a/core/lib/Thelia/Form/AdministratorCreationForm.php b/core/lib/Thelia/Form/AdministratorCreationForm.php index 4b5afe34c..f0a479dd2 100644 --- a/core/lib/Thelia/Form/AdministratorCreationForm.php +++ b/core/lib/Thelia/Form/AdministratorCreationForm.php @@ -81,7 +81,7 @@ class AdministratorCreationForm extends BaseForm array($this, "verifyPasswordField") ))) ), - "label" => "Password confirmation", + "label" => Translator::getInstance()->trans('Password confirmation'), "label_attr" => array( "for" => "password_confirmation" ), @@ -94,7 +94,7 @@ class AdministratorCreationForm extends BaseForm "constraints" => array( new Constraints\NotBlank(), ), - "label" => "Profile", + "label" => Translator::getInstance()->trans('Profile'), "label_attr" => array( "for" => "profile" ), diff --git a/core/lib/Thelia/Form/ConfigCreationForm.php b/core/lib/Thelia/Form/ConfigCreationForm.php index e52f44c29..56df63f8a 100644 --- a/core/lib/Thelia/Form/ConfigCreationForm.php +++ b/core/lib/Thelia/Form/ConfigCreationForm.php @@ -25,6 +25,7 @@ namespace Thelia\Form; use Symfony\Component\Validator\Constraints; use Thelia\Model\ConfigQuery; use Symfony\Component\Validator\ExecutionContextInterface; +use Thelia\Core\Translation\Translator; class ConfigCreationForm extends BaseForm { @@ -41,7 +42,7 @@ class ConfigCreationForm extends BaseForm $this->formBuilder ->add("name", "text", array( "constraints" => $name_constraints, - "label" => "Name *", + "label" => Translator::getInstance()->trans('Name *'), "label_attr" => array( "for" => "name" ) @@ -50,7 +51,7 @@ class ConfigCreationForm extends BaseForm "constraints" => array( new Constraints\NotBlank() ), - "label" => "Purpose *", + "label" => Translator::getInstance()->trans('Purpose *'), "label_attr" => array( "for" => "purpose" ) @@ -61,14 +62,14 @@ class ConfigCreationForm extends BaseForm ) )) ->add("value", "text", array( - "label" => "Value *", + "label" => Translator::getInstance()->trans('Value *'), "label_attr" => array( "for" => "value" ) )) ->add("hidden", "hidden", array()) ->add("secured", "hidden", array( - "label" => "Prevent variable modification or deletion, except for super-admin" + "label" => Translator::getInstance()->trans('Prevent variable modification or deletion, except for super-admin') )) ; } @@ -83,7 +84,7 @@ class ConfigCreationForm extends BaseForm $config = ConfigQuery::create()->findOneByName($value); if ($config) { - $context->addViolation(sprintf("A variable with name \"%s\" already exists.", $value)); + $context->addViolation(Translator::getInstance()->trans('A variable with name "%name" already exists.', array('%name' => $value))); } } diff --git a/core/lib/Thelia/Form/ConfigModificationForm.php b/core/lib/Thelia/Form/ConfigModificationForm.php index 257af38c5..318da7185 100644 --- a/core/lib/Thelia/Form/ConfigModificationForm.php +++ b/core/lib/Thelia/Form/ConfigModificationForm.php @@ -24,6 +24,7 @@ namespace Thelia\Form; use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Constraints\GreaterThan; +use Thelia\Core\Translation\Translator; class ConfigModificationForm extends BaseForm { @@ -43,20 +44,20 @@ class ConfigModificationForm extends BaseForm "constraints" => array( new NotBlank() ), - "label" => "Name", + "label" => Translator::getInstance()->trans('Name'), "label_attr" => array( "for" => "name" ) )) ->add("value", "text", array( - "label" => "Value", + "label" => Translator::getInstance()->trans('Value'), "label_attr" => array( "for" => "value" ) )) ->add("hidden", "hidden", array()) ->add("secured", "hidden", array( - "label" => "Prevent variable modification or deletion, except for super-admin" + "label" => Translator::getInstance()->trans('Prevent variable modification or deletion, except for super-admin') )) ; diff --git a/core/lib/Thelia/Form/ContentCreationForm.php b/core/lib/Thelia/Form/ContentCreationForm.php index df8838f59..663ed4c1b 100644 --- a/core/lib/Thelia/Form/ContentCreationForm.php +++ b/core/lib/Thelia/Form/ContentCreationForm.php @@ -34,7 +34,7 @@ class ContentCreationForm extends BaseForm "constraints" => array( new NotBlank() ), - "label" => "Content title *", + "label" => Translator::getInstance()->trans('Content title *'), "label_attr" => array( "for" => "title" ) diff --git a/core/lib/Thelia/Form/CurrencyCreationForm.php b/core/lib/Thelia/Form/CurrencyCreationForm.php index 3328cd342..9872d100c 100644 --- a/core/lib/Thelia/Form/CurrencyCreationForm.php +++ b/core/lib/Thelia/Form/CurrencyCreationForm.php @@ -26,6 +26,7 @@ use Symfony\Component\Validator\Constraints; use Thelia\Model\CurrencyQuery; use Symfony\Component\Validator\ExecutionContextInterface; use Symfony\Component\Validator\Constraints\NotBlank; +use Thelia\Core\Translation\Translator; class CurrencyCreationForm extends BaseForm { @@ -44,7 +45,7 @@ class CurrencyCreationForm extends BaseForm "constraints" => array( new NotBlank() ), - "label" => "Name *", + "label" => Translator::getInstance()->trans('Name *'), "label_attr" => array( "for" => "name" )) @@ -58,7 +59,7 @@ class CurrencyCreationForm extends BaseForm "constraints" => array( new NotBlank() ), - "label" => "Symbol *", + "label" => Translator::getInstance()->trans('Symbol *'), "label_attr" => array( "for" => "symbol" )) @@ -67,7 +68,7 @@ class CurrencyCreationForm extends BaseForm "constraints" => array( new NotBlank() ), - "label" => "Rate from € *", + "label" => Translator::getInstance()->trans('Rate from € *'), "label_attr" => array( "for" => "rate" )) @@ -76,7 +77,7 @@ class CurrencyCreationForm extends BaseForm "constraints" => array( new NotBlank() ), - "label" => "ISO 4217 code *", + "label" => Translator::getInstance()->trans('ISO 4217 code *'), "label_attr" => array( "for" => "iso_4217_code" )) @@ -94,7 +95,7 @@ class CurrencyCreationForm extends BaseForm $currency = CurrencyQuery::create()->findOneByCode($value); if ($currency) { - $context->addViolation(sprintf("A currency with code \"%s\" already exists.", $value)); + $context->addViolation(Translator::getInstance()->trans('A currency with code "%name" already exists.', array('%name' => $value))); } } diff --git a/core/lib/Thelia/Form/CustomerPasswordUpdateForm.php b/core/lib/Thelia/Form/CustomerPasswordUpdateForm.php index afea21f70..0a29aeda7 100755 --- a/core/lib/Thelia/Form/CustomerPasswordUpdateForm.php +++ b/core/lib/Thelia/Form/CustomerPasswordUpdateForm.php @@ -70,7 +70,7 @@ class CustomerPasswordUpdateForm extends BaseForm array($this, "verifyPasswordField") ))) ), - "label" => "Password confirmation", + "label" => Translator::getInstance()->trans('Password confirmation'), "label_attr" => array( "for" => "password_confirmation" ) diff --git a/core/lib/Thelia/Form/CustomerProfilUpdateForm.php b/core/lib/Thelia/Form/CustomerProfilUpdateForm.php index d1e928d0c..471c12432 100755 --- a/core/lib/Thelia/Form/CustomerProfilUpdateForm.php +++ b/core/lib/Thelia/Form/CustomerProfilUpdateForm.php @@ -58,7 +58,7 @@ class CustomerProfilUpdateForm extends CustomerCreateForm // Add Newsletter ->add("newsletter", "checkbox", array( - "label" => "I would like to receive the newsletter our the latest news.", + "label" => Translator::getInstance()->trans('I would like to receive the newsletter or the latest news.'), "label_attr" => array( "for" => "newsletter" ), diff --git a/core/lib/Thelia/Form/MessageCreationForm.php b/core/lib/Thelia/Form/MessageCreationForm.php index 6ce84cb06..288de1d36 100644 --- a/core/lib/Thelia/Form/MessageCreationForm.php +++ b/core/lib/Thelia/Form/MessageCreationForm.php @@ -25,6 +25,7 @@ namespace Thelia\Form; use Symfony\Component\Validator\Constraints; use Thelia\Model\MessageQuery; use Symfony\Component\Validator\ExecutionContextInterface; +use Thelia\Core\Translation\Translator; class MessageCreationForm extends BaseForm { @@ -41,7 +42,7 @@ class MessageCreationForm extends BaseForm $this->formBuilder ->add("name", "text", array( "constraints" => $name_constraints, - "label" => "Name *", + "label" => Translator::getInstance()->trans('Name *'), "label_attr" => array( "for" => "name" ) @@ -50,7 +51,7 @@ class MessageCreationForm extends BaseForm "constraints" => array( new Constraints\NotBlank() ), - "label" => "Purpose *", + "label" => Translator::getInstance()->trans('Purpose *'), "label_attr" => array( "for" => "purpose" ) @@ -74,7 +75,7 @@ class MessageCreationForm extends BaseForm $message = MessageQuery::create()->findOneByName($value); if ($message) { - $context->addViolation(sprintf("A message with name \"%s\" already exists.", $value)); + $context->addViolation(Translator::getInstance()->trans('A message with name "%name" already exists.', array('%name' => $value))); } } diff --git a/core/lib/Thelia/Form/MessageModificationForm.php b/core/lib/Thelia/Form/MessageModificationForm.php index c8f20448d..c22d67bbf 100644 --- a/core/lib/Thelia/Form/MessageModificationForm.php +++ b/core/lib/Thelia/Form/MessageModificationForm.php @@ -24,6 +24,7 @@ namespace Thelia\Form; use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Constraints\GreaterThan; +use Thelia\Core\Translation\Translator; class MessageModificationForm extends BaseForm { @@ -33,37 +34,37 @@ class MessageModificationForm extends BaseForm ->add("id" , "hidden", array("constraints" => array(new GreaterThan(array('value' => 0))))) ->add("name" , "text" , array( "constraints" => array(new NotBlank()), - "label" => "Name *", + "label" => Translator::getInstance()->trans('Name *'), "label_attr" => array( "for" => "name" ) )) ->add("secured" , "text" , array( - "label" => "Prevent mailing template modification or deletion, except for super-admin" + "label" => Translator::getInstance()->trans('Prevent mailing template modification or deletion, except for super-admin') )) ->add("locale" , "text" , array()) ->add("title" , "text" , array( "constraints" => array(new NotBlank()), - "label" => "Title *", + "label" => Translator::getInstance()->trans('Title *'), "label_attr" => array( "for" => "title" ) )) ->add("subject" , "text" , array( "constraints" => array(new NotBlank()), - "label" => "Message subject *", + "label" => Translator::getInstance()->trans('Message subject *'), "label_attr" => array( "for" => "subject" ) )) ->add("html_message" , "text" , array( - "label" => "HTML Message", + "label" => Translator::getInstance()->trans('HTML Message'), "label_attr" => array( "for" => "html_message" ) )) ->add("text_message" , "text" , array( - "label" => "Text Message", + "label" => Translator::getInstance()->trans('Text Message'), "label_attr" => array( "for" => "text_message" ) diff --git a/core/lib/Thelia/Form/ProductCreationForm.php b/core/lib/Thelia/Form/ProductCreationForm.php index c1b8bd6b4..de683e27a 100644 --- a/core/lib/Thelia/Form/ProductCreationForm.php +++ b/core/lib/Thelia/Form/ProductCreationForm.php @@ -43,12 +43,12 @@ class ProductCreationForm extends BaseForm $this->formBuilder ->add("ref", "text", array( "constraints" => $ref_constraints, - "label" => "Product reference *", + "label" => Translator::getInstance()->trans('Product reference *'), "label_attr" => array("for" => "ref") )) ->add("title", "text", array( "constraints" => array(new NotBlank()), - "label" => "Product title *", + "label" => Translator::getInstance()->trans('Product title *'), "label_attr" => array("for" => "title") )) ->add("default_category", "integer", array( diff --git a/core/lib/Thelia/Form/SystemLogConfigurationForm.php b/core/lib/Thelia/Form/SystemLogConfigurationForm.php new file mode 100644 index 000000000..9ba9e6cf2 --- /dev/null +++ b/core/lib/Thelia/Form/SystemLogConfigurationForm.php @@ -0,0 +1,86 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form; + +use Symfony\Component\Validator\Constraints; +use Thelia\Model\ConfigQuery; +use Symfony\Component\Validator\ExecutionContextInterface; +use Thelia\Log\Tlog; +use Thelia\Core\Translation\Translator; + +class SystemLogConfigurationForm extends BaseForm +{ + protected function buildForm() + { + $this->formBuilder + ->add("level", "choice", array( + 'choices' => array( + Tlog::MUET => Translator::getInstance()->trans("Disabled"), + Tlog::DEBUG => Translator::getInstance()->trans("Debug"), + Tlog::INFO => Translator::getInstance()->trans("Information"), + Tlog::NOTICE => Translator::getInstance()->trans("Notices"), + Tlog::WARNING => Translator::getInstance()->trans("Warnings"), + Tlog::ERROR => Translator::getInstance()->trans("Errors"), + Tlog::CRITICAL => Translator::getInstance()->trans("Critical"), + Tlog::ALERT => Translator::getInstance()->trans("Alerts"), + Tlog::EMERGENCY => Translator::getInstance()->trans("Emergency"), + ), + + "label" => Translator::getInstance()->trans('Log level *'), + "label_attr" => array( + "for" => "level_field" + ) + )) + ->add("format", "text", array( + "label" => Translator::getInstance()->trans('Log format *'), + "label_attr" => array( + "for" => "format_field" + ) + )) + ->add("show_redirections", "integer", array( + "constraints" => array(new Constraints\NotBlank()), + "label" => Translator::getInstance()->trans('Show redirections *'), + "label_attr" => array( + "for" => "show_redirections_field" + ) + )) + ->add("files", "text", array( + "label" => Translator::getInstance()->trans('Activate logs only for these files'), + "label_attr" => array( + "for" => "files_field" + ) + )) + ->add("ip_addresses", "text", array( + "label" => Translator::getInstance()->trans('Activate logs only for these IP Addresses'), + "label_attr" => array( + "for" => "files_field" + ) + )) + ; + } + + public function getName() + { + return "thelia_system_log_configuration"; + } +} diff --git a/core/lib/Thelia/Log/AbstractTlogDestination.php b/core/lib/Thelia/Log/AbstractTlogDestination.php index 582f57934..0d3cde9e1 100755 --- a/core/lib/Thelia/Log/AbstractTlogDestination.php +++ b/core/lib/Thelia/Log/AbstractTlogDestination.php @@ -31,9 +31,6 @@ abstract class AbstractTlogDestination //Tableau des lignes de logs stockés avant utilisation par ecrire() protected $_logs; - // Vaudra true si on est dans le back office. - protected $flag_back_office = false; - public function __construct() { $this->_configs = array(); @@ -50,8 +47,8 @@ abstract class AbstractTlogDestination public function setConfig($name, $value) { foreach ($this->_configs as $config) { - if ($config->name == $name) { - $config->value = $value; + if ($config->getName() == $name) { + $config->setValue($value); // Appliquer les changements $this->configure(); @@ -66,8 +63,8 @@ abstract class AbstractTlogDestination public function getConfig($name) { foreach ($this->_configs as $config) { - if ($config->name == $name) { - return $config->value; + if ($config->getName() == $name) { + return $config->getValue(); } } @@ -79,26 +76,19 @@ abstract class AbstractTlogDestination return $this->_configs; } - public function SetBackOfficeMode($bool) - { - $this->flag_back_office = $bool; - } - //Ajoute une ligne de logs à la destination public function add($string) { $this->_logs[] = $string; } - protected function InsertAfterBody(&$res, $logdata) + protected function insertAfterBody(&$res, $logdata) { - $match = array(); + $match = array(); - if (preg_match("/(]*>)/i", $res, $match)) { - $res = str_replace($match[0], $match[0] . "\n" . $logdata, $res); - } else { - $res = $logdata . $res; - } + if (preg_match("/(]*>)/i", $res, $match)) { + $res = str_replace($match[0], $match[0] . "\n" . $logdata, $res); + } } // Demande à la destination de se configurer pour être prête @@ -106,7 +96,7 @@ abstract class AbstractTlogDestination // que seul le paramètre de configuration indiqué a été modifié. protected function configure() { - // Cette methode doit etre surchargée si nécessaire. + // Cette methode doit etre surchargée si nécessaire. } //Lance l'écriture de tous les logs par la destination diff --git a/core/lib/Thelia/Log/Destination/TlogDestinationFile.php b/core/lib/Thelia/Log/Destination/TlogDestinationFile.php index 6d2da2b52..a045196fe 100755 --- a/core/lib/Thelia/Log/Destination/TlogDestinationFile.php +++ b/core/lib/Thelia/Log/Destination/TlogDestinationFile.php @@ -25,6 +25,7 @@ namespace Thelia\Log\Destination; use Thelia\Log\AbstractTlogDestination; use Thelia\Log\TlogDestinationConfig; +use Thelia\Core\Translation\Translator; class TlogDestinationFile extends AbstractTlogDestination { @@ -41,7 +42,7 @@ class TlogDestinationFile extends AbstractTlogDestination public function __construct() { - $this->path_defaut = THELIA_ROOT . "log/" . self::TLOG_DEFAULT_NAME; + $this->path_defaut = THELIA_ROOT . "log" . DS . self::TLOG_DEFAULT_NAME; parent::__construct(); } @@ -69,12 +70,12 @@ class TlogDestinationFile extends AbstractTlogDestination public function getTitle() { - return "Text File"; + return Translator::getInstance()->trans('Text File'); } public function getDescription() { - return "Store logs into text file"; + return Translator::getInstance()->trans('Store logs into text file'); } public function getConfigs() @@ -82,15 +83,15 @@ class TlogDestinationFile extends AbstractTlogDestination return array( new TlogDestinationConfig( self::VAR_PATH_FILE, - "Chemin du fichier", - "Attention, vous devez indiquer un chemin absolu.
Le répertoire de base de votre Thelia est ".dirname(getcwd()), + 'Absolute file path', + 'You should enter an abolute file path. The base directory of your Thelia installation is '.THELIA_ROOT, $this->path_defaut, TlogDestinationConfig::TYPE_TEXTFIELD ), new TlogDestinationConfig( self::VAR_MODE, - "Mode d'ouverture (A ou E)", - "Indiquez E pour ré-initialiser le fichier à chaque requête, A pour ne jamais réinitialiser le fichier. Pensez à le vider de temps en temps !", + 'File opening mode (A or E)', + 'Enter E to empty this file for each request, or A to always append logs. Consider resetting the file from time to time', self::VALEUR_MODE_DEFAULT, TlogDestinationConfig::TYPE_TEXTFIELD ) diff --git a/core/lib/Thelia/Log/Destination/TlogDestinationHtml.php b/core/lib/Thelia/Log/Destination/TlogDestinationHtml.php index a510e18ef..7d0be3fa8 100755 --- a/core/lib/Thelia/Log/Destination/TlogDestinationHtml.php +++ b/core/lib/Thelia/Log/Destination/TlogDestinationHtml.php @@ -24,6 +24,7 @@ namespace Thelia\Log\Destination; use Thelia\Log\AbstractTlogDestination; +use Thelia\Log\TlogDestinationConfig; class TlogDestinationHtml extends AbstractTlogDestination { @@ -46,12 +47,12 @@ class TlogDestinationHtml extends AbstractTlogDestination public function getTitle() { - return "Affichage direct dans la page, en HTML"; + return "Direct HTML display"; } public function getDescription() { - return "Permet d'afficher les logs directement dans la page resultat, avec une mise en forme HTML."; + return "Display logs in HTML format, on top of generated pages."; } public function getConfigs() @@ -59,8 +60,8 @@ class TlogDestinationHtml extends AbstractTlogDestination return array( new TlogDestinationConfig( self::VAR_STYLE, - "Style d'affichage direct dans la page", - "Vous pouvez aussi laisser ce champ vide, et créer un style \"tlog-trace\" dans votre feuille de style.", + "CSS of each log line", + "You may also leave this field empty, and define a \"tlog-trace\" style in your CSS.", self::VALEUR_STYLE_DEFAUT, TlogDestinationConfig::TYPE_TEXTAREA ) @@ -71,6 +72,6 @@ class TlogDestinationHtml extends AbstractTlogDestination { $block = sprintf('
%s
', $this->style, htmlspecialchars(implode("\n", $this->_logs))); - $this->InsertAfterBody($res, $block); + $this->insertAfterBody($res, $block); } } diff --git a/core/lib/Thelia/Log/Destination/TlogDestinationJavascriptConsole.php b/core/lib/Thelia/Log/Destination/TlogDestinationJavascriptConsole.php new file mode 100644 index 000000000..546ab488c --- /dev/null +++ b/core/lib/Thelia/Log/Destination/TlogDestinationJavascriptConsole.php @@ -0,0 +1,51 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Log\Destination; + +use Thelia\Log\AbstractTlogDestination; + +class TlogDestinationJavascriptConsole extends AbstractTlogDestination { + + public function getTitle() { + return "Browser's Javascript console"; + } + + public function getDescription() { + return "The Thelia logs are displayed in your browser's Javascript console."; + } + + public function write(&$res) { + + $content = ''."\n"; + + if (preg_match("||i", $res)) + $res = preg_replace("||i", "$content", $res); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Log/Destination/TlogDestinationNull.php b/core/lib/Thelia/Log/Destination/TlogDestinationNull.php index 1fa8eaf3a..b78d24258 100755 --- a/core/lib/Thelia/Log/Destination/TlogDestinationNull.php +++ b/core/lib/Thelia/Log/Destination/TlogDestinationNull.php @@ -29,12 +29,12 @@ class TlogDestinationNull extends AbstractTlogDestination { public function getTitle() { - return "Trou noir"; + return "Black hole"; } public function getDescription() { - return "Cette destination ne provoque aucune sortie"; + return "This destinations consumes the logs but don't display them"; } public function add($string) diff --git a/core/lib/Thelia/Log/Destination/TlogDestinationPopup.php b/core/lib/Thelia/Log/Destination/TlogDestinationPopup.php new file mode 100644 index 000000000..1734e2f43 --- /dev/null +++ b/core/lib/Thelia/Log/Destination/TlogDestinationPopup.php @@ -0,0 +1,111 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Log\Destination; + +use Thelia\Log\AbstractTlogDestination; +use Thelia\Log\TlogDestinationConfig; + +class TlogDestinationPopup extends AbstractTlogDestination { + + // Nom des variables de configuration + // ---------------------------------- + const VAR_POPUP_WIDTH = "tlog_destinationpopup_width"; + const VALEUR_POPUP_WIDTH_DEFAUT = "600"; + + const VAR_POPUP_HEIGHT = "tlog_destinationpopup_height"; + const VALEUR_POPUP_HEIGHT_DEFAUT = "600"; + + const VAR_POPUP_TPL = "tlog_destinationpopup_template"; + // Ce fichier doit se trouver dans le même répertoire que TlogDestinationPopup.class.php + const VALEUR_POPUP_TPL_DEFAUT = "TlogDestinationPopup.tpl"; + + public function getTitle() { + return "Javascript popup window"; + } + + public function getDescription() { + return "Display logs in a popup window, separate from the main window ."; + } + + public function getConfigs() { + return array( + new TlogDestinationConfig( + self::VAR_POPUP_TPL, + "Popup windows template", + "Put #LOGTEXT in the template text where you want to display logs..", + file_get_contents(__DIR__.DS. self::VALEUR_POPUP_TPL_DEFAUT), + TlogDestinationConfig::TYPE_TEXTAREA + ), + new TlogDestinationConfig( + self::VAR_POPUP_HEIGHT, + "Height of the popup window", + "In pixels", + self::VALEUR_POPUP_HEIGHT_DEFAUT, + TlogDestinationConfig::TYPE_TEXTFIELD + ), + new TlogDestinationConfig( + self::VAR_POPUP_WIDTH, + "Width of the popup window", + "In pixels", + self::VALEUR_POPUP_WIDTH_DEFAUT, + TlogDestinationConfig::TYPE_TEXTFIELD + ) + ); + } + + public function write(&$res) { + + $content = ""; $count = 1; + + foreach($this->_logs as $line) { + $content .= "
".htmlspecialchars($line)."
"; + } + + $tpl = $this->getConfig(self::VAR_POPUP_TPL); + + $tpl = str_replace('#LOGTEXT', $content, $tpl); + $tpl = str_replace(array("\r\n", "\r", "\n"), '\\n', $tpl); + + $wop = sprintf(' + ', + $this->getConfig(self::VAR_POPUP_WIDTH), + $this->getConfig(self::VAR_POPUP_HEIGHT), + str_replace('"', '\\"', $tpl) + ); + + if (preg_match("||i", $res)) + $res = preg_replace("||i", "$wop\n", $res); + else + $res .= $wop; + } +} diff --git a/core/lib/Thelia/Log/Destination/TlogDestinationPopup.tpl b/core/lib/Thelia/Log/Destination/TlogDestinationPopup.tpl new file mode 100644 index 000000000..7c67e1649 --- /dev/null +++ b/core/lib/Thelia/Log/Destination/TlogDestinationPopup.tpl @@ -0,0 +1,52 @@ + + + + + Thelia logs + + + + + +

Thelia Debug

+
#LOGTEXT
+ + diff --git a/core/lib/Thelia/Log/Destination/TlogDestinationText.php b/core/lib/Thelia/Log/Destination/TlogDestinationText.php index b03f03f65..00dca3ddd 100755 --- a/core/lib/Thelia/Log/Destination/TlogDestinationText.php +++ b/core/lib/Thelia/Log/Destination/TlogDestinationText.php @@ -34,12 +34,12 @@ class TlogDestinationText extends AbstractTlogDestination public function getTitle() { - return "Affichage direct dans la page, en texte brut"; + return "Direct text display"; } public function getDescription() { - return "Permet d'afficher les logs directement dans la page resultat, au format texte brut."; + return "Display logs in raw text format, on top of generated pages."; } public function add($texte) diff --git a/core/lib/Thelia/Log/Tlog.php b/core/lib/Thelia/Log/Tlog.php index a2396d31b..86bd8bb29 100755 --- a/core/lib/Thelia/Log/Tlog.php +++ b/core/lib/Thelia/Log/Tlog.php @@ -24,6 +24,7 @@ namespace Thelia\Log; use Thelia\Model\ConfigQuery; use Psr\Log\LoggerInterface; +use Thelia\Core\Translation\Translator; /** * @@ -69,7 +70,7 @@ class Tlog Implements LoggerInterface // default values const DEFAULT_LEVEL = self::DEBUG; const DEFAUT_DESTINATIONS = "Thelia\Log\Destination\TlogDestinationFile"; - const DEFAUT_PREFIXE = "#NUM: #NIVEAU [#FICHIER:#FONCTION()] {#LIGNE} #DATE #HEURE: "; + const DEFAUT_PREFIXE = "#INDEX: #LEVEL [#FILE:#FUNCTION()] {#LINE} #DATE #HOUR: "; const DEFAUT_FILES = "*"; const DEFAUT_IP = ""; const DEFAUT_SHOW_REDIRECT = 0; @@ -95,7 +96,7 @@ class Tlog Implements LoggerInterface private $linecount = 0; - protected static $done = false; + protected $done = false; // directories where are the Destinations Files public $dir_destinations = array(); @@ -132,8 +133,8 @@ class Tlog Implements LoggerInterface $this->setLevel(ConfigQuery::read(self::VAR_LEVEL, self::DEFAULT_LEVEL)); $this->dir_destinations = array( - __DIR__.'/Destination' - //, __DIR__.'/../client/tlog/destinations' + __DIR__.DS.'Destination', + THELIA_LOCAL_DIR.'tlog'.DS.'destinations' ); $this->setPrefix(ConfigQuery::read(self::VAR_PREFIXE, self::DEFAUT_PREFIXE)); @@ -160,10 +161,20 @@ class Tlog Implements LoggerInterface $this->destinations = array(); $classes_destinations = explode(';', $destinations); + $this->loadDestinations($this->destinations, $classes_destinations); } } + /** + * Return the directories where destinations classes should be searched. + * + * @return array of directories + */ + public function getDestinationsDirectories() { + return $this->dir_destinations; + } + /** * * change the debug level. Use Tlog constant : \Thelia\Log\Tlog::DEBUG set level to Debug @@ -489,16 +500,6 @@ class Tlog Implements LoggerInterface $this->out($this->levels[$level], $message, $context); } - - - // Mode back office - public static function SetBackOfficeMode($booleen) - { - foreach (Tlog::getInstance()->destinations as $dest) { - $dest->SetBackOfficeMode($booleen); - } - } - /** * * final end method. Write log for each destination handler @@ -508,7 +509,7 @@ class Tlog Implements LoggerInterface */ public function write(&$res) { - self::$done = true; + $this->done = true; // Muet ? On ne fait rien if ($this->level == self::MUET) return; @@ -524,7 +525,7 @@ class Tlog Implements LoggerInterface public function writeOnExit() { // Si les infos de debug n'ont pas été ecrites, le faire maintenant - if (self::$done === false) { + if ($this->done === false) { $res = ""; @@ -539,12 +540,12 @@ class Tlog Implements LoggerInterface if ($this->level != self::MUET && $this->show_redirect) { echo " -Redirection... +".Translator::getInstance()->trans('Redirecting ...')." -
Redirection vers $url +".Translator::getInstance()->trans('Redirecting to %url', array('%url' => $url))." - "; +"; return true; } else { @@ -670,7 +671,7 @@ class Tlog Implements LoggerInterface $line = $origine['line']; $prefixe = str_replace( - array("#NUM", "#NIVEAU", "#FICHIER", "#FONCTION", "#LIGNE", "#DATE", "#HEURE"), + array("#INDEX", "#LEVEL", "#FILE", "#FUNCTION", "#LINE", "#DATE", "#HOUR"), array(1+$this->linecount, $level, $file, $function, $line, date("Y-m-d"), date("G:i:s")), $this->prefixe ); diff --git a/core/lib/Thelia/Log/TlogDestinationConfig.php b/core/lib/Thelia/Log/TlogDestinationConfig.php index 1bcbd9960..01c8fbe4f 100755 --- a/core/lib/Thelia/Log/TlogDestinationConfig.php +++ b/core/lib/Thelia/Log/TlogDestinationConfig.php @@ -22,7 +22,6 @@ /*************************************************************************************/ namespace Thelia\Log; - use Thelia\Model\Config; use Thelia\Model\ConfigQuery; @@ -32,12 +31,12 @@ class TlogDestinationConfig const TYPE_TEXTAREA = 1; const TYPE_TEXTFIELD = 2; - public $name; - public $title; - public $label; - public $default; - public $type; - public $value; + protected $name; + protected $title; + protected $label; + protected $default; + protected $type; + protected $value; public function __construct($name, $title, $label, $default, $type) { @@ -45,22 +44,67 @@ class TlogDestinationConfig $this->title = $title; $this->label = $label; $this->default = $default; - $this->type = $type; - - $this->load(); + $this->type= $type; + $this->value = ConfigQuery::read($this->name, $this->default); } - public function load() + public function getName() { - if (null === $config = ConfigQuery::create()->findOneByName($this->name)) { - $config = new Config(); - $config->setName($this->name); - $config->setValue($this->default); - $config->setHidden(1); - $config->setSecured(1); - $config->save(); - } + return $this->name; + } - $this->value = $config->getValue(); + public function setName($name) + { + $this->name = $name; + } + + public function getTitle() + { + return $this->title; + } + + public function setTitle($title) + { + $this->title = $title; + } + + public function getLabel() + { + return $this->label; + } + + public function setLabel($label) + { + $this->label = $label; + } + + public function getDefault() + { + return $this->default; + } + + public function setDefault($default) + { + $this->default = $default; + } + + public function getType() + { + return $this->type; + } + + public function setType($type) + { + $this->type = $type; + } + + public function getValue() + { + return $this->value; + } + + public function setValue($value) + { + $this->value = $value; } } diff --git a/core/lib/Thelia/Model/ConfigQuery.php b/core/lib/Thelia/Model/ConfigQuery.php index 11bbc51d6..71ff253ea 100755 --- a/core/lib/Thelia/Model/ConfigQuery.php +++ b/core/lib/Thelia/Model/ConfigQuery.php @@ -32,7 +32,7 @@ class ConfigQuery extends BaseConfigQuery { return self::$cache[$search]; } - public static function write($configName, $value, $secured, $hidden) + public static function write($configName, $value, $secured = null, $hidden = null) { $config = self::create()->findOneByName($configName); @@ -41,8 +41,9 @@ class ConfigQuery extends BaseConfigQuery { $config->setName($configName); } - $config->setSecured($secured ? 1 : 0); - $config->setHidden($hidden ? 1 : 0); + if ($secured !== null) $config->setSecured($secured ? 1 : 0); + if ($hidden !== null) $config->setHidden($hidden ? 1 : 0); + $config->setValue($value); $config->save(); diff --git a/core/lib/Thelia/Tools/Redirect.php b/core/lib/Thelia/Tools/Redirect.php index ed7932080..23fd9258b 100755 --- a/core/lib/Thelia/Tools/Redirect.php +++ b/core/lib/Thelia/Tools/Redirect.php @@ -24,14 +24,17 @@ namespace Thelia\Tools; use Symfony\Component\HttpFoundation\RedirectResponse; +use Thelia\Log\Tlog; class Redirect { public static function exec($url, $status = 302) { - $response = new RedirectResponse($url, $status); + if (false == Tlog::getInstance()->showRedirect($url)) { + $response = new RedirectResponse($url, $status); - $response->send(); + $response->send(); + } exit; } diff --git a/core/lib/Thelia/Tools/Rest/ResponseRest.php b/core/lib/Thelia/Tools/Rest/ResponseRest.php index 0c9186436..9df26e0d8 100644 --- a/core/lib/Thelia/Tools/Rest/ResponseRest.php +++ b/core/lib/Thelia/Tools/Rest/ResponseRest.php @@ -2,7 +2,7 @@ namespace Thelia\Tools\Rest; -use Symfony\Component\HttpFoundation\Response; +use Thelia\Core\HttpFoundation\Response; use Symfony\Component\Serializer\Serializer; use Symfony\Component\Serializer\Encoder\XmlEncoder; diff --git a/local/config/schema.xml b/local/config/schema.xml index cc9c4c396..70df6710e 100755 --- a/local/config/schema.xml +++ b/local/config/schema.xml @@ -1,1264 +1,1264 @@ - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - -
- - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - -
- - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - -
- - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - -
- - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
- - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
- - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - -
- - - - - - - - - - -
-
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + +
+ + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
diff --git a/templates/admin/default/configuration.html b/templates/admin/default/configuration.html index d0e3c880c..9f0cc4160 100644 --- a/templates/admin/default/configuration.html +++ b/templates/admin/default/configuration.html @@ -167,8 +167,8 @@ {loop type="auth" name="pcc8" role="ADMIN" resource="admin.configuration.system-logs" access="VIEW"}
{intl l='System logs'}{intl l='System logs'}
+
{* {loop type="auth" name="can_change" role="ADMIN" resource="admin.modules" access="VIEW"} diff --git a/templates/admin/default/system-logs.html b/templates/admin/default/system-logs.html new file mode 100644 index 000000000..92e59c730 --- /dev/null +++ b/templates/admin/default/system-logs.html @@ -0,0 +1,213 @@ +{extends file="admin-layout.tpl"} + +{block name="page-title"}{intl l='System Logs'}{/block} + +{block name="check-resource"}admin.configuration.variable{/block} +{block name="check-access"}update{/block} + +{block name="main-content"} +
+ +
+ + + +
+
+
+ +
+ {intl l="System Logs configuration"} +
+
+ +
+
+
+ {form name='thelia.system-logs.configuration'} + + + {form_hidden_fields form=$form} + + {include + file = "includes/inner-form-toolbar.html" + hide_flags = true + + page_url = "{url path='/admin/configuration/system-logs'}" + close_url = "{url path='/admin/configuration'}" + } + +
+
+

{intl l='General configuration'}

+ + {if $form_error} +
{$form_error_message}
+ {/if} + +
+ + {form_field form=$form field="level"} +
+ + + + + + + {intl l='Messages which have a level greater or equal to the selected level will be added to the log destinations. '} + +
+ {/form_field} + + {form_field form=$form field='format'} +
+ + +
+ +
+ + + {intl l='Log lines header format. You may use the following variables: '} +
    +
  • #INDEX : {intl l='Sequential number of log line'}
  • +
  • #LEVEL : {intl l='Message level'}
  • +
  • #FILE : {intl l='Originating file name'}
  • +
  • #FUNCTION : {intl l='Originating function name '}
  • +
  • #LINE : {intl l='Originating file line number '}
  • +
  • #DATE : {intl l='date in yyyy-mm-dd format'}
  • +
  • #HOUR : {intl l='hour in hh:mm:ss format'}
  • +
+
+
+ {/form_field} + + {form_field form=$form field='show_redirections'} +
+ + +
+ + +
+ + {intl l='If yes, redirections through Redirect::exec() will be displayed as links'} +
+ {/form_field} + + {form_field form=$form field='files'} +
+ + +
+ +
+ + {intl l='Enter one or more file names without path separated by ";". Use "!" before a file name to exclude it. Use "*" to activate logs for all files.'} +
+ {/form_field} + + {form_field form=$form field='ip_addresses'} +
+ + +
+ +
+ + {intl l='Enter one or more IP V4 addresses separated by ";". Leave empty to display logs for all IP addresses'} + {intl l='Your current IP address is %ip' ip=$ip_address} +
+ {/form_field} + +
+ +
+ +
+

{intl l='Destinations'}

+ +
+ {intl l='The destinations processes logs to display, store or send them. You can select and configure zero, one or more destinations below.'} +
+ +
+ {foreach $destinations as $classname => $destination} + {$active = in_array(get_class($destination), $active_destinations)} +
+ + +

{$destination->getTitle()}

+

{$destination->getDescription()}

+ +
+
+ +
+
+ + {if count($destination->getConfigs()) > 0} +
+ {foreach $destination->getConfigs() as $config} +
+ + {if $config->getType() == 2} + + {else if $config->getType() == 1} + + {/if} + {$config->getLabel()} +
+ {/foreach} +
+ {/if} + +
+ {/foreach} +
+ +
+
+ + {/form} +
+
+
+
+
+
+
+{/block} + +{block name="javascript-initialization"} + +{/block} \ No newline at end of file diff --git a/web/index_dev.php b/web/index_dev.php index 3a88088fc..6b06585cd 100755 --- a/web/index_dev.php +++ b/web/index_dev.php @@ -21,9 +21,8 @@ /* */ /**********************************************************************************/ - -use Symfony\Component\HttpFoundation\Response; use Thelia\Core\Thelia; +use Thelia\Core\HttpFoundation\Response; use Thelia\Core\HttpFoundation\Request; //use Symfony\Component\DependencyInjection; From 069b047801c967a6a25f8c105be6f78ae1af6ee7 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Fri, 1 Nov 2013 16:45:25 +0100 Subject: [PATCH 57/59] Added size limitation to the Thelia log file --- .../Thelia/Log/AbstractTlogDestination.php | 4 +- .../Log/Destination/TlogDestinationFile.php | 47 +++++++++++++++---- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/core/lib/Thelia/Log/AbstractTlogDestination.php b/core/lib/Thelia/Log/AbstractTlogDestination.php index 0d3cde9e1..5dcb76f71 100755 --- a/core/lib/Thelia/Log/AbstractTlogDestination.php +++ b/core/lib/Thelia/Log/AbstractTlogDestination.php @@ -60,7 +60,7 @@ abstract class AbstractTlogDestination } //Récupère la valeur affectée à une configuration de la destination - public function getConfig($name) + public function getConfig($name, $default = false) { foreach ($this->_configs as $config) { if ($config->getName() == $name) { @@ -68,7 +68,7 @@ abstract class AbstractTlogDestination } } - return false; + return $default; } public function getConfigs() diff --git a/core/lib/Thelia/Log/Destination/TlogDestinationFile.php b/core/lib/Thelia/Log/Destination/TlogDestinationFile.php index a045196fe..5d9089ebe 100755 --- a/core/lib/Thelia/Log/Destination/TlogDestinationFile.php +++ b/core/lib/Thelia/Log/Destination/TlogDestinationFile.php @@ -37,33 +37,53 @@ class TlogDestinationFile extends AbstractTlogDestination const VAR_MODE = "tlog_destinationfile_mode"; const VALEUR_MODE_DEFAULT = "A"; + const VAR_MAX_FILE_SIZE_KB = "tlog_destinationfile_max_file_size"; + const MAX_FILE_SIZE_KB_DEFAULT = 1024; // 1 Mb + protected $path_defaut = false; protected $fh = false; public function __construct() { - $this->path_defaut = THELIA_ROOT . "log" . DS . self::TLOG_DEFAULT_NAME; - parent::__construct(); + $this->path_defaut = THELIA_ROOT . "log" . DS . self::TLOG_DEFAULT_NAME; + parent::__construct(); } public function configure() { $file_path = $this->getConfig(self::VAR_PATH_FILE); - $mode = strtolower($this->getConfig(self::VAR_MODE)) == 'a' ? 'a' : 'w'; + $mode = strtolower($this->getConfig(self::VAR_MODE, self::VALEUR_MODE_DEFAULT)) == 'a' ? 'a' : 'w'; if (! empty($file_path)) { if (! is_file($file_path)) { - $dir = dirname($file_path); - if (! is_dir($dir)) { - mkdir($dir, 0777, true); - } + $dir = dirname($file_path); + if (! is_dir($dir)) { + mkdir($dir, 0777, true); + } - touch($file_path); - chmod($file_path, 0777); + touch($file_path); + chmod($file_path, 0666); } if ($this->fh) @fclose($this->fh); + if (filesize($file_path) > 1024 * $this->getConfig(self::VAR_MAX_FILE_SIZE_KB, self::MAX_FILE_SIZE_KB_DEFAULT)) { + + $idx = 1; + + do { + $file_path_bk = "$file_path.$idx"; + + $idx++; + + } while (file_exists($file_path_bk)); + + rename($file_path, $file_path_bk); + + touch($file_path); + chmod($file_path, 0666); + } + $this->fh = fopen($file_path, $mode); } } @@ -94,6 +114,13 @@ class TlogDestinationFile extends AbstractTlogDestination 'Enter E to empty this file for each request, or A to always append logs. Consider resetting the file from time to time', self::VALEUR_MODE_DEFAULT, TlogDestinationConfig::TYPE_TEXTFIELD + ), + new TlogDestinationConfig( + self::VAR_MAX_FILE_SIZE_KB, + 'Maximum log file size, in Kb', + 'When this size if exeeded, a backup copy of the file is made, and a new log file is opened. As the file size check is performed only at the beginning of a request, the file size may be bigger thant this limit. Note: 1 Mb = 1024 Kb', + self::MAX_FILE_SIZE_KB_DEFAULT, + TlogDestinationConfig::TYPE_TEXTFIELD ) ); } @@ -111,4 +138,4 @@ class TlogDestinationFile extends AbstractTlogDestination $this->fh = false; } -} +} \ No newline at end of file From f3cba323c64b51889e82657136d69564639417a2 Mon Sep 17 00:00:00 2001 From: Franck Allimant Date: Sat, 2 Nov 2013 19:18:19 +0100 Subject: [PATCH 58/59] Changed 'template' loop into 'product-template' loop --- core/lib/Thelia/Config/Resources/loop.xml | 2 +- .../Core/Template/Loop/ProductTemplate.php | 108 ++++++++++++++++++ .../default/ajax/product-attributes-tab.html | 2 +- templates/admin/default/template-edit.html | 2 +- templates/admin/default/templates.html | 2 +- 5 files changed, 112 insertions(+), 4 deletions(-) create mode 100644 core/lib/Thelia/Core/Template/Loop/ProductTemplate.php diff --git a/core/lib/Thelia/Config/Resources/loop.xml b/core/lib/Thelia/Config/Resources/loop.xml index fe2c333d4..bf5c9f7f9 100644 --- a/core/lib/Thelia/Config/Resources/loop.xml +++ b/core/lib/Thelia/Config/Resources/loop.xml @@ -48,7 +48,7 @@ - + diff --git a/core/lib/Thelia/Core/Template/Loop/ProductTemplate.php b/core/lib/Thelia/Core/Template/Loop/ProductTemplate.php new file mode 100644 index 000000000..175ff0f91 --- /dev/null +++ b/core/lib/Thelia/Core/Template/Loop/ProductTemplate.php @@ -0,0 +1,108 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Template\Loop; + +use Propel\Runtime\ActiveQuery\Criteria; +use Thelia\Core\Template\Element\BaseI18nLoop; +use Thelia\Core\Template\Element\LoopResult; +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; + +/** + * + * Template loop + * + * + * Class Template + * @package Thelia\Core\Template\Loop + * @author Etienne Roudeix + */ +class ProductTemplate extends BaseI18nLoop +{ + public $timestampable = true; + + /** + * @return ArgumentCollection + */ + protected function getArgDefinitions() + { + return new ArgumentCollection( + Argument::createIntListTypeArgument('id'), + Argument::createIntListTypeArgument('exclude') + ); + } + + /** + * @param $pagination + * + * @return \Thelia\Core\Template\Element\LoopResult + */ + public function exec(&$pagination) + { + $search = TemplateQuery::create(); + + $backendContext = $this->getBackend_context(); + + $lang = $this->getLang(); + + /* 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); + + foreach ($templates as $template) { + $loopResultRow = new LoopResultRow($loopResult, $template, $this->versionable, $this->timestampable, $this->countable); + + $loopResultRow + ->set("ID", $template->getId()) + ->set("IS_TRANSLATED" , $template->getVirtualColumn('IS_TRANSLATED')) + ->set("LOCALE" , $locale) + ->set("NAME" , $template->getVirtualColumn('i18n_NAME')) + ; + + $loopResult->addRow($loopResultRow); + } + + return $loopResult; + } +} diff --git a/templates/admin/default/ajax/product-attributes-tab.html b/templates/admin/default/ajax/product-attributes-tab.html index 2a62da2e3..f9913d413 100644 --- a/templates/admin/default/ajax/product-attributes-tab.html +++ b/templates/admin/default/ajax/product-attributes-tab.html @@ -25,7 +25,7 @@
diff --git a/templates/admin/default/template-edit.html b/templates/admin/default/template-edit.html index f9e1fd139..623854060 100644 --- a/templates/admin/default/template-edit.html +++ b/templates/admin/default/template-edit.html @@ -10,7 +10,7 @@
- {loop name="template_edit" type="template" id="$template_id" backend_context="1" lang="$edit_language_id"} + {loop name="template_edit" type="product-template" id="$template_id" backend_context="1" lang="$edit_language_id"}
{$ID}