Completed the backoffice variable management

This commit is contained in:
franck
2013-09-02 00:17:27 +02:00
parent 6d5d0f6606
commit 5670855dd6
51 changed files with 1144 additions and 288 deletions

View File

@@ -49,34 +49,4 @@ class BaseAction
{ {
return $this->container->get('event_dispatcher'); return $this->container->get('event_dispatcher');
} }
/**
* Check current user authorisations.
*
* @param mixed $roles a single role or an array of roles.
* @param mixed $permissions a single permission or an array of permissions.
*
* @throws AuthenticationException if permissions are not granted to the current user.
*/
protected function checkAuth($roles, $permissions) {
if (! $this->getSecurityContext()->isGranted(
is_array($roles) ? $roles : array($roles),
is_array($permissions) ? $permissions : array($permissions)) ) {
Tlog::getInstance()->addAlert("Authorization roles:", $roles, " permissions:", $permissions, " refused.");
throw new AuthorizationException("Sorry, you're not allowed to perform this action");
}
}
/**
* Return the security context
*
* @return Thelia\Core\Security\SecurityContext
*/
protected function getSecurityContext()
{
return $this->container->get('thelia.securityContext');
}
} }

View File

@@ -42,8 +42,6 @@ class Category extends BaseAction implements EventSubscriberInterface
{ {
public function create(CategoryCreateEvent $event) public function create(CategoryCreateEvent $event)
{ {
$this->checkAuth("ADMIN", "admin.category.create");
$category = new CategoryModel(); $category = new CategoryModel();
$category $category
@@ -57,9 +55,6 @@ class Category extends BaseAction implements EventSubscriberInterface
public function modify(CategoryChangeEvent $event) public function modify(CategoryChangeEvent $event)
{ {
$this->checkAuth("ADMIN", "admin.category.change");
// TODO !!
} }
/** /**
@@ -69,8 +64,6 @@ class Category extends BaseAction implements EventSubscriberInterface
*/ */
public function delete(CategoryDeleteEvent $event) public function delete(CategoryDeleteEvent $event)
{ {
$this->checkAuth("ADMIN", "admin.category.delete");
$category = CategoryQuery::create()->findPk($event->getCategoryId()); $category = CategoryQuery::create()->findPk($event->getCategoryId());
if ($category !== null) { if ($category !== null) {
@@ -86,8 +79,6 @@ class Category extends BaseAction implements EventSubscriberInterface
*/ */
public function toggleVisibility(CategoryToggleVisibilityEvent $event) public function toggleVisibility(CategoryToggleVisibilityEvent $event)
{ {
$this->checkAuth("ADMIN", "admin.category.edit");
$category = CategoryQuery::create()->findPk($event->getCategoryId()); $category = CategoryQuery::create()->findPk($event->getCategoryId());
if ($category !== null) { if ($category !== null) {
@@ -107,8 +98,6 @@ class Category extends BaseAction implements EventSubscriberInterface
*/ */
public function changePosition(CategoryChangePositionEvent $event) public function changePosition(CategoryChangePositionEvent $event)
{ {
$this->checkAuth("ADMIN", "admin.category.edit");
if ($event->getMode() == CategoryChangePositionEvent::POSITION_ABSOLUTE) if ($event->getMode() == CategoryChangePositionEvent::POSITION_ABSOLUTE)
return $this->changeAbsolutePosition($event); return $this->changeAbsolutePosition($event);
else else
@@ -177,8 +166,6 @@ class Category extends BaseAction implements EventSubscriberInterface
*/ */
protected function changeAbsolutePosition(CategoryChangePositionEvent $event) protected function changeAbsolutePosition(CategoryChangePositionEvent $event)
{ {
$this->checkAuth("ADMIN", "admin.category.edit");
$category = CategoryQuery::create()->findPk($event->getCategoryId()); $category = CategoryQuery::create()->findPk($event->getCategoryId());
if ($category !== null) { if ($category !== null) {

View File

@@ -44,26 +44,20 @@ class Config extends BaseAction implements EventSubscriberInterface
*/ */
public function create(ConfigCreateEvent $event) public function create(ConfigCreateEvent $event)
{ {
$this->checkAuth("ADMIN", "admin.configuration.variables.create");
$config = new ConfigModel(); $config = new ConfigModel();
$config $config
->setDispatcher($this->getDispatcher()) ->setDispatcher($this->getDispatcher())
->setName($event->getName()) ->setName($event->getEventName())
->setValue($event->getValue()) ->setValue($event->getValue())
->setHidden($evetn->getHidden())
->setSecured($event->getSecured())
->setLocale($event->getLocale()) ->setLocale($event->getLocale())
->setTitle($event->getTitle()) ->setTitle($event->getTitle())
->setDescription($event->getDescription())
->setChapo($event->getChapo())
->setPostscriptum($event->getPostscriptum())
->save() ->save()
; ;
$event->setConfig($config);
} }
/** /**
@@ -73,17 +67,20 @@ class Config extends BaseAction implements EventSubscriberInterface
*/ */
public function setValue(ConfigChangeEvent $event) public function setValue(ConfigChangeEvent $event)
{ {
$this->checkAuth("ADMIN", "admin.configuration.variables.change");
$search = ConfigQuery::create(); $search = ConfigQuery::create();
if (null !== $config = $search->findOneById($event->getConfigId())) { if (null !== $config = $search->findOneById($event->getConfigId())
&&
$event->getValue() != $config->getValue()) {
$config $config
->setDispatcher($this->getDispatcher()) ->setDispatcher($this->getDispatcher())
->setValue($event->getValue()) ->setValue($event->getValue())
->save() ->save()
; ;
$event->setConfig($config);
} }
} }
@@ -94,8 +91,6 @@ class Config extends BaseAction implements EventSubscriberInterface
*/ */
public function modify(ConfigChangeEvent $event) public function modify(ConfigChangeEvent $event)
{ {
$this->checkAuth("ADMIN", "admin.configuration.variables.change");
$search = ConfigQuery::create(); $search = ConfigQuery::create();
if (null !== $config = ConfigQuery::create()->findOneById($event->getConfigId())) { if (null !== $config = ConfigQuery::create()->findOneById($event->getConfigId())) {
@@ -103,9 +98,9 @@ class Config extends BaseAction implements EventSubscriberInterface
$config $config
->setDispatcher($this->getDispatcher()) ->setDispatcher($this->getDispatcher())
->setName($event->getName()) ->setName($event->getEventName())
->setValue($event->getValue()) ->setValue($event->getValue())
->setHidden($evetn->getHidden()) ->setHidden($event->getHidden())
->setSecured($event->getSecured()) ->setSecured($event->getSecured())
->setLocale($event->getLocale()) ->setLocale($event->getLocale())
@@ -115,6 +110,8 @@ class Config extends BaseAction implements EventSubscriberInterface
->setPostscriptum($event->getPostscriptum()) ->setPostscriptum($event->getPostscriptum())
->save(); ->save();
$event->setConfig($config);
} }
} }
@@ -125,22 +122,22 @@ class Config extends BaseAction implements EventSubscriberInterface
*/ */
public function delete(ConfigDeleteEvent $event) public function delete(ConfigDeleteEvent $event)
{ {
$this->checkAuth("ADMIN", "admin.configuration.variables.delete");
if (null !== ($config = ConfigQuery::create()->findOneById($event->getConfigId()))) { if (null !== ($config = ConfigQuery::create()->findOneById($event->getConfigId()))) {
if (! $config->getSecured()) { if (! $config->getSecured()) {
$config->setDispatcher($this->getDispatcher());
$config->delete(); $config
->setDispatcher($this->getDispatcher())
->delete()
;
$event->setConfig($config);
} }
} }
} }
/** /**
* Returns an array of event names this subscriber listens to. * {@inheritDoc}
*
* @return array The event names to listen to
*
* @api
*/ */
public static function getSubscribedEvents() public static function getSubscribedEvents()
{ {

View File

@@ -109,6 +109,16 @@ class Customer extends BaseAction implements EventSubscriberInterface
// TODO // TODO
} }
/**
* Return the security context
*
* @return Thelia\Core\Security\SecurityContext
*/
protected function getSecurityContext()
{
return $this->container->get('thelia.securityContext');
}
/** /**
* Returns an array of event names this subscriber wants to listen to. * Returns an array of event names this subscriber wants to listen to.
* *

View File

@@ -46,6 +46,9 @@
<form name="thelia.admin.category.deletion" class="Thelia\Form\CategoryDeletionForm"/> <form name="thelia.admin.category.deletion" class="Thelia\Form\CategoryDeletionForm"/>
<form name="thelia.cart.add" class="Thelia\Form\CartAdd"/> <form name="thelia.cart.add" class="Thelia\Form\CartAdd"/>
<form name="thelia.admin.variable.creation" class="Thelia\Form\VariableCreationForm"/>
<form name="thelia.admin.variable.modification" class="Thelia\Form\VariableModificationForm"/>
</forms> </forms>

View File

@@ -41,6 +41,10 @@
<default key="_controller">Thelia\Controller\Admin\VariablesController::defaultAction</default> <default key="_controller">Thelia\Controller\Admin\VariablesController::defaultAction</default>
</route> </route>
<route id="admin.configuration.variables.change-values" path="/admin/configuration/variables/change-values">
<default key="_controller">Thelia\Controller\Admin\VariablesController::changeValuesAction</default>
</route>
<route id="admin.configuration.variables.create" path="/admin/configuration/variables/create"> <route id="admin.configuration.variables.create" path="/admin/configuration/variables/create">
<default key="_controller">Thelia\Controller\Admin\VariablesController::createAction</default> <default key="_controller">Thelia\Controller\Admin\VariablesController::createAction</default>
</route> </route>
@@ -49,6 +53,10 @@
<default key="_controller">Thelia\Controller\Admin\VariablesController::changeAction</default> <default key="_controller">Thelia\Controller\Admin\VariablesController::changeAction</default>
</route> </route>
<route id="admin.configuration.variables.save-change" path="/admin/configuration/variables/save-change">
<default key="_controller">Thelia\Controller\Admin\VariablesController::saveChangeAction</default>
</route>
<route id="admin.configuration.variables.delete" path="/admin/configuration/variables/delete"> <route id="admin.configuration.variables.delete" path="/admin/configuration/variables/delete">
<default key="_controller">Thelia\Controller\Admin\VariablesController::deleteAction</default> <default key="_controller">Thelia\Controller\Admin\VariablesController::deleteAction</default>
</route> </route>

View File

@@ -29,10 +29,4 @@ class AdminController extends BaseAdminController
{ {
return $this->render("home"); return $this->render("home");
} }
public function processAction()
{
echo "not yet coded !";
exit();
}
} }

View File

@@ -32,6 +32,8 @@ use Thelia\Tools\URL;
use Thelia\Tools\Redirect; use Thelia\Tools\Redirect;
use Thelia\Core\Security\SecurityContext; use Thelia\Core\Security\SecurityContext;
use Thelia\Model\AdminLog; use Thelia\Model\AdminLog;
use Thelia\Model\Lang;
use Thelia\Model\LangQuery;
class BaseAdminController extends BaseController class BaseAdminController extends BaseController
{ {
@@ -46,6 +48,12 @@ class BaseAdminController extends BaseController
AdminLog::append($message, $this->getRequest(), $this->getSecurityContext()->getAdminUser()); AdminLog::append($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
*/
public function processTemplateAction($template) public function processTemplateAction($template)
{ {
try { try {
@@ -89,19 +97,31 @@ class BaseAdminController extends BaseController
/** /**
* Check current admin user authorisations. An ADMIN role is assumed. * Check current admin user authorisations. An ADMIN role is assumed.
* *
* @param unknown $permissions a single permission or an array of permissions. * @param mixed $permissions a single permission or an array of permissions.
*
* @return mixed null if authorization is granted, or a Response object which contains the error page otherwise
* *
* @throws AuthenticationException if permissions are not granted ti the current user.
*/ */
protected function checkAuth($permissions) protected function checkAuth($permissions)
{ {
if (! $this->getSecurityContext()->isGranted(array("ADMIN"), is_array($permissions) ? $permissions : array($permissions))) { $permArr = is_array($permissions) ? $permissions : array($permissions);
throw new AuthorizationException("Sorry, you're not allowed to perform this action");
} if ($this->getSecurityContext()->isGranted(array("ADMIN"), $permArr)) {
// Okay !
return null;
}
// Log the problem
$this->adminLogAppend("User is not granted for permissions %s", implode(", ", $permArr));
// Generate the proper response
$response = new Response();
return $response->setContent($this->errorPage("Sorry, you're not allowed to perform this action"));
} }
/** /**
* @return a ParserInterfac instance parser * @return a ParserInterface instance parser
*/ */
protected function getParser() protected function getParser()
{ {
@@ -130,6 +150,23 @@ class BaseAdminController extends BaseController
return $this->container->get('http_kernel')->handle($subRequest, HttpKernelInterface::SUB_REQUEST); return $this->container->get('http_kernel')->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
} }
/**
* Get the current edition lang ID, checking if a change was requested in the current request
*/
protected function getCurrentEditionLangId() {
return $this->getRequest()->get(
'edition_language',
$this->getSession()->getAdminEditionLangId()
);
}
/**
* A simple helper to get the current edition locale, from the session edition language ID
*/
protected function getCurrentEditionLocale() {
return LangQuery::create()->findOneById($this->getCurrentEditionLangId())->getLocale();
}
/** /**
* Render the given template, and returns the result as an Http Response. * Render the given template, and returns the result as an Http Response.
* *
@@ -153,26 +190,40 @@ class BaseAdminController extends BaseController
*/ */
protected function renderRaw($templateName, $args = array()) protected function renderRaw($templateName, $args = array())
{ {
// Add the template standard extension // Add the template standard extension
$templateName .= '.html'; $templateName .= '.html';
$session = $this->getSession(); $session = $this->getSession();
// Find the current edit language ID
$edition_language = $this->getCurrentEditionLangId();
// Prepare common template variables
$args = array_merge($args, array( $args = array_merge($args, array(
'locale' => $session->getLocale(), 'locale' => $session->getLocale(),
'lang' => $session->getLang() 'lang' => $session->getLang(),
'edition_language' => $edition_language,
'current_url' => htmlspecialchars($this->getRequest()->getUri())
)); ));
// Update the current edition language in session
$this->getSession()->setAdminEditionLangId($edition_language);
// Render the template.
try { try {
$data = $this->getParser()->render($templateName, $args); $data = $this->getParser()->render($templateName, $args);
return $data; return $data;
} catch (AuthenticationException $ex) { }
catch (AuthenticationException $ex) {
// User is not authenticated, and templates requires authentication -> redirect to login page // User is not authenticated, and templates requires authentication -> redirect to login page
// We user login_tpl as a path, not a template. // We user login_tpl as a path, not a template.
Redirect::exec(URL::absoluteUrl($ex->getLoginTemplate())); Redirect::exec(URL::absoluteUrl($ex->getLoginTemplate()));
} }
catch (AuthorizationException $ex) {
// User is not allowed to perform the required action. Return the error page instead of the requested page.
return $this->errorPage("Sorry, you are not allowed to perform this action.");
}
} }
} }

View File

@@ -66,7 +66,7 @@ class CategoryController extends BaseAdminController
} }
catch (FormValidationException $e) { catch (FormValidationException $e) {
$categoryCreationForm->setErrorMessage($e->getMessage()); $categoryCreationForm->setErrorMessage($e->getMessage());
$this->getParserContext()->setErrorForm($categoryCreationForm); $this->getParserContext()->addForm($categoryCreationForm);
} }
catch (Exception $e) { catch (Exception $e) {
Tlog::getInstance()->error(sprintf("Failed to create category: %s", $e->getMessage())); Tlog::getInstance()->error(sprintf("Failed to create category: %s", $e->getMessage()));
@@ -79,7 +79,7 @@ class CategoryController extends BaseAdminController
protected function editCategory($args) protected function editCategory($args)
{ {
$this->checkAuth("ADMIN", "admin.category.edit"); if (null !== $response = $this->checkAuth("admin.category.edit")) return $response;
return $this->render('edit_category', $args); return $this->render('edit_category', $args);
} }
@@ -107,7 +107,7 @@ class CategoryController extends BaseAdminController
} }
catch (FormValidationException $e) { catch (FormValidationException $e) {
$categoryDeletionForm->setErrorMessage($e->getMessage()); $categoryDeletionForm->setErrorMessage($e->getMessage());
$this->getParserContext()->setErrorForm($categoryDeletionForm); $this->getParserContext()->addForm($categoryDeletionForm);
} }
catch (Exception $e) { catch (Exception $e) {
Tlog::getInstance()->error(sprintf("Failed to delete category: %s", $e->getMessage())); Tlog::getInstance()->error(sprintf("Failed to delete category: %s", $e->getMessage()));
@@ -120,7 +120,7 @@ class CategoryController extends BaseAdminController
protected function browseCategory($args) protected function browseCategory($args)
{ {
$this->checkAuth("AMIN", "admin.catalog.view"); if (null !== $response = $this->checkAuth("admin.catalog.view")) return $response;
return $this->render('categories', $args); return $this->render('categories', $args);
} }
@@ -203,9 +203,6 @@ class CategoryController extends BaseAdminController
'current_category_id' => $id, 'current_category_id' => $id,
'category_order' => $category_order, 'category_order' => $category_order,
'edition_language' => $edition_language, 'edition_language' => $edition_language,
'date_format' => Lang::getDefaultLanguage()->getDateFormat(),
'time_format' => Lang::getDefaultLanguage()->getTimeFormat(),
'datetime_format' => Lang::getDefaultLanguage()->getDateTimeFormat(),
); );
// Store the current sort order in session // Store the current sort order in session

View File

@@ -96,7 +96,7 @@ class SessionController extends BaseAdminController
$adminLoginForm->setErrorMessage($message); $adminLoginForm->setErrorMessage($message);
// Store the form name in session (see Form Smarty plugin to find usage of this parameter) // Store the form name in session (see Form Smarty plugin to find usage of this parameter)
$this->getParserContext()->setErrorForm($adminLoginForm); $this->getParserContext()->addForm($adminLoginForm);
// Display the login form again // Display the login form again
return $this->render("login"); return $this->render("login");

View File

@@ -26,23 +26,272 @@ namespace Thelia\Controller\Admin;
use Thelia\Core\Event\ConfigDeleteEvent; use Thelia\Core\Event\ConfigDeleteEvent;
use Thelia\Core\Event\TheliaEvents; use Thelia\Core\Event\TheliaEvents;
use Thelia\Tools\URL; use Thelia\Tools\URL;
use Thelia\Core\Event\ConfigChangeEvent;
use Thelia\Form\VariableCreationForm;
use Thelia\Core\Event\ConfigCreateEvent;
use Thelia\Log\Tlog;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Core\Security\Exception\AuthorizationException;
use Thelia\Form\VariableModificationForm;
use Thelia\Model\ConfigQuery;
/**
* Manages Thelmia system variables, aka Config objects.
*
* @author Franck Allimant <franck@cqfdev.fr>
*/
class VariablesController extends BaseAdminController class VariablesController extends BaseAdminController
{ {
/**
* The default action is displaying the variables list.
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
public function defaultAction() { public function defaultAction() {
if (null !== $response = $this->checkAuth("admin.configuration.variables.view")) return $response;
return $this->render('variables'); return $this->render('variables');
} }
/**
* Create a new config object
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
public function createAction() { public function createAction() {
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.configuration.variables.create")) return $response;
$message = false;
// Create the Creation Form
$creationForm = new VariableCreationForm($this->getRequest());
try {
// Validate the form, create the ConfigCreation event and dispatch it.
$form = $this->validateForm($creationForm, "POST");
$data = $form->getData();
$createEvent = new ConfigCreateEvent();
$createEvent
->setEventName($data['name'])
->setValue($data['value'])
->setLocale($data["locale"])
->setTitle($data['title'])
;
$this->dispatch(TheliaEvents::CONFIG_CREATE, $createEvent);
$createdObject = $createEvent->getConfig();
// Log config creation
$this->adminLogAppend(sprintf("Variable %s (ID %s) created", $createdObject->getName(), $createdObject->getId()));
// Substitute _ID_ in the URL with the ID of the created object
$successUrl = str_replace('_ID_', $createdObject->getId(), $creationForm->getSuccessUrl());
// Redirect to the success URL
$this->redirect($successUrl);
}
catch (FormValidationException $ex) {
// Form cannot be validated
$message = sprintf("Please check your input: %s", $ex->getMessage());
}
catch (\Exception $ex) {
// Any other error
$message = sprintf("Sorry, an error occured: %s", $ex->getMessage());
}
if ($message !== false) {
// An error has been detected: log it
Tlog::getInstance()->error(sprintf("Error during variable creation process : %s. Exception was %s", $message, $ex->getMessage()));
// Mark the form as errored
$creationForm->setErrorMessage($message);
// Pass it to the parser, along with the error message
$this->getParserContext()
->addForm($creationForm)
->setGeneralError($message)
;
}
// At this point, the form has error, and should be redisplayed.
return $this->render('variables');
} }
/**
* Load a config object for modification, and display the edit template.
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
public function changeAction() {
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.configuration.variables.change")) return $response;
// Load the config object
$config = ConfigQuery::create()
->joinWithI18n($this->getCurrentEditionLocale())
->findOneById($this->getRequest()->get('variable_id'));
if ($config != null) {
// Prepare the data that will hydrate the form
$data = array(
'id' => $config->getId(),
'name' => $config->getName(),
'value' => $config->getValue(),
'hidden' => $config->getHidden(),
'secured' => $config->getSecured(),
'locale' => $config->getLocale(),
'title' => $config->getTitle(),
'chapo' => $config->getChapo(),
'description' => $config->getDescription(),
'postscriptum' => $config->getPostscriptum()
);
// Setup the object form
$changeForm = new VariableModificationForm($this->getRequest(), "form", $data);
// Pass it to the parser
$this->getParserContext()->addForm($changeForm);
}
// Render the edition template.
return $this->render('variable-edit', array('variable_id' => $this->getRequest()->get('variable_id')));
}
/**
* Save changes on a modified config object, and either go back to the variable list, or stay on the edition page.
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
public function saveChangeAction() {
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.configuration.variables.change")) return $response;
$message = false;
// Create the form from the request
$changeForm = new VariableModificationForm($this->getRequest());
// Get the variable ID
$variable_id = $this->getRequest()->get('variable_id');
try {
// Check the form against constraints violations
$form = $this->validateForm($changeForm, "POST");
// Get the form field values
$data = $form->getData();
$changeEvent = new ConfigChangeEvent($data['id']);
// Create and dispatch the change event
$changeEvent
->setEventName($data['name'])
->setValue($data['value'])
->setHidden($data['hidden'])
->setSecured($data['secured'])
->setLocale($data["locale"])
->setTitle($data['title'])
->setChapo($data['chapo'])
->setDescription($data['description'])
->setPostscriptum($data['postscriptum'])
;
$this->dispatch(TheliaEvents::CONFIG_MODIFY, $changeEvent);
// Log config modification
$changedObject = $changeEvent->getConfig();
$this->adminLogAppend(sprintf("Variable %s (ID %s) modified", $changedObject->getName(), $changedObject->getId()));
// If we have to stay on the same page, do not redirect to the succesUrl,
// just redirect to the edit page again.
if ($this->getRequest()->get('save_mode') == 'stay') {
$this->redirect(URL::absoluteUrl(
"admin/configuration/variables/change",
array('variable_id' => $variable_id)
));
}
// Redirect to the success URL
$this->redirect($changeForm->getSuccessUrl());
}
catch (FormValidationException $ex) {
// Invalid data entered
$message = sprintf("Please check your input: %s", $ex->getMessage());
}
catch (\Exception $ex) {
// Any other error
$message = sprintf("Sorry, an error occured: %s", $ex->getMessage());
}
if ($message !== false) {
// Log error message
Tlog::getInstance()->error(sprintf("Error during variable creation process : %s. Exception was %s", $message, $ex->getMessage()));
// Mark the form as errored
$changeForm->setErrorMessage($message);
// Pas the form and the error to the parser
$this->getParserContext()
->addForm($changeForm)
->setGeneralError($message)
;
}
// At this point, the form has errors, and should be redisplayed.
return $this->render('variable-edit', array('variable_id' => $variable_id));
}
/**
* Change values modified directly from the variable list
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
public function changeValuesAction() {
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.configuration.variables.change")) return $response;
$variables = $this->getRequest()->get('variable', array());
// Process all changed variables
foreach($variables as $id => $value) {
$event = new ConfigChangeEvent($id);
$event->setValue($value);
$this->dispatch(TheliaEvents::CONFIG_SETVALUE, $event);
}
$this->redirect(URL::adminViewUrl('variables'));
}
/**
* Delete a config object
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
public function deleteAction() { public function deleteAction() {
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.configuration.variables.delete")) return $response;
// Get the config id, and dispatch the delet request
$event = new ConfigDeleteEvent($this->getRequest()->get('id')); $event = new ConfigDeleteEvent($this->getRequest()->get('id'));
$this->dispatch(TheliaEvents::CONFIG_DELETE, $event); $this->dispatch(TheliaEvents::CONFIG_DELETE, $event);
$this->redirect(URL::adminViewUrl('variables')); $this->redirect(URL::adminViewUrl('variables'));
} }
}
public function updateAction() {
}
}

View File

@@ -63,7 +63,7 @@ class CartController extends BaseFrontController
if ($message) { if ($message) {
$cartAdd->setErrorMessage($message); $cartAdd->setErrorMessage($message);
$this->getParserContext()->setErrorForm($cartAdd); $this->getParserContext()->addForm($cartAdd);
} }
} }

View File

@@ -75,10 +75,10 @@ class CustomerController extends BaseFrontController
if ($message !== false) { if ($message !== false) {
Tlog::getInstance()->error(sprintf("Error during customer creation process : %s. Exception was %s", $message, $e->getMessage())); Tlog::getInstance()->error(sprintf("Error during customer creation process : %s. Exception was %s", $message, $e->getMessage()));
$customerLoginForm->setErrorMessage($message); $customerCreation->setErrorMessage($message);
$this->getParserContext() $this->getParserContext()
->setErrorForm($customerLoginForm) ->addForm($customerCreation)
->setGeneralError($message) ->setGeneralError($message)
; ;
} }
@@ -123,10 +123,10 @@ class CustomerController extends BaseFrontController
if ($message !== false) { if ($message !== false) {
Tlog::getInstance()->error(sprintf("Error during customer modification process : %s. Exception was %s", $message, $e->getMessage())); Tlog::getInstance()->error(sprintf("Error during customer modification process : %s. Exception was %s", $message, $e->getMessage()));
$customerLoginForm->setErrorMessage($message); $customerModification->setErrorMessage($message);
$this->getParserContext() $this->getParserContext()
->setErrorForm($customerLoginForm) ->addForm($customerModification)
->setGeneralError($message) ->setGeneralError($message)
; ;
} }
@@ -183,7 +183,7 @@ class CustomerController extends BaseFrontController
$customerLoginForm->setErrorMessage($message); $customerLoginForm->setErrorMessage($message);
$this->getParserContext()->setErrorForm($customerLoginForm); $this->getParserContext()->addForm($customerLoginForm);
} }
} }
} }

View File

@@ -29,6 +29,12 @@ class ConfigChangeEvent extends ConfigCreateEvent
{ {
protected $config_id; protected $config_id;
protected $hidden;
protected $secured;
protected $description;
protected $chapo;
protected $postscriptum;
public function __construct($config_id) public function __construct($config_id)
{ {
$this->setConfigId($config_id); $this->setConfigId($config_id);
@@ -45,4 +51,64 @@ class ConfigChangeEvent extends ConfigCreateEvent
return $this; return $this;
} }
}
public function getHidden()
{
return $this->hidden;
}
public function setHidden($hidden)
{
$this->hidden = $hidden;
return $this;
}
public function getSecured()
{
return $this->secured;
}
public function setSecured($secured)
{
$this->secured = $secured;
return $this;
}
public function getDescription()
{
return $this->description;
}
public function setDescription($description)
{
$this->description = $description;
return $this;
}
public function getChapo()
{
return $this->chapo;
}
public function setChapo($chapo)
{
$this->chapo = $chapo;
return $this;
}
public function getPostscriptum()
{
return $this->postscriptum;
}
public function setPostscriptum($postscriptum)
{
$this->postscriptum = $postscriptum;
return $this;
}
}

View File

@@ -24,26 +24,22 @@
namespace Thelia\Core\Event; namespace Thelia\Core\Event;
use Thelia\Model\Config; use Thelia\Model\Config;
class ConfigCreateEvent extends ActionEvent class ConfigCreateEvent extends ConfigEvent
{ {
protected $name; protected $event_name;
protected $value; protected $value;
protected $hidden;
protected $secured;
protected $locale; protected $locale;
protected $title; protected $title;
protected $description;
protected $chapo;
protected $postscriptum;
public function getName() // Use event_name to prevent conflict with Event::name property.
public function getEventName()
{ {
return $this->name; return $this->event_name;
} }
public function setName($name) public function setEventName($event_name)
{ {
$this->name = $name; $this->event_name = $event_name;
return $this; return $this;
} }
@@ -60,30 +56,6 @@ class ConfigCreateEvent extends ActionEvent
return $this; return $this;
} }
public function getHidden()
{
return $this->hidden;
}
public function setHidden($hidden)
{
$this->hidden = $hidden;
return $this;
}
public function getSecured()
{
return $this->secured;
}
public function setSecured($secured)
{
$this->secured = $secured;
return $this;
}
public function getLocale() public function getLocale()
{ {
return $this->locale; return $this->locale;
@@ -107,40 +79,4 @@ class ConfigCreateEvent extends ActionEvent
return $this; return $this;
} }
public function getDescription()
{
return $this->description;
}
public function setDescription($description)
{
$this->description = $description;
return $this;
}
public function getChapo()
{
return $this->chapo;
}
public function setChapo($chapo)
{
$this->chapo = $chapo;
return $this;
}
public function getPostscriptum()
{
return $this->postscriptum;
}
public function setPostscriptum($postscriptum)
{
$this->postscriptum = $postscriptum;
return $this;
}
} }

View File

@@ -25,24 +25,10 @@ namespace Thelia\Core\Event;
use Thelia\Model\Config; use Thelia\Model\Config;
class ConfigDeleteEvent extends ActionEvent class ConfigDeleteEvent extends ConfigEvent
{ {
protected $config_id;
public function __construct($config_id) public function __construct($config_id)
{ {
$this->setConfigId($config_id); $this->setConfigId($config_id);
} }
public function getConfigId()
{
return $this->config_id;
}
public function setConfigId($config_id)
{
$this->config_id = $config_id;
return $this;
}
} }

View File

@@ -22,13 +22,26 @@
/*************************************************************************************/ /*************************************************************************************/
namespace Thelia\Core\Event; namespace Thelia\Core\Event;
use Thelia\Model\Config; use Thelia\Model\Config;
class ConfigEvent extends ActionEvent class ConfigEvent extends ActionEvent
{ {
public function __construct(Config $config) protected $config;
public function __construct(Config $config = null)
{ {
$this->config = $config; $this->config = $config;
} }
public function getConfig()
{
return $this->config;
}
public function setConfig($config)
{
$this->config = $config;
return $this;
}
} }

View File

@@ -29,6 +29,7 @@ use Thelia\Exception\InvalidCartException;
use Thelia\Model\CartQuery; use Thelia\Model\CartQuery;
use Thelia\Model\Cart; use Thelia\Model\Cart;
use Thelia\Tools\URL; use Thelia\Tools\URL;
use Thelia\Model\Lang;
class Session extends BaseSession class Session extends BaseSession
{ {
@@ -39,9 +40,35 @@ class Session extends BaseSession
return $this->get("locale", "en_US"); return $this->get("locale", "en_US");
} }
public function setLocale($locale)
{
$this->set("locale", $locale);
return $this;
}
public function getLang() public function getLang()
{ {
return substr($this->getLocale(), 0, 2); return $this->get("lang", substr($this->getLocale(), 0, 2));
}
public function setLang($lang)
{
$this->set("lang", $lang);
return $this;
}
public function getAdminEditionLangId()
{
return $this->get('admin.edition_language', Lang::getDefaultLanguage()->getId());
}
public function setAdminEditionLangId($langId)
{
$this->set('admin.edition_language', $langId);
return $this;
} }
// -- Customer user -------------------------------------------------------- // -- Customer user --------------------------------------------------------
@@ -49,6 +76,7 @@ class Session extends BaseSession
public function setCustomerUser(UserInterface $user) public function setCustomerUser(UserInterface $user)
{ {
$this->set('customer_user', $user); $this->set('customer_user', $user);
return $this;
} }
public function getCustomerUser() public function getCustomerUser()
@@ -66,6 +94,7 @@ class Session extends BaseSession
public function setAdminUser(UserInterface $user) public function setAdminUser(UserInterface $user)
{ {
$this->set('admin_user', $user); $this->set('admin_user', $user);
return $this;
} }
public function getAdminUser() public function getAdminUser()
@@ -83,6 +112,7 @@ class Session extends BaseSession
public function setReturnToUrl($url) public function setReturnToUrl($url)
{ {
$this->set('return_to_url', $url); $this->set('return_to_url', $url);
return $this;
} }
/** /**
@@ -141,6 +171,6 @@ class Session extends BaseSession
public function setCart($cart_id) public function setCart($cart_id)
{ {
$this->set("cart_id", $cart_id); $this->set("cart_id", $cart_id);
return $this;
} }
} }

View File

@@ -90,7 +90,7 @@ class Attribute extends BaseI18nLoop
$lang = $this->getLang(); $lang = $this->getLang();
/* manage translations */ /* manage translations */
$this->configureI18nProcessing($search); $locale = $this->configureI18nProcessing($search);
$id = $this->getId(); $id = $this->getId();
@@ -156,6 +156,7 @@ class Attribute extends BaseI18nLoop
$loopResultRow = new LoopResultRow(); $loopResultRow = new LoopResultRow();
$loopResultRow->set("ID", $attribute->getId()) $loopResultRow->set("ID", $attribute->getId())
->set("IS_TRANSLATED",$attribute->getVirtualColumn('IS_TRANSLATED')) ->set("IS_TRANSLATED",$attribute->getVirtualColumn('IS_TRANSLATED'))
->set("LOCALE",$locale)
->set("TITLE",$attribute->getVirtualColumn('i18n_TITLE')) ->set("TITLE",$attribute->getVirtualColumn('i18n_TITLE'))
->set("CHAPO", $attribute->getVirtualColumn('i18n_CHAPO')) ->set("CHAPO", $attribute->getVirtualColumn('i18n_CHAPO'))
->set("DESCRIPTION", $attribute->getVirtualColumn('i18n_DESCRIPTION')) ->set("DESCRIPTION", $attribute->getVirtualColumn('i18n_DESCRIPTION'))

View File

@@ -77,7 +77,7 @@ class AttributeAvailability extends BaseI18nLoop
$search = AttributeAvQuery::create(); $search = AttributeAvQuery::create();
/* manage translations */ /* manage translations */
$this->configureI18nProcessing($search); $locale = $this->configureI18nProcessing($search);
$id = $this->getId(); $id = $this->getId();
@@ -125,6 +125,7 @@ class AttributeAvailability extends BaseI18nLoop
$loopResultRow = new LoopResultRow(); $loopResultRow = new LoopResultRow();
$loopResultRow->set("ID", $attributeAv->getId()) $loopResultRow->set("ID", $attributeAv->getId())
->set("IS_TRANSLATED",$attributeAv->getVirtualColumn('IS_TRANSLATED')) ->set("IS_TRANSLATED",$attributeAv->getVirtualColumn('IS_TRANSLATED'))
->set("LOCALE",$locale)
->set("TITLE",$attributeAv->getVirtualColumn('i18n_TITLE')) ->set("TITLE",$attributeAv->getVirtualColumn('i18n_TITLE'))
->set("CHAPO", $attributeAv->getVirtualColumn('i18n_CHAPO')) ->set("CHAPO", $attributeAv->getVirtualColumn('i18n_CHAPO'))
->set("DESCRIPTION", $attributeAv->getVirtualColumn('i18n_DESCRIPTION')) ->set("DESCRIPTION", $attributeAv->getVirtualColumn('i18n_DESCRIPTION'))

View File

@@ -77,7 +77,7 @@ class AttributeCombination extends BaseI18nLoop
$search = AttributeCombinationQuery::create(); $search = AttributeCombinationQuery::create();
/* manage attribute translations */ /* manage attribute translations */
$this->configureI18nProcessing( $locale = $this->configureI18nProcessing(
$search, $search,
array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'),
AttributeTableMap::TABLE_NAME, AttributeTableMap::TABLE_NAME,
@@ -85,7 +85,7 @@ class AttributeCombination extends BaseI18nLoop
); );
/* manage attributeAv translations */ /* manage attributeAv translations */
$this->configureI18nProcessing( $locale = $this->configureI18nProcessing(
$search, $search,
array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'),
AttributeAvTableMap::TABLE_NAME, AttributeAvTableMap::TABLE_NAME,
@@ -117,6 +117,7 @@ class AttributeCombination extends BaseI18nLoop
$loopResultRow = new LoopResultRow(); $loopResultRow = new LoopResultRow();
$loopResultRow $loopResultRow
->set("LOCALE",$locale)
->set("ATTRIBUTE_TITLE", $attributeCombination->getVirtualColumn(AttributeTableMap::TABLE_NAME . '_i18n_TITLE')) ->set("ATTRIBUTE_TITLE", $attributeCombination->getVirtualColumn(AttributeTableMap::TABLE_NAME . '_i18n_TITLE'))
->set("ATTRIBUTE_CHAPO", $attributeCombination->getVirtualColumn(AttributeTableMap::TABLE_NAME . '_i18n_CHAPO')) ->set("ATTRIBUTE_CHAPO", $attributeCombination->getVirtualColumn(AttributeTableMap::TABLE_NAME . '_i18n_CHAPO'))
->set("ATTRIBUTE_DESCRIPTION", $attributeCombination->getVirtualColumn(AttributeTableMap::TABLE_NAME . '_i18n_DESCRIPTION')) ->set("ATTRIBUTE_DESCRIPTION", $attributeCombination->getVirtualColumn(AttributeTableMap::TABLE_NAME . '_i18n_DESCRIPTION'))

View File

@@ -178,6 +178,7 @@ class Category extends BaseI18nLoop
$loopResultRow $loopResultRow
->set("ID", $category->getId()) ->set("ID", $category->getId())
->set("IS_TRANSLATED",$category->getVirtualColumn('IS_TRANSLATED')) ->set("IS_TRANSLATED",$category->getVirtualColumn('IS_TRANSLATED'))
->set("LOCALE",$locale)
->set("TITLE", $category->getVirtualColumn('i18n_TITLE')) ->set("TITLE", $category->getVirtualColumn('i18n_TITLE'))
->set("CHAPO", $category->getVirtualColumn('i18n_CHAPO')) ->set("CHAPO", $category->getVirtualColumn('i18n_CHAPO'))
->set("DESCRIPTION", $category->getVirtualColumn('i18n_DESCRIPTION')) ->set("DESCRIPTION", $category->getVirtualColumn('i18n_DESCRIPTION'))

View File

@@ -101,6 +101,7 @@ class CategoryPath extends BaseI18nLoop
->set("TITLE",$category->getVirtualColumn('i18n_TITLE')) ->set("TITLE",$category->getVirtualColumn('i18n_TITLE'))
->set("URL", $category->getUrl($locale)) ->set("URL", $category->getUrl($locale))
->set("ID", $category->getId()) ->set("ID", $category->getId())
->set("LOCALE",$locale)
; ;
$results[] = $loopResultRow; $results[] = $loopResultRow;

View File

@@ -72,10 +72,11 @@ class Config extends BaseI18nLoop
{ {
$id = $this->getId(); $id = $this->getId();
$name = $this->getVariable(); $name = $this->getVariable();
$secured = $this->getSecured();
$search = ConfigQuery::create(); $search = ConfigQuery::create();
$this->configureI18nProcessing($search); $locale = $this->configureI18nProcessing($search);
if (! is_null($id)) if (! is_null($id))
$search->filterById($id); $search->filterById($id);
@@ -90,8 +91,8 @@ class Config extends BaseI18nLoop
if ($this->getHidden() != BooleanOrBothType::ANY) if ($this->getHidden() != BooleanOrBothType::ANY)
$search->filterByHidden($this->getHidden() ? 1 : 0); $search->filterByHidden($this->getHidden() ? 1 : 0);
if ($this->getSecured() != BooleanOrBothType::ANY) if (! is_null($secured) && $secured != BooleanOrBothType::ANY)
$search->filterBySecured($this->getSecured() ? 1 : 0); $search->filterBySecured($secured ? 1 : 0);
$search->orderByName(Criteria::ASC); $search->orderByName(Criteria::ASC);
@@ -108,6 +109,7 @@ class Config extends BaseI18nLoop
->set("NAME" , $result->getName()) ->set("NAME" , $result->getName())
->set("VALUE" , $result->getValue()) ->set("VALUE" , $result->getValue())
->set("IS_TRANSLATED", $result->getVirtualColumn('IS_TRANSLATED')) ->set("IS_TRANSLATED", $result->getVirtualColumn('IS_TRANSLATED'))
->set("LOCALE",$locale)
->set("TITLE" , $result->getVirtualColumn('i18n_TITLE')) ->set("TITLE" , $result->getVirtualColumn('i18n_TITLE'))
->set("CHAPO" , $result->getVirtualColumn('i18n_CHAPO')) ->set("CHAPO" , $result->getVirtualColumn('i18n_CHAPO'))
->set("DESCRIPTION" , $result->getVirtualColumn('i18n_DESCRIPTION')) ->set("DESCRIPTION" , $result->getVirtualColumn('i18n_DESCRIPTION'))

View File

@@ -214,6 +214,7 @@ class Content extends BaseI18nLoop
$loopResultRow->set("ID", $content->getId()) $loopResultRow->set("ID", $content->getId())
->set("IS_TRANSLATED",$content->getVirtualColumn('IS_TRANSLATED')) ->set("IS_TRANSLATED",$content->getVirtualColumn('IS_TRANSLATED'))
->set("LOCALE",$locale)
->set("TITLE",$content->getVirtualColumn('i18n_TITLE')) ->set("TITLE",$content->getVirtualColumn('i18n_TITLE'))
->set("CHAPO", $content->getVirtualColumn('i18n_CHAPO')) ->set("CHAPO", $content->getVirtualColumn('i18n_CHAPO'))
->set("DESCRIPTION", $content->getVirtualColumn('i18n_DESCRIPTION')) ->set("DESCRIPTION", $content->getVirtualColumn('i18n_DESCRIPTION'))

View File

@@ -68,7 +68,7 @@ class Country extends BaseI18nLoop
$search = CountryQuery::create(); $search = CountryQuery::create();
/* manage translations */ /* manage translations */
$this->configureI18nProcessing($search); $locale = $this->configureI18nProcessing($search);
$id = $this->getId(); $id = $this->getId();
@@ -107,6 +107,7 @@ class Country extends BaseI18nLoop
$loopResultRow = new LoopResultRow(); $loopResultRow = new LoopResultRow();
$loopResultRow->set("ID", $country->getId()) $loopResultRow->set("ID", $country->getId())
->set("IS_TRANSLATED",$country->getVirtualColumn('IS_TRANSLATED')) ->set("IS_TRANSLATED",$country->getVirtualColumn('IS_TRANSLATED'))
->set("LOCALE",$locale)
->set("TITLE",$country->getVirtualColumn('i18n_TITLE')) ->set("TITLE",$country->getVirtualColumn('i18n_TITLE'))
->set("CHAPO", $country->getVirtualColumn('i18n_CHAPO')) ->set("CHAPO", $country->getVirtualColumn('i18n_CHAPO'))
->set("DESCRIPTION", $country->getVirtualColumn('i18n_DESCRIPTION')) ->set("DESCRIPTION", $country->getVirtualColumn('i18n_DESCRIPTION'))

View File

@@ -67,7 +67,7 @@ class Currency extends BaseI18nLoop
$search = CurrencyQuery::create(); $search = CurrencyQuery::create();
/* manage translations */ /* manage translations */
$this->configureI18nProcessing($search, array('NAME')); $locale = $this->configureI18nProcessing($search, array('NAME'));
$id = $this->getId(); $id = $this->getId();
@@ -98,6 +98,7 @@ class Currency extends BaseI18nLoop
$loopResultRow = new LoopResultRow(); $loopResultRow = new LoopResultRow();
$loopResultRow->set("ID", $currency->getId()) $loopResultRow->set("ID", $currency->getId())
->set("IS_TRANSLATED",$currency->getVirtualColumn('IS_TRANSLATED')) ->set("IS_TRANSLATED",$currency->getVirtualColumn('IS_TRANSLATED'))
->set("LOCALE",$locale)
->set("NAME",$currency->getVirtualColumn('i18n_NAME')) ->set("NAME",$currency->getVirtualColumn('i18n_NAME'))
->set("ISOCODE", $currency->getCode()) ->set("ISOCODE", $currency->getCode())
->set("SYMBOL", $currency->getSymbol()) ->set("SYMBOL", $currency->getSymbol())

View File

@@ -82,7 +82,7 @@ class Feature extends BaseI18nLoop
$search = FeatureQuery::create(); $search = FeatureQuery::create();
/* manage translations */ /* manage translations */
$this->configureI18nProcessing($search); $locale = $this->configureI18nProcessing($search);
$id = $this->getId(); $id = $this->getId();
@@ -148,6 +148,7 @@ class Feature extends BaseI18nLoop
$loopResultRow = new LoopResultRow(); $loopResultRow = new LoopResultRow();
$loopResultRow->set("ID", $feature->getId()) $loopResultRow->set("ID", $feature->getId())
->set("IS_TRANSLATED",$feature->getVirtualColumn('IS_TRANSLATED')) ->set("IS_TRANSLATED",$feature->getVirtualColumn('IS_TRANSLATED'))
->set("LOCALE",$locale)
->set("TITLE",$feature->getVirtualColumn('i18n_TITLE')) ->set("TITLE",$feature->getVirtualColumn('i18n_TITLE'))
->set("CHAPO", $feature->getVirtualColumn('i18n_CHAPO')) ->set("CHAPO", $feature->getVirtualColumn('i18n_CHAPO'))
->set("DESCRIPTION", $feature->getVirtualColumn('i18n_DESCRIPTION')) ->set("DESCRIPTION", $feature->getVirtualColumn('i18n_DESCRIPTION'))

View File

@@ -75,7 +75,7 @@ class FeatureAvailability extends BaseI18nLoop
$search = FeatureAvQuery::create(); $search = FeatureAvQuery::create();
/* manage translations */ /* manage translations */
$this->configureI18nProcessing($search); $locale = $this->configureI18nProcessing($search);
$id = $this->getId(); $id = $this->getId();
@@ -123,6 +123,7 @@ class FeatureAvailability extends BaseI18nLoop
$loopResultRow = new LoopResultRow(); $loopResultRow = new LoopResultRow();
$loopResultRow->set("ID", $featureAv->getId()) $loopResultRow->set("ID", $featureAv->getId())
->set("IS_TRANSLATED",$featureAv->getVirtualColumn('IS_TRANSLATED')) ->set("IS_TRANSLATED",$featureAv->getVirtualColumn('IS_TRANSLATED'))
->set("LOCALE",$locale)
->set("TITLE",$featureAv->getVirtualColumn('i18n_TITLE')) ->set("TITLE",$featureAv->getVirtualColumn('i18n_TITLE'))
->set("CHAPO", $featureAv->getVirtualColumn('i18n_CHAPO')) ->set("CHAPO", $featureAv->getVirtualColumn('i18n_CHAPO'))
->set("DESCRIPTION", $featureAv->getVirtualColumn('i18n_DESCRIPTION')) ->set("DESCRIPTION", $featureAv->getVirtualColumn('i18n_DESCRIPTION'))

View File

@@ -82,7 +82,7 @@ class FeatureValue extends BaseI18nLoop
$search = FeatureProductQuery::create(); $search = FeatureProductQuery::create();
/* manage featureAv translations */ /* manage featureAv translations */
$this->configureI18nProcessing( $locale = $this->configureI18nProcessing(
$search, $search,
array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'),
FeatureAvTableMap::TABLE_NAME, FeatureAvTableMap::TABLE_NAME,
@@ -141,7 +141,9 @@ class FeatureValue extends BaseI18nLoop
$loopResultRow = new LoopResultRow(); $loopResultRow = new LoopResultRow();
$loopResultRow->set("ID", $featureValue->getId()); $loopResultRow->set("ID", $featureValue->getId());
$loopResultRow->set("PERSONAL_VALUE", $featureValue->getByDefault()) $loopResultRow
->set("LOCALE",$locale)
->set("PERSONAL_VALUE", $featureValue->getByDefault())
->set("TITLE",$featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_TITLE')) ->set("TITLE",$featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_TITLE'))
->set("CHAPO", $featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_CHAPO')) ->set("CHAPO", $featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_CHAPO'))
->set("DESCRIPTION", $featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_DESCRIPTION')) ->set("DESCRIPTION", $featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_DESCRIPTION'))

View File

@@ -156,6 +156,7 @@ class Folder extends BaseI18nLoop
$loopResultRow $loopResultRow
->set("ID", $folder->getId()) ->set("ID", $folder->getId())
->set("IS_TRANSLATED",$folder->getVirtualColumn('IS_TRANSLATED')) ->set("IS_TRANSLATED",$folder->getVirtualColumn('IS_TRANSLATED'))
->set("LOCALE",$locale)
->set("TITLE",$folder->getVirtualColumn('i18n_TITLE')) ->set("TITLE",$folder->getVirtualColumn('i18n_TITLE'))
->set("CHAPO", $folder->getVirtualColumn('i18n_CHAPO')) ->set("CHAPO", $folder->getVirtualColumn('i18n_CHAPO'))
->set("DESCRIPTION", $folder->getVirtualColumn('i18n_DESCRIPTION')) ->set("DESCRIPTION", $folder->getVirtualColumn('i18n_DESCRIPTION'))

View File

@@ -164,7 +164,7 @@ class Image extends BaseI18nLoop
$search = $this->getSearchQuery($object_type, $object_id); $search = $this->getSearchQuery($object_type, $object_id);
/* manage translations */ /* manage translations */
$this->configureI18nProcessing($search); $locale = $this->configureI18nProcessing($search);
$id = $this->getId(); $id = $this->getId();
@@ -186,7 +186,7 @@ class Image extends BaseI18nLoop
$background_color = $this->getBackgroundColor(); $background_color = $this->getBackgroundColor();
$quality = $this->getQuality(); $quality = $this->getQuality();
$effects = $this->getEffects(); $effects = $this->getEffects();
$effects = $this->getEffects();
if (! is_null($effects)) { if (! is_null($effects)) {
$effects = explode(',', $effects); $effects = explode(',', $effects);
} }
@@ -245,14 +245,15 @@ class Image extends BaseI18nLoop
$loopResultRow $loopResultRow
->set("ID", $result->getId()) ->set("ID", $result->getId())
->set("LOCALE",$locale)
->set("IMAGE_URL", $event->getFileUrl()) ->set("IMAGE_URL", $event->getFileUrl())
->set("ORIGINAL_IMAGE_URL", $event->getOriginalFileUrl()) ->set("ORIGINAL_IMAGE_URL", $event->getOriginalFileUrl())
->set("IMAGE_PATH", $event->getCacheFilepath()) ->set("IMAGE_PATH", $event->getCacheFilepath())
->set("ORIGINAL_IMAGE_PATH", $source_filepath) ->set("ORIGINAL_IMAGE_PATH", $source_filepath)
->set("TITLE", $result->getTitle()) ->set("TITLE",$folder->getVirtualColumn('i18n_TITLE'))
->set("CHAPO", $result->getChapo()) ->set("CHAPO", $folder->getVirtualColumn('i18n_CHAPO'))
->set("DESCRIPTION", $result->getDescription()) ->set("DESCRIPTION", $folder->getVirtualColumn('i18n_DESCRIPTION'))
->set("POSTSCRIPTUM", $result->getPostscriptum()) ->set("POSTSCRIPTUM", $folder->getVirtualColumn('i18n_POSTSCRIPTUM'))
->set("POSITION", $result->getPosition()) ->set("POSITION", $result->getPosition())
->set("OBJECT_TYPE", $object_type) ->set("OBJECT_TYPE", $object_type)
->set("OBJECT_ID", $object_id) ->set("OBJECT_ID", $object_id)

View File

@@ -509,6 +509,7 @@ class Product extends BaseI18nLoop
$loopResultRow->set("ID", $product->getId()) $loopResultRow->set("ID", $product->getId())
->set("REF",$product->getRef()) ->set("REF",$product->getRef())
->set("IS_TRANSLATED",$product->getVirtualColumn('IS_TRANSLATED')) ->set("IS_TRANSLATED",$product->getVirtualColumn('IS_TRANSLATED'))
->set("LOCALE",$locale)
->set("TITLE",$product->getVirtualColumn('i18n_TITLE')) ->set("TITLE",$product->getVirtualColumn('i18n_TITLE'))
->set("CHAPO", $product->getVirtualColumn('i18n_CHAPO')) ->set("CHAPO", $product->getVirtualColumn('i18n_CHAPO'))
->set("DESCRIPTION", $product->getVirtualColumn('i18n_DESCRIPTION')) ->set("DESCRIPTION", $product->getVirtualColumn('i18n_DESCRIPTION'))

View File

@@ -65,7 +65,7 @@ class Title extends BaseI18nLoop
$search = CustomerTitleQuery::create(); $search = CustomerTitleQuery::create();
/* manage translations */ /* manage translations */
$this->configureI18nProcessing($search, array('SHORT', 'LONG')); $locale = $this->configureI18nProcessing($search, array('SHORT', 'LONG'));
$id = $this->getId(); $id = $this->getId();
@@ -84,6 +84,7 @@ class Title extends BaseI18nLoop
$loopResultRow = new LoopResultRow(); $loopResultRow = new LoopResultRow();
$loopResultRow->set("ID", $title->getId()) $loopResultRow->set("ID", $title->getId())
->set("IS_TRANSLATED",$title->getVirtualColumn('IS_TRANSLATED')) ->set("IS_TRANSLATED",$title->getVirtualColumn('IS_TRANSLATED'))
->set("LOCALE",$locale)
->set("DEFAULT", $title->getByDefault()) ->set("DEFAULT", $title->getByDefault())
->set("SHORT", $title->getVirtualColumn('i18n_SHORT')) ->set("SHORT", $title->getVirtualColumn('i18n_SHORT'))
->set("LONG", $title->getVirtualColumn('i18n_LONG')); ->set("LONG", $title->getVirtualColumn('i18n_LONG'));

View File

@@ -49,13 +49,18 @@ class ParserContext implements \IteratorAggregate
/** /**
* @param BaseForm $form the errored form * @param BaseForm $form the errored form
*/ */
public function setErrorForm(BaseForm $form) public function addForm(BaseForm $form)
{ {
$this->set('error_form', $form); $this->set($form->getName(), $form);
return $this; return $this;
} }
public function getForm($name)
{
return $this->get($name, null);
}
public function setGeneralError($error) public function setGeneralError($error)
{ {
$this->set('general_error', $error); $this->set('general_error', $error);
@@ -63,16 +68,6 @@ class ParserContext implements \IteratorAggregate
return $this; return $this;
} }
public function getErrorForm()
{
return $this->get('error_form', null);
}
public function clearErrorForm()
{
return $this->remove('error_form');
}
// -- Internal table manipulation ------------------------------------------ // -- Internal table manipulation ------------------------------------------
public function set($name, $value) public function set($name, $value)

View File

@@ -82,6 +82,7 @@ class Form extends AbstractSmartyPlugin
public function generateForm($params, $content, \Smarty_Internal_Template $template, &$repeat) public function generateForm($params, $content, \Smarty_Internal_Template $template, &$repeat)
{ {
if ($repeat) { if ($repeat) {
$name = $this->getParam($params, 'name'); $name = $this->getParam($params, 'name');
@@ -93,15 +94,11 @@ class Form extends AbstractSmartyPlugin
$instance = $this->createInstance($name); $instance = $this->createInstance($name);
// Check if parser context contains our form // Check if parser context contains our form
$errorForm = $this->parserContext->getErrorForm(); $form = $this->parserContext->getForm($instance->getName());
if (null != $errorForm && $errorForm->getName() == $instance->getName()) { if (null != $form) {
// Re-use the form
// Re-use the errored form $instance = $form;
$instance = $errorForm;
// Don't do that, as we may want to use this form firther in the template code
//$this->parserContext->clearErrorForm();
} }
$instance->createView(); $instance->createView();
@@ -110,7 +107,8 @@ class Form extends AbstractSmartyPlugin
$template->assign("form_error", $instance->hasError() ? true : false); $template->assign("form_error", $instance->hasError() ? true : false);
$template->assign("form_error_message", $instance->getErrorMessage()); $template->assign("form_error_message", $instance->getErrorMessage());
} else { }
else {
return $content; return $content;
} }
} }

View File

@@ -311,13 +311,13 @@ class TheliaLoop extends AbstractSmartyPlugin
$type = strtolower($smartyParams['type']); $type = strtolower($smartyParams['type']);
if (! isset($this->loopDefinition[$type])) { if (! isset($this->loopDefinition[$type])) {
throw new ElementNotFoundException(sprintf("%s loop does not exists", $type)); throw new ElementNotFoundException(sprintf("'%s' loop type does not exists", $type));
} }
$class = new \ReflectionClass($this->loopDefinition[$type]); $class = new \ReflectionClass($this->loopDefinition[$type]);
if ($class->isSubclassOf("Thelia\Core\Template\Element\BaseLoop") === false) { if ($class->isSubclassOf("Thelia\Core\Template\Element\BaseLoop") === false) {
throw new InvalidElementException(sprintf("%s Loop class have to extends Thelia\Core\Template\Element\BaseLoop", throw new InvalidElementException(sprintf("'%s' Loop class should extends Thelia\Core\Template\Element\BaseLoop",
$type)); $type));
} }

View File

@@ -212,14 +212,14 @@ class SmartyParser extends Smarty implements ParserInterface
$templateDir = realpath(THELIA_TEMPLATE_DIR . rtrim($this->template, "/") . "/"); $templateDir = realpath(THELIA_TEMPLATE_DIR . rtrim($this->template, "/") . "/");
if (strpos($pathFileName, $templateDir) !== 0) { if (strpos($pathFileName, $templateDir) !== 0) {
throw new ResourceNotFoundException(sprintf("%s view does not exists", $file)); throw new ResourceNotFoundException(sprintf("'%s' view does not exists", $file));
} }
if (!file_exists($fileName)) { if (!file_exists($fileName)) {
$fileName .= ".html"; $fileName .= ".html";
if (!file_exists($fileName)) { if (!file_exists($fileName)) {
throw new ResourceNotFoundException(sprintf("%s file not found in %s template", $file, $this->template)); throw new ResourceNotFoundException(sprintf("'%s' file not found in %s template", $file, $this->template));
} }
} }

View File

@@ -125,8 +125,10 @@ class TheliaHttpKernel extends HttpKernel
$lang = $this->detectLang($request); $lang = $this->detectLang($request);
if ($lang) { if ($lang) {
$request->getSession()->set("lang", $lang->getCode()); $request->getSession()
$request->getSession()->set("locale", $lang->getLocale()); ->setLang($lang->getCode())
->setLocale($lang->getLocale())
;
} }
} }
@@ -164,7 +166,7 @@ class TheliaHttpKernel extends HttpKernel
} }
//check if lang is not defined. If not we have to search the good one. //check if lang is not defined. If not we have to search the good one.
if (null === $request->getSession()->get("lang")) { if (null === $request->getSession()->getLang()) {
if (Model\ConfigQuery::read("one_domain_foreach_lang", false) == 1) { if (Model\ConfigQuery::read("one_domain_foreach_lang", false) == 1) {
//find lang with domain //find lang with domain
@@ -173,9 +175,7 @@ class TheliaHttpKernel extends HttpKernel
//find default lang //find default lang
return Model\LangQuery::create()->findOneByByDefault(1); return Model\LangQuery::create()->findOneByByDefault(1);
} }
} }
protected function initSession(Request $request) protected function initSession(Request $request)

View File

@@ -0,0 +1,54 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Form;
use Symfony\Component\Validator\Constraints\NotBlank;
/**
* A base form for all objects with standard contents.
*
* @author Franck Allimant <franck@cqfdev.fr>
*/
abstract class BaseDescForm extends BaseForm
{
protected function buildForm()
{
$this->formBuilder
->add("locale", "hidden", array(
"constraints" => array(
new NotBlank()
)
)
)
->add("title", "text", array(
"constraints" => array(
new NotBlank()
)
)
)
->add("chapo", "text", array())
->add("description", "text", array())
->add("postscriptum", "text", array())
;
}
}

View File

@@ -0,0 +1,57 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Form;
use Symfony\Component\Validator\Constraints\NotBlank;
use Thelia\Model\LangQuery;
use Propel\Runtime\ActiveQuery\Criteria;
class VariableCreationForm extends BaseForm
{
protected function buildForm()
{
$this->formBuilder
->add("name", "text", array(
"constraints" => array(
new NotBlank()
)
))
->add("title", "text", array(
"constraints" => array(
new NotBlank()
)
))
->add("locale", "hidden", array(
"constraints" => array(
new NotBlank()
)
))
->add("value", "text", array())
;
}
public function getName()
{
return "thelia_variable_creation";
}
}

View File

@@ -0,0 +1,59 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Form;
use Symfony\Component\Validator\Constraints\NotBlank;
use Thelia\Model\LangQuery;
use Propel\Runtime\ActiveQuery\Criteria;
use Symfony\Component\Validator\Constraints\GreaterThan;
class VariableModificationForm extends BaseDescForm
{
protected function buildForm()
{
parent::buildForm();
$this->formBuilder
->add("id", "hidden", array(
"constraints" => array(
new GreaterThan(
array('value' => 0)
)
)
))
->add("name", "text", array(
"constraints" => array(
new NotBlank()
)
))
->add("value", "text", array())
->add("hidden", "hidden", array())
->add("secured", "hidden", array())
;
}
public function getName()
{
return "thelia_variable_creation";
}
}

View File

@@ -32,6 +32,9 @@ class Config extends BaseConfig {
use \Thelia\Model\Tools\ModelEventDispatcherTrait; use \Thelia\Model\Tools\ModelEventDispatcherTrait;
/**
* {@inheritDoc}
*/
public function preInsert(ConnectionInterface $con = null) public function preInsert(ConnectionInterface $con = null)
{ {
$this->dispatchEvent(TheliaEvents::BEFORE_CREATECONFIG, new ConfigEvent($this)); $this->dispatchEvent(TheliaEvents::BEFORE_CREATECONFIG, new ConfigEvent($this));
@@ -39,11 +42,17 @@ class Config extends BaseConfig {
return true; return true;
} }
/**
* {@inheritDoc}
*/
public function postInsert(ConnectionInterface $con = null) public function postInsert(ConnectionInterface $con = null)
{ {
$this->dispatchEvent(TheliaEvents::AFTER_CREATECONFIG, new ConfigEvent($this)); $this->dispatchEvent(TheliaEvents::AFTER_CREATECONFIG, new ConfigEvent($this));
} }
/**
* {@inheritDoc}
*/
public function preUpdate(ConnectionInterface $con = null) public function preUpdate(ConnectionInterface $con = null)
{ {
$this->dispatchEvent(TheliaEvents::BEFORE_CHANGECONFIG, new ConfigEvent($this)); $this->dispatchEvent(TheliaEvents::BEFORE_CHANGECONFIG, new ConfigEvent($this));
@@ -51,11 +60,17 @@ class Config extends BaseConfig {
return true; return true;
} }
/**
* {@inheritDoc}
*/
public function postUpdate(ConnectionInterface $con = null) public function postUpdate(ConnectionInterface $con = null)
{ {
$this->dispatchEvent(TheliaEvents::AFTER_CHANGECONFIG, new ConfigEvent($this)); $this->dispatchEvent(TheliaEvents::AFTER_CHANGECONFIG, new ConfigEvent($this));
} }
/**
* {@inheritDoc}
*/
public function preDelete(ConnectionInterface $con = null) public function preDelete(ConnectionInterface $con = null)
{ {
$this->dispatchEvent(TheliaEvents::BEFORE_DELETECONFIG, new ConfigEvent($this)); $this->dispatchEvent(TheliaEvents::BEFORE_DELETECONFIG, new ConfigEvent($this));
@@ -63,6 +78,9 @@ class Config extends BaseConfig {
return true; return true;
} }
/**
* {@inheritDoc}
*/
public function postDelete(ConnectionInterface $con = null) public function postDelete(ConnectionInterface $con = null)
{ {
$this->dispatchEvent(TheliaEvents::AFTER_DELETECONFIG, new ConfigEvent($this)); $this->dispatchEvent(TheliaEvents::AFTER_DELETECONFIG, new ConfigEvent($this));

View File

@@ -575,6 +575,11 @@ form .info .input-append .add-on {
line-height: 30px; line-height: 30px;
} }
.title-without-tabs {
border-bottom: 2px solid #A5CED8;
margin-bottom: 0.5em;
}
// The action bar on the right // The action bar on the right
.actions { .actions {
text-align: right; text-align: right;
@@ -594,6 +599,8 @@ form .info .input-append .add-on {
line-height: 30px; line-height: 30px;
margin-bottom: 1em; margin-bottom: 1em;
border-bottom: 1px dotted #A5CED8;
padding-bottom: 0.5em;
.inner-actions { .inner-actions {
text-align: right; text-align: right;
@@ -633,7 +640,7 @@ label {
} }
.input-append.input-block-level .add-on img { .input-append.input-block-level .add-on img {
max-height: 18px; max-height: 16px;
} }
// Information in field label // Information in field label
@@ -739,6 +746,10 @@ label {
border-radius: 4px 4px 4px 4px; border-radius: 4px 4px 4px 4px;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
} }
&.actions {
text-align: right;
}
} }
} }
@@ -770,4 +781,9 @@ label {
select, textarea, input[type="text"], input[type="password"], input[type="datetime"], input[type="datetime-local"], input[type="date"], input[type="month"], input[type="time"], input[type="week"], input[type="number"], input[type="email"], input[type="url"], input[type="search"], input[type="tel"], input[type="color"], .uneditable-input { select, textarea, input[type="text"], input[type="password"], input[type="datetime"], input[type="datetime-local"], input[type="date"], input[type="month"], input[type="time"], input[type="week"], input[type="number"], input[type="email"], input[type="url"], input[type="search"], input[type="tel"], input[type="color"], .uneditable-input {
margin-bottom: 0; margin-bottom: 0;
} }
}
// Modal is no longer limited
.modal-body {
max-height: none;
} }

View File

@@ -4,7 +4,7 @@
{include file='includes/header.inc.html'} {include file='includes/header.inc.html'}
<div class="catalog"> <div class="catalog edit-category">
<div id="wrapper" class="container"> <div id="wrapper" class="container">
<ul class="breadcrumb"> <ul class="breadcrumb">
{include file="includes/category_breadcrumb.html"} {include file="includes/category_breadcrumb.html"}

View File

@@ -1,26 +1,13 @@
{* Breadcrumb for categories browsing and editing *} {* Breadcrumb for categories browsing and editing *}
<li><a href="{url path='admin/home'}">Home</a> <span class="divider">/</span></li> <li><a href="{url path='admin/home'}">Home</a> <span class="divider">/</span></li>
<li><a href="{url path='admin/catalog'}">Catalog</a> <li><a href="{url path='admin/catalog'}">Catalog</a> {ifloop rel="category_path"} <span class="divider">/</span></li>
{ifloop rel="category_path"} {loop name="category_path" type="category-path" visible="*" category="{$current_category_id}"} {if $ID == $current_category_id}
<span class="divider">/</span></li> <li class="active">{if $action == 'edit'} {intl l='Editing %cat' cat="{$TITLE}"} {else} {$TITLE} <a href="{url path='admin/catalog/category' id=" $ID" action='edit' }" title="{intl l='Edit this category'}">{intl l="(edit)"}</a> {/if}
</li>
{loop name="category_path" type="category-path" visible="*" category="{$current_category_id}"} {else}
{if $ID == $current_category_id} <li><a href="{url path='admin/catalog/category' id=" $ID" action='browse'}">{$TITLE}</a> <span class="divider">/</span></li>
<li class="active"> {/if} {/loop} {/ifloop} {elseloop rel="category_path"}
{if $action == 'edit'} </li>
{intl l='Editing %cat' cat="{$TITLE}"} {/elseloop}
{else}
{$TITLE} <a href="{url path='admin/catalog/category' id="$ID" action='edit'}" title="{intl l='Edit this category'}">{intl l="(edit)"}</a>
{/if}
</li>
{else}
<li><a href="{url path='admin/catalog/category' id="$ID" action='browse'}">{$TITLE}</a> <span class="divider">/</span></li>
{/if}
{/loop}
{/ifloop}
{elseloop rel="category_path"}
</li>
{/elseloop}

View File

@@ -55,7 +55,7 @@
{module_include location='inside_topbar'} {module_include location='inside_topbar'}
<div class="user-info"> <div class="user-info">
<a class="profile" href="href="{url path='admin/edit_profile'}">{admin attr="firstname"} {admin attr="lastname"}</a> <a class="profile" href="{url path='admin/edit_profile'}">{admin attr="firstname"} {admin attr="lastname"}</a>
<a class="logout" href="{url path='admin/logout'}" title="{intl l='Close administation session'}">{intl l="Logout"}</a></div> <a class="logout" href="{url path='admin/logout'}" title="{intl l='Close administation session'}">{intl l="Logout"}</a></div>
{loop name="top-bar-search" type="auth" context="admin" roles="ADMIN" permissions="admin.search"} {loop name="top-bar-search" type="auth" context="admin" roles="ADMIN" permissions="admin.search"}

View File

@@ -11,17 +11,17 @@
<ul class="nav nav-pills"> <ul class="nav nav-pills">
{loop name="lang_list" type="lang" default_only={$default_only}} {loop name="lang_list" type="lang" default_only={$default_only}}
<li {if $IS_DEFAULT}class="active"{/if}> <li {if $ID == $edition_language}class="active"{/if}>
<a href="#" title="{intl l="Edit information in %lng" lng=$TITLE}"> <a href="{$current_url}&amp;edition_language={$ID}" title="{intl l="Edit information in %lng" lng=$TITLE}">
<img src="{image file="../assets/img/flags/{$CODE}.gif"}" alt="{intl l=$TITLE}" /> <img src="{image file="../assets/img/flags/{$CODE}.gif"}" alt="{intl l=$TITLE}" />
</a> </a>
</li> </li>
{/loop} {/loop}
</ul> </ul>
</div> </div>
<div class="span6 inner-actions"> <div class="span6 inner-actions">
<button class="btn btn-primary" title="{intl l='Save'}">{intl l='Save'} <i class="icon icon-white icon-ok"></i></button> <button type="submit" name="save_mode" value="stay" class="btn btn-primary" title="{intl l='Save'}">{intl l='Save'} <i class="icon icon-white icon-ok"></i></button>
<button class="btn btn-info" title="{intl l='Save and close'}">{intl l='Save and close'} <i class="icon icon-remove icon-white"></i></button> <button type="submit" name="save_mode" value="close" class="btn btn-info" title="{intl l='Save and close'}">{intl l='Save and close'} <i class="icon icon-remove icon-white"></i></button>
</div> </div>
</div> </div>

View File

@@ -0,0 +1,60 @@
{* The standard description fields, used by many Thelia objects *}
{form_field form=$form field='title'}
<div class="control-group">
<label class="control-label">
{intl l='Title *'}
</label>
<div class="controls">
<span {if $error}class="error"{/if}>
<input type="text" name="{$name}" required="required" title="{intl l='Title'}" placeholder="{intl l='Title'}" class="input-block-level" value="{$value|htmlspecialchars}">
</span>
</div>
</div>
{/form_field}
{form_field form=$form field='chapo'}
<div class="control-group">
<label class="control-label">
{intl l='Summary'}
<span class="label-help-block">{intl l="A short description, used when a summary or an introduction is required"}</span>
</label>
<div class="controls">
<span {if $error}class="error"{/if}>
<textarea name="{$name}" rows="3" title="{intl l='Short description'}" placeholder="{intl l='Short description'}" class="input-block-level">{$value|htmlspecialchars}</textarea>
</span>
</div>
</div>
{/form_field}
{form_field form=$form field='description'}
<div class="control-group">
<label class="control-label">
{intl l='Detailed description'}
<span class="label-help-block">{intl l="The détailed description."}</span>
</label>
<div class="controls">
<span {if $error}class="error"{/if}>
<textarea name="{$name}" rows="10" class="input-block-level">{$value|htmlspecialchars}</textarea>
</span>
</div>
</div>
{/form_field}
{form_field form=$form field='postscriptum'}
<div class="control-group">
<label class="control-label">
{intl l='Conclusion'}
<span class="label-help-block">{intl l="A short post-description information"}</span>
</label>
<div class="controls">
<span {if $error}class="error"{/if}>
<textarea name="{$name}" rows="3" title="{intl l='Short conclusion'}" placeholder="{intl l='Short conclusion'}" class="input-block-level">{$value|htmlspecialchars}</textarea>
</span>
</div>
</div>
{/form_field}

View File

@@ -0,0 +1,136 @@
{check_auth context="admin" roles="ADMIN" permissions="admin.configuration.variables.edit" login_tpl="admin/login"}
{$page_title={intl l='Edit a system variable'}}
{include file='includes/header.inc.html'}
<div class="variables edit-variable">
<div id="wrapper" class="container">
{loop name="config_edit" type="config" hidden="*" id="$variable_id" backend_context="1" lang="$edition_language"}
<ul class="breadcrumb">
<li><a href="{url path='admin/home'}">{intl l="Home"}</a> <span class="divider">/</span></li>
<li><a href="{url path='admin/configuration'}">{intl l="Configuration"}</a> <span class="divider">/</span></li>
<li><a href="{url path='admin/configuration/variables'}">{intl l="System variables"}</a> <span class="divider">/</span></li>
<li>{intl l='Editing variable "%name"' name="{$NAME}"}</li>
</ul>
<div class="row-fluid">
<div class="span12 general-block-decorator">
<div class="row-fluid">
<div class="span12 title title-without-tabs">
{intl l="Edit variable $NAME"}
</div>
<div class="form-container">
<div class="form-horizontal span12">
<fieldset>
{form name="thelia.admin.variable.modification"}
<form method="POST" action="{url path='admin/configuration/variables/save-change'}" {form_enctype form=$form}>
{* Be sure to get the variable ID, even if the form could not be validated *}
<input type="hidden" name="variable_id" value="{$variable_id}" />
{include file="includes/inner-form-toolbar.html"}
{form_hidden_fields form=$form}
{form_field form=$form field='success_url'}
<input type="hidden" name="{$name}" value="{url path='admin/configuration/variables'}" />
{/form_field}
{* We do not allow creation of hidden variables *}
{form_field form=$form field='id'}
<input type="hidden" name="{$name}" value="{$value|htmlspecialchars}" />
{/form_field}
{form_field form=$form field='hidden'}
<input type="hidden" name="{$name}" value="0" />
{/form_field}
{form_field form=$form field='locale'}
<input type="hidden" name="{$name}" value="{$value|htmlspecialchars}" />
{/form_field}
{if #form_error}<div class="alert alert-block alert-error">#form_error_message</div>{/if}
<div class="control-group">
<label class="control-label">
{intl l='Name *'}
</label>
<div class="controls">
{form_field form=$form field='name'}
<span {if $error}class="error"{/if}>
<input type="text" required="required" name="{$name}" value="{$value|htmlspecialchars}" title="{intl l='Variable name'}" placeholder="{intl l='Variable name'}" class="input-block-level">
</span>
{/form_field}
</div>
</div>
<div class="control-group">
<label class="control-label">
{intl l='Value'}
</label>
<div class="controls">
{form_field form=$form field='value'}
<span {if $error}class="error"{/if}>
<input type="text" name="{$name}" value="{$value|htmlspecialchars}" title="{intl l='Variable value'}" placeholder="{intl l='Variable value'}" class="input-block-level">
</span>
{/form_field}
</div>
</div>
<div class="control-group">
<label class="control-label">
{intl l='Secured'}
</label>
<div class="controls">
{form_field form=$form field='value'}
<span {if $error}class="error"{/if}>
<label class="checkbox">
<input type="checkbox" name="{$name}" value="1" {if $value == 1}checked="checked"{/if}>
{intl l="Prevent variable modification or deletion, except for super-admin"}
</label>
</span>
{/form_field}
</div>
</div>
{include file="includes/standard-description-form-fields.html"}
</form>
{/form}
</fieldset>
</div>
</div>
</div>
</div>
</div>
{/loop}
{elseloop rel="config_edit"}
<div class="row-fluid">
<div class="span12">
<div class="alert alert-error">
{intl l="Sorry, variable ID=$variable_id was not found."}
</div>
</div>
</div>
{/elseloop}
</div>
</div>
{include file='includes/js.inc.html'}
{include file='includes/footer.inc.html'}

View File

@@ -1,6 +1,6 @@
{check_auth context="admin" roles="ADMIN" permissions="admin.configuration.variables.view" login_tpl="/admin/login"} {check_auth context="admin" roles="ADMIN" permissions="admin.configuration.variables.view" login_tpl="admin/login"}
{$page_title={intl l='Configuration'}} {$page_title={intl l='Thelia System Variables'}}
{include file='includes/header.inc.html'} {include file='includes/header.inc.html'}
@@ -8,20 +8,26 @@
<div id="wrapper" class="container"> <div id="wrapper" class="container">
{module_include location='config_top'} <ul class="breadcrumb">
<li><a href="{url path='admin/home'}">{intl l="Home"}</a> <span class="divider">/</span></li>
<li><a href="{url path='admin/configuration'}">{intl l="Configuration"}</a> <span class="divider">/</span></li>
<li>{intl l="System variables"}</li>
</ul>
{module_include location='variables_top'}
<h2>{intl l="Thelia system variables configuration"}</h2> <h2>{intl l="Thelia system variables configuration"}</h2>
<div class="row-fluid"> <div class="row-fluid">
<div class="span6"> <div class="span12">
<form> <form action="{url path='admin/configuration/variables/change-values'}" method="post">
<div class="general-block-decorator"> <div class="general-block-decorator">
<table class="table table-striped table-condensed table-left-aligned"> <table class="table table-striped table-condensed table-left-aligned">
<caption> <caption>
{intl l='Thelia system variables'} {intl l='Thelia system variables'}
{loop type="auth" name="can_create" context="admin" roles="ADMIN" permissions="admin.category.create"} {loop type="auth" name="can_create" context="admin" roles="ADMIN" permissions="admin.configuration.variables.create"}
<a class="btn btn-primary action-btn" title="{intl l='Add a new variable'}" href="#"> <a class="btn btn-primary action-btn" title="{intl l='Add a new variable'}" href="#add_variable_dialog" data-toggle="modal">
<i class="icon-plus-sign icon-white"></i> <i class="icon-plus-sign icon-white"></i>
</a> </a>
<button class="btn btn-primary action-btn" title="{intl l='Save chages'}">{intl l='Save changes'} <i class="icon icon-white icon-ok"></i></button> <button class="btn btn-primary action-btn" title="{intl l='Save chages'}">{intl l='Save changes'} <i class="icon icon-white icon-ok"></i></button>
@@ -32,6 +38,9 @@
<th>{intl l="Purpose"}</th> <th>{intl l="Purpose"}</th>
<th>{intl l="Name"}</th> <th>{intl l="Name"}</th>
<th>{intl l="Value"}</th> <th>{intl l="Value"}</th>
{module_include location='variables_table_header'}
<th>&nbsp;</th> <th>&nbsp;</th>
</tr> </tr>
{loop name="config" type="config" hidden="0" secured="*" backend_context="1"} {loop name="config" type="config" hidden="0" secured="*" backend_context="1"}
@@ -42,14 +51,25 @@
{if $SECURED} {if $SECURED}
{$VALUE} {$VALUE}
{else} {else}
<input type="text" name="value" value="{$VALUE|htmlspecialchars}" /> <input id="cancelable_edit_{$ID}" class="js-edit" data-id="{$ID}" type="text" name="variable[{$ID}]" value="{$VALUE|htmlspecialchars}" />
{/if} {/if}
</td> </td>
<td>
{module_include location='variables_table_row'}
<td class="actions">
{if ! $SECURED} {if ! $SECURED}
{loop type="auth" name="can_delete" context="admin" roles="ADMIN" permissions="admin.configuration.variables.delete"} <div class="btn-group">
<a class="btn btn-mini config-delete" title="{intl l='Delete this configuration variable'}" href="{url path='/admin/configuration/variables/delete' id="$ID"}"><i class="icon-trash"></i></a> <a class="btn btn-mini cancel-edit" id="cancel_edit_btn_{$ID}" data-id="{$ID}" title="{intl l='Cancel changes and revert to original value'}" href="#"><i class="icon-remove-circle"></i></a>
{/loop}
{loop type="auth" name="can_change" context="admin" roles="ADMIN" permissions="admin.configuration.variables.change"}
<a class="btn btn-mini config-change" title="{intl l='Change this variable'}" href="{url path='admin/configuration/variables/change' variable_id="$ID"}"><i class="icon-edit"></i></a>
{/loop}
{loop type="auth" name="can_delete" context="admin" roles="ADMIN" permissions="admin.configuration.variables.delete"}
<a class="btn btn-mini config-delete" title="{intl l='Delete this configuration variable'}" href="{url path='admin/configuration/variables/delete' id="$ID"}"><i class="icon-trash"></i></a>
{/loop}
</div>
{/if} {/if}
</td> </td>
</tr> </tr>
@@ -59,19 +79,160 @@
</form> </form>
</div> </div>
</div> </div>
{module_include location='variables_bottom'}
</div> </div>
</div> </div>
{* Adding a new variable *}
<div class="modal hide fade" id="add_variable_dialog" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h3>{intl l="Create a new variable"}</h3>
</div>
{form name="thelia.admin.variable.creation"}
<form method="POST" action="{url path='admin/configuration/variables/create'}" {form_enctype form=$form}>
{form_hidden_fields form=$form}
{form_field form=$form field='success_url'}
{* on success, redirect to the edition page, _ID_ is replaced with the created variable ID, see controller *}
<input type="hidden" name="{$name}" value="{url path='admin/configuration/variables/change' variable_id='_ID_'}" />
{/form_field}
<div class="modal-body">
{if #form_error}<div class="alert alert-block alert-error" id="add_variable_dialog_error">#form_error_message</div>{/if}
<div class="control-group">
<label class="control-label">
{intl l='Name *'}
</label>
<div class="controls">
{form_field form=$form field='name'}
<span {if $error}class="error"{/if}>
<input type="text" required="required" name="{$name}" value="{$value}" title="{intl l='Variable name'}" placeholder="{intl l='Variable name'}" class="input-block-level">
</span>
{/form_field}
</div>
</div>
<div class="control-group">
<label class="control-label">
{intl l='Value'}
</label>
<div class="controls">
{form_field form=$form field='value'}
<span {if $error}class="error"{/if}>
<input type="text" name="{$name}" value="{$value}" title="{intl l='Variable value'}" placeholder="{intl l='Variable value'}" class="input-block-level">
</span>
{/form_field}
</div>
</div>
<div class="control-group">
<label class="control-label">
{intl l='Purpose *'}
</label>
<div class="controls">
{loop type="lang" name="default-lang" default_only="1"}
{form_field form=$form field='locale'}
<input type="hidden" name="{$name}" value="{$LOCALE}" />
{/form_field}
<div class="input-append input-block-level">
{form_field form=$form field='title'}
<span {if $error}class="error"{/if}>
<input type="text" required="required" name="{$name}" value="{$value}" title="{intl l='Variable purpose'}" placeholder="{intl l='Variable purpose'}" class="input-block-level">
</span>
{/form_field}
<span class="add-on"><img src="{image file="assets/img/flags/{$CODE}.gif"}" alt="{intl l=$TITLE}" /></span>
</div>
<div class="help-block">{intl l="Enter here the variable purpose in the default language ($TITLE)"}</div>
{/loop}
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn" data-dismiss="modal" aria-hidden="true">{intl l="Cancel"}</button>
<button type="submit" class="btn btn-primary">{intl l="Create this variable"}</button>
</div>
</form>
{/form}
</div>
{include file='includes/js.inc.html'} {include file='includes/js.inc.html'}
<script> <script>
$(function() { $(function() {
// Variable delete confirmation
$('a.config-delete').click(function(ev) { $('a.config-delete').click(function(ev) {
if (! confirm("{intl l='Do you really want to delete this variable ?'}")) { if (! confirm("{intl l='Do you really want to delete this variable ?'}")) {
ev.preventDefault(); ev.preventDefault();
} }
} });
)})
{* display the form creation dialog if it contains errors *}
{form name="thelia.admin.variable.creation"}
{if #form_error}
$('#add_variable_dialog').modal();
{/if}
{/form}
{* Always reset create dialog on close *}
$('#add_variable_dialog').on('hidden',function() {
// Hide error message
$('#add_variable_dialog_error').remove();
// Clear error status
$("#add_variable_dialog .error").removeClass('error');
// Empty field values
$("#add_variable_dialog input[type=text]").val('');
});
// Edition canceling management
$('.cancel-edit').each(function() {
var zis = $(this);
var field = $('#cancelable_edit_' + $(this).data('id'));
zis.addClass('disabled');
zis.data('original-value', field.val());
zis.click(function(ev) {
if (!zis.is('.disabled')) {
zis.addClass('disabled');
field.val(zis.data('original-value'));
}
ev.preventDefault();
});
})
$('.js-edit').keyup(function() {
$('#cancel_edit_btn_' + $(this).data('id')).removeClass('disabled');
});
});
</script> </script>
{include file='includes/footer.inc.html'} {include file='includes/footer.inc.html'}