diff --git a/composer.json b/composer.json index 09aa606b5..47be312f6 100755 --- a/composer.json +++ b/composer.json @@ -9,7 +9,6 @@ }, "require":{ "php": ">=5.4", - "ezyang/htmlpurifier": "dev-master", "ircmaxell/password-compat": "dev-master", "propel/propel": "dev-master", "psr/log" : "1.0", @@ -41,7 +40,8 @@ }, "require-dev" : { "phpunit/phpunit": "3.7.*", - "fzaninotto/faker": "dev-master" + "fzaninotto/faker": "dev-master", + "maximebf/debugbar": "1.*" }, "minimum-stability": "stable", "config" : { diff --git a/composer.lock b/composer.lock index a54fe3024..0215c3d0f 100755 --- a/composer.lock +++ b/composer.lock @@ -3,52 +3,9 @@ "This file locks the dependencies of your project to a known state", "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file" ], - "hash": "db69990b239a4056558bfd694115d01b", + "hash": "ba2f3e0943f00c7c3bf0c086bc611b0f", + "packages": [ - { - "name": "ezyang/htmlpurifier", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/ezyang/htmlpurifier.git", - "reference": "fac747bdbdba6aeaba4bed91ef49b2378c1798e4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/fac747bdbdba6aeaba4bed91ef49b2378c1798e4", - "reference": "fac747bdbdba6aeaba4bed91ef49b2378c1798e4", - "shasum": "" - }, - "require": { - "php": ">=5.2" - }, - "type": "library", - "autoload": { - "psr-0": { - "HTMLPurifier": "library/" - }, - "files": [ - "library/HTMLPurifier.composer.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL" - ], - "authors": [ - { - "name": "Edward Z. Yang", - "email": "admin@htmlpurifier.org", - "homepage": "http://ezyang.com" - } - ], - "description": "Standards compliant HTML filter written in PHP", - "homepage": "http://htmlpurifier.org/", - "keywords": [ - "html" - ], - "time": "2013-08-18 02:27:26" - }, { "name": "imagine/imagine", "version": "dev-master", @@ -1662,6 +1619,55 @@ ], "time": "2013-08-29 19:11:59" }, + { + "name": "maximebf/debugbar", + "version": "1.5.1", + "source": { + "type": "git", + "url": "https://github.com/maximebf/php-debugbar.git", + "reference": "37dccc40da52bf9f85571c30cf302da696db0d05" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/37dccc40da52bf9f85571c30cf302da696db0d05", + "reference": "37dccc40da52bf9f85571c30cf302da696db0d05", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "psr/log": "~1.0" + }, + "require-dev": { + "php": ">=5.3.0" + }, + "suggest": { + "kriswallsmith/assetic": "The best way to manage assets", + "monolog/monolog": "Log using Monolog" + }, + "type": "library", + "autoload": { + "psr-0": { + "DebugBar": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Maxime Bouroumeau-Fuseau", + "email": "maxime.bouroumeau@gmail.com", + "homepage": "http://maximebf.com" + } + ], + "description": "Debug bar in the browser for php application", + "homepage": "https://github.com/maximebf/php-debugbar", + "keywords": [ + "debug" + ], + "time": "2013-08-17 02:02:49" + }, { "name": "phpunit/php-code-coverage", "version": "1.2.12", @@ -2035,7 +2041,6 @@ ], "minimum-stability": "stable", "stability-flags": { - "ezyang/htmlpurifier": 20, "ircmaxell/password-compat": 20, "propel/propel": 20, "kriswallsmith/assetic": 20, diff --git a/core/lib/Thelia/Action/Category.php b/core/lib/Thelia/Action/Category.php index 1b0568cbe..7b7608dc9 100755 --- a/core/lib/Thelia/Action/Category.php +++ b/core/lib/Thelia/Action/Category.php @@ -51,6 +51,8 @@ class Category extends BaseAction implements EventSubscriberInterface $event->getParent(), $event->getLocale() ); + + $event->setCategory($category); } public function update(CategoryChangeEvent $event) diff --git a/core/lib/Thelia/Command/Skeleton/Module/Class.php b/core/lib/Thelia/Command/Skeleton/Module/Class.php index c9c7109ac..c4c90aa60 100755 --- a/core/lib/Thelia/Command/Skeleton/Module/Class.php +++ b/core/lib/Thelia/Command/Skeleton/Module/Class.php @@ -25,7 +25,7 @@ namespace %%NAMESPACE%%; use Thelia\Module\BaseModule; -class Class extends BaseModule +class %%CLASSNAME%% extends BaseModule { /** * YOU HAVE TO IMPLEMENT HERE ABSTRACT METHODD FROM BaseModule Class diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index 974de091c..e4cf3a475 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -34,6 +34,7 @@ + @@ -47,7 +48,10 @@
- + + + + @@ -79,7 +83,6 @@ - %kernel.environment% @@ -98,7 +101,7 @@ - + diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index 2257a9459..e8262117b 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -25,14 +25,40 @@ - + - Thelia\Controller\Admin\CategoryController::indexAction + Thelia\Controller\Admin\CategoryController::defaultAction - - Thelia\Controller\Admin\CategoryController::processAction + + + + Thelia\Controller\Admin\CategoryController::defaultAction + + + + Thelia\Controller\Admin\CategoryController::createAction + + + + Thelia\Controller\Admin\CategoryController::changeAction + + + + Thelia\Controller\Admin\CategoryController::saveChangeAction + + + + Thelia\Controller\Admin\CategoryController::toggleOnlineAction + + + + Thelia\Controller\Admin\CategoryController::deleteAction + + + + Thelia\Controller\Admin\CategoryController::updatePositionAction @@ -105,6 +131,10 @@ Thelia\Controller\Admin\CurrencyController::setDefaultAction + + Thelia\Controller\Admin\CurrencyController::updatePositionAction + + Thelia\Controller\Admin\CurrencyController::updateRatesAction @@ -113,17 +143,20 @@ Thelia\Controller\Admin\CurrencyController::deleteAction + + Thelia\Controller\Admin\CurrencyController::updatePositionAction + + + + Thelia\Controller\Admin\AttributeController::defaultAction - - - - Thelia\Controller\Admin\CurrencyController::updatePositionAction + + Thelia\Controller\Admin\AttributeController::updateAction - diff --git a/core/lib/Thelia/Config/Resources/routing/front.xml b/core/lib/Thelia/Config/Resources/routing/front.xml index f8b156946..aeff55d7c 100755 --- a/core/lib/Thelia/Config/Resources/routing/front.xml +++ b/core/lib/Thelia/Config/Resources/routing/front.xml @@ -60,4 +60,11 @@ cart + + + Thelia\Controller\Front\DeliveryController::select + \d+ + + + diff --git a/core/lib/Thelia/Controller/Admin/AttributeController.php b/core/lib/Thelia/Controller/Admin/AttributeController.php index d2c1ea351..a6dd05c89 100644 --- a/core/lib/Thelia/Controller/Admin/AttributeController.php +++ b/core/lib/Thelia/Controller/Admin/AttributeController.php @@ -43,7 +43,7 @@ use Thelia\Form\MessageCreationForm; class AttributeController extends BaseAdminController { /** - * The default action is displaying the messages list. + * The default action is displaying the attributes list. * * @return Symfony\Component\HttpFoundation\Response the response */ @@ -51,7 +51,13 @@ class AttributeController extends BaseAdminController if (null !== $response = $this->checkAuth("admin.configuration.attributes.view")) return $response; - return $this->render('product_attributes'); + return $this->render('product-attributes'); } + public function updateAction() { + + if (null !== $response = $this->checkAuth("admin.configuration.attributes.update")) return $response; + + return $this->render('product-attributes-edit'); + } } \ No newline at end of file diff --git a/core/lib/Thelia/Controller/Admin/BaseAdminController.php b/core/lib/Thelia/Controller/Admin/BaseAdminController.php index eab57394b..298cd0182 100755 --- a/core/lib/Thelia/Controller/Admin/BaseAdminController.php +++ b/core/lib/Thelia/Controller/Admin/BaseAdminController.php @@ -34,6 +34,9 @@ use Thelia\Core\Security\SecurityContext; use Thelia\Model\AdminLog; use Thelia\Model\Lang; use Thelia\Model\LangQuery; +use Thelia\Form\BaseForm; +use Thelia\Form\Exception\FormValidationException; +use Thelia\Log\Tlog; class BaseAdminController extends BaseController { @@ -66,7 +69,7 @@ class BaseAdminController extends BaseController } } catch (\Exception $ex) { - return new Response($this->errorPage($ex->getMessage())); + return $this->errorPage($ex->getMessage()); } return $this->pageNotFound(); @@ -92,7 +95,7 @@ class BaseAdminController extends BaseController protected function errorPage($message) { if ($message instanceof \Exception) { - $message = sprintf("Sorry, an error occured: %s", $message->getMessage()); + $message = sprintf($this->getTranslator()->trans("Sorry, an error occured: %msg"), array('msg' => $message->getMessage())); } return $this->render('general_error', array( @@ -123,7 +126,56 @@ class BaseAdminController extends BaseController // Generate the proper response $response = new Response(); - return $response->setContent($this->errorPage("Sorry, you're not allowed to perform this action")); + return $this->errorPage($this->getTranslator()->trans("Sorry, you're not allowed to perform this action")); + } + + /* + * Create the standard message displayed to the user when the form cannot be validated. + */ + protected function createStandardFormValidationErrorMessage(FormValidationException $exception) { + return $this->getTranslator()->trans( + "Please check your input: %error", + array( + '%error' => $exception->getMessage() + ) + ); + } + + /** + * Setup the error context when an error occurs in a action method. + * + * @param string $action the action that caused the error (category modification, variable creation, currency update, etc.) + * @param BaseForm $form the form where the error occured, or null if no form was involved + * @param string $error_message the error message + * @param Exception $exception the exception or null if no exception + */ + protected function setupFormErrorContext($action, $error_message, BaseForm $form = null, \Exception $exception = null) { + + if ($error_message !== false) { + + // Log the error message + Tlog::getInstance()->error( + $this->getTranslator()->trans( + "Error during %action process : %error. Exception was %exc", + array( + '%action' => $action, + '%error' => $error_message, + '%exc' => $exception != null ? $exception->getMessage() : 'no exception' + ) + ) + ); + + if ($form != null) { + // Mark the form as errored + $form->setErrorMessage($error_message); + + // Pass it to the parser context + $this->getParserContext()->addForm($form); + } + + // Pass the error message to the parser. + $this->getParserContext()->setGeneralError($error_message); + } } /** @@ -261,7 +313,7 @@ class BaseAdminController extends BaseController } 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."); + return $this->errorPage($this->getTranslator()->trans("Sorry, you are not allowed to perform this action.")); } } } diff --git a/core/lib/Thelia/Controller/Admin/CategoryController.php b/core/lib/Thelia/Controller/Admin/CategoryController.php index 6cba34e39..5eca91cf9 100755 --- a/core/lib/Thelia/Controller/Admin/CategoryController.php +++ b/core/lib/Thelia/Controller/Admin/CategoryController.php @@ -34,226 +34,305 @@ use Thelia\Core\Event\CategoryToggleVisibilityEvent; use Thelia\Core\Event\CategoryChangePositionEvent; use Thelia\Form\CategoryDeletionForm; use Thelia\Model\Lang; +use Thelia\Core\Translation\Translator; +use Thelia\Core\Event\CategoryUpdatePositionEvent; +use Thelia\Model\CategoryQuery; +use Thelia\Form\CategoryModificationForm; class CategoryController extends BaseAdminController { - protected function createNewCategory($args) - { - try { - $categoryCreationForm = new CategoryCreationForm($this->getRequest()); - - $form = $this->validateForm($categoryCreationForm, "POST"); - - $data = $form->getData(); - - $categoryCreateEvent = new CategoryCreateEvent( - $data["title"], - $data["parent"], - $data["locale"] - ); - - $this->dispatch(TheliaEvents::CATEGORY_CREATE, $categoryCreateEvent); - - $category = $categoryCreateEvent->getCreatedCategory(); - - $this->adminLogAppend(sprintf("Category %s (ID %s) created", $category->getTitle(), $category->getId())); - - // Substitute _ID_ in the URL with the ID of the created category - $successUrl = str_replace('_ID_', $category->getId(), $categoryCreationForm->getSuccessUrl()); - - // Redirect to the success URL - $this->redirect($successUrl); - } - catch (FormValidationException $e) { - $categoryCreationForm->setErrorMessage($e->getMessage()); - $this->getParserContext()->addForm($categoryCreationForm); - } - catch (Exception $e) { - Tlog::getInstance()->error(sprintf("Failed to create category: %s", $e->getMessage())); - $this->getParserContext()->setGeneralError($e->getMessage()); - } - - // At this point, the form has error, and should be redisplayed. - return $this->render('categories', $args); + /** + * Render the categories list, ensuring the sort order is set. + * + * @return Symfony\Component\HttpFoundation\Response the response + */ + protected function renderList() { + return $this->render('categories', $this->getTemplateArgs()); } - protected function editCategory($args) - { - if (null !== $response = $this->checkAuth("admin.category.edit")) return $response; - - return $this->render('edit_category', $args); - } - - protected function deleteCategory($args) - { - try { - $categoryDeletionForm = new CategoryDeletionForm($this->getRequest()); - - $data = $this->validateForm($categoryDeletionForm, "POST")->getData(); - - $categoryDeleteEvent = new CategoryDeleteEvent($data['category_id']); - - $this->dispatch(TheliaEvents::CATEGORY_DELETE, $categoryDeleteEvent); - - $category = $categoryDeleteEvent->getDeletedCategory(); - - $this->adminLogAppend(sprintf("Category %s (ID %s) deleted", $category->getTitle(), $category->getId())); - - // Substitute _ID_ in the URL with the ID of the created category - $successUrl = str_replace('_ID_', $categoryDeleteEvent->getDeletedCategory()->getParent(), $categoryDeletionForm->getSuccessUrl()); - - // Redirect to the success URL - $this->redirect($successUrl); - } - catch (FormValidationException $e) { - $categoryDeletionForm->setErrorMessage($e->getMessage()); - $this->getParserContext()->addForm($categoryDeletionForm); - } - catch (Exception $e) { - Tlog::getInstance()->error(sprintf("Failed to delete category: %s", $e->getMessage())); - $this->getParserContext()->setGeneralError($e->getMessage()); - } - - // At this point, something was wrong, category was not deleted. Display parent category list - return $this->render('categories', $args); - } - - protected function browseCategory($args) - { - if (null !== $response = $this->checkAuth("admin.catalog.view")) return $response; - - return $this->render('categories', $args); - } - - protected function visibilityToggle($args) - { - $event = new CategoryToggleVisibilityEvent($this->getRequest()->get('category_id', 0)); - - $this->dispatch(TheliaEvents::CATEGORY_TOGGLE_VISIBILITY, $event); - - return $this->nullResponse(); - } - - protected function changePosition($args) - { - $request = $this->getRequest(); - - $event = new CategoryChangePositionEvent( - $request->get('category_id', 0), - CategoryChangePositionEvent::POSITION_ABSOLUTE, - $request->get('position', null) - ); - - $this->dispatch(TheliaEvents::CATEGORY_CHANGE_POSITION, $event); - - return $this->render('categories', $args); - } - - protected function positionDown($args) - { - $event = new CategoryChangePositionEvent( - $this->getRequest()->get('category_id', 0), - CategoryChangePositionEvent::POSITION_DOWN - ); - - $this->dispatch(TheliaEvents::CATEGORY_CHANGE_POSITION, $event); - - return $this->render('categories', $args); - } - - protected function positionUp($args) - { - $event = new CategoryChangePositionEvent( - $this->getRequest()->get('category_id', 0), - CategoryChangePositionEvent::POSITION_UP - ); - - $this->dispatch(TheliaEvents::CATEGORY_CHANGE_POSITION, $event); - - return $this->render('categories', $args); - } - - public function indexAction() - { - return $this->processAction(); - } - - public function processAction() - { - // Get the current action - $action = $this->getRequest()->get('action', 'browse'); + protected function getTemplateArgs() { // Get the category ID - $id = $this->getRequest()->get('id', 0); + $category_id = $this->getRequest()->get('category_id', 0); - // Find the current order + // Find the current category order $category_order = $this->getRequest()->get( 'order', $this->getSession()->get('admin.category_order', 'manual') ); - // Find the current edit language ID - $edition_language = $this->getRequest()->get( - 'edition_language', - $this->getSession()->get('admin.edition_language', Lang::getDefaultLanguage()->getId()) - ); - $args = array( - 'action' => $action, - 'current_category_id' => $id, + 'current_category_id' => $category_id, 'category_order' => $category_order, - 'edition_language' => $edition_language, ); // Store the current sort order in session $this->getSession()->set('admin.category_order', $category_order); - // Store the current edition language in session - $this->getSession()->set('admin.edition_language', $edition_language); + return $args; + } + + /** + * The default action is displaying the categories list. + * + * @return Symfony\Component\HttpFoundation\Response the response + */ + public function defaultAction() { + + if (null !== $response = $this->checkAuth("admin.categories.view")) return $response; + + return $this->renderList(); + } + + /** + * Create a new category object + * + * @return Symfony\Component\HttpFoundation\Response the response + */ + public function createAction() { + + // Check current user authorization + if (null !== $response = $this->checkAuth("admin.categories.create")) return $response; + + $error_msg = false; + + // Create the Creation Form + $creationForm = new CategoryCreationForm($this->getRequest()); try { - switch ($action) { - case 'browse' : // Browse categories - return $this->browseCategory($args); + // Validate the form, create the CategoryCreation event and dispatch it. + $form = $this->validateForm($creationForm, "POST"); - case 'create' : // Create a new category + $data = $form->getData(); - return $this->createNewCategory($args); + $createEvent = new CategoryCreateEvent( + $data["title"], + $data["parent"], + $data["locale"] + ); - case 'edit' : // Edit an existing category + $this->dispatch(TheliaEvents::CATEGORY_CREATE, $createEvent); - return $this->editCategory($args); + if (! $createEvent->hasCategory()) throw new \LogicException($this->getTranslator()->trans("No category was created.")); - case 'delete' : // Delete an existing category + $createdObject = $createEvent->getCategory(); - return $this->deleteCategory($args); + // Log category creation + $this->adminLogAppend(sprintf("Category %s (ID %s) created", $createdObject->getTitle(), $createdObject->getId())); - case 'visibilityToggle' : // Toggle visibility + // Substitute _ID_ in the URL with the ID of the created object + $successUrl = str_replace('_ID_', $createdObject->getId(), $creationForm->getSuccessUrl()); - return $this->visibilityToggle($id); - - case 'changePosition' : // Change position - - return $this->changePosition($args); - - case 'positionUp' : // Move up category - - return $this->positionUp($args); - - case 'positionDown' : // Move down category - - return $this->positionDown($args); - } + // Redirect to the success URL + $this->redirect($successUrl); } - catch (AuthorizationException $ex) { - return $this->errorPage($ex->getMessage()); + catch (FormValidationException $ex) { + // Form cannot be validated + $error_msg = $this->createStandardFormValidationErrorMessage($ex); } - catch (AuthenticationException $ex) { - return $this->errorPage($ex->getMessage()); + catch (\Exception $ex) { + // Any other error + $error_msg = $ex->getMessage(); } - // We did not recognized the action -> return a 404 page - return $this->pageNotFound(); + $this->setupFormErrorContext("category creation", $error_msg, $creationForm, $ex); + + // At this point, the form has error, and should be redisplayed. + return $this->renderList(); } -} + + /** + * Load a category 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.categories.update")) return $response; + + // Load the category object + $category = CategoryQuery::create() + ->joinWithI18n($this->getCurrentEditionLocale()) + ->findOneById($this->getRequest()->get('category_id')); + + if ($category != null) { + + // Prepare the data that will hydrate the form + $data = array( + 'id' => $category->getId(), + 'locale' => $category->getLocale(), + 'title' => $category->getTitle(), + 'chapo' => $category->getChapo(), + 'description' => $category->getDescription(), + 'postscriptum' => $category->getPostscriptum(), + 'parent' => $category->getParent(), + 'visible' => $category->getVisible() ? true : false, + 'url' => $category->getUrl($this->getCurrentEditionLocale()) + // tbc !!! + ); + + // Setup the object form + $changeForm = new CategoryModificationForm($this->getRequest(), "form", $data); + + // Pass it to the parser + $this->getParserContext()->addForm($changeForm); + } + + // Render the edition template. + return $this->render('category-edit', $this->getTemplateArgs()); + } + + /** + * Save changes on a modified category object, and either go back to the category 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.categories.update")) return $response; + + $error_msg = false; + + // Create the form from the request + $changeForm = new CategoryModificationForm($this->getRequest()); + + // Get the category ID + $category_id = $this->getRequest()->get('category_id'); + + try { + + // Check the form against constraints violations + $form = $this->validateForm($changeForm, "POST"); + + // Get the form field values + $data = $form->getData(); + + $changeEvent = new CategoryUpdateEvent($data['id']); + + // Create and dispatch the change event + $changeEvent + ->setCategoryName($data['name']) + ->setLocale($data["locale"]) + ->setSymbol($data['symbol']) + ->setCode($data['code']) + ->setRate($data['rate']) + ; + + $this->dispatch(TheliaEvents::CATEGORY_UPDATE, $changeEvent); + + if (! $createEvent->hasCategory()) throw new \LogicException($this->getTranslator()->trans("No category was updated.")); + + // Log category modification + $changedObject = $changeEvent->getCategory(); + + $this->adminLogAppend(sprintf("Category %s (ID %s) modified", $changedObject->getTitle(), $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->redirectToRoute( + "admin.categories.update", + array('category_id' => $category_id) + ); + } + + // 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("category modification", $error_msg, $changeForm, $ex); + + // At this point, the form has errors, and should be redisplayed. + return $this->render('category-edit', array('category_id' => $category_id)); + } + + /** + * Online status toggle category + */ + public function setToggleVisibilityAction() { + // Check current user authorization + if (null !== $response = $this->checkAuth("admin.categories.update")) return $response; + + $changeEvent = new CategoryUpdateEvent($this->getRequest()->get('category_id', 0)); + + // Create and dispatch the change event + $changeEvent->setIsDefault(true); + + try { + $this->dispatch(TheliaEvents::CATEGORY_SET_DEFAULT, $changeEvent); + } + catch (\Exception $ex) { + // Any error + return $this->errorPage($ex); + } + + $this->redirectToRoute('admin.categories.default'); + } + + /** + * Update categoryposition + */ + public function updatePositionAction() { + // Check current user authorization + if (null !== $response = $this->checkAuth("admin.categories.update")) return $response; + + try { + $mode = $this->getRequest()->get('mode', null); + + if ($mode == 'up') + $mode = CategoryUpdatePositionEvent::POSITION_UP; + else if ($mode == 'down') + $mode = CategoryUpdatePositionEvent::POSITION_DOWN; + else + $mode = CategoryUpdatePositionEvent::POSITION_ABSOLUTE; + + $position = $this->getRequest()->get('position', null); + + $event = new CategoryUpdatePositionEvent( + $this->getRequest()->get('category_id', null), + $mode, + $this->getRequest()->get('position', null) + ); + + $this->dispatch(TheliaEvents::CATEGORY_UPDATE_POSITION, $event); + } + catch (\Exception $ex) { + // Any error + return $this->errorPage($ex); + } + + $this->redirectToRoute('admin.categories.default'); + } + + /** + * Delete a category object + * + * @return Symfony\Component\HttpFoundation\Response the response + */ + public function deleteAction() { + + // Check current user authorization + if (null !== $response = $this->checkAuth("admin.categories.delete")) return $response; + + // Get the category id, and dispatch the deleted request + $event = new CategoryDeleteEvent($this->getRequest()->get('category_id')); + + $this->dispatch(TheliaEvents::CATEGORY_DELETE, $event); + + if ($event->hasCategory()) + $this->adminLogAppend(sprintf("Category %s (ID %s) deleted", $event->getCategory()->getTitle(), $event->getCategory()->getId())); + + $this->redirectToRoute('admin.categories.default'); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Controller/Admin/ConfigController.php b/core/lib/Thelia/Controller/Admin/ConfigController.php index b84368c2f..6d1a04b05 100644 --- a/core/lib/Thelia/Controller/Admin/ConfigController.php +++ b/core/lib/Thelia/Controller/Admin/ConfigController.php @@ -108,6 +108,8 @@ class ConfigController extends BaseAdminController $this->dispatch(TheliaEvents::CONFIG_CREATE, $createEvent); + if (! $createEvent->hasConfig()) throw new \LogicException($this->getTranslator()->trans("No variable was created.")); + $createdObject = $createEvent->getConfig(); // Log config creation @@ -121,26 +123,14 @@ class ConfigController extends BaseAdminController } catch (FormValidationException $ex) { // Form cannot be validated - $message = sprintf("Please check your input: %s", $ex->getMessage()); + $message = $this->createStandardFormValidationErrorMessage($ex); } catch (\Exception $ex) { // Any other error - $message = sprintf("Sorry, an error occured: %s", $ex->getMessage()); + $message = $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) - ; - } + $this->setupFormErrorContext("variable creation", $message, $creationForm, $ex); // At this point, the form has error, and should be redisplayed. return $this->renderList(); @@ -231,6 +221,8 @@ class ConfigController extends BaseAdminController $this->dispatch(TheliaEvents::CONFIG_UPDATE, $changeEvent); + if (! $changeEvent->hasConfig()) throw new \LogicException($this->getTranslator()->trans("No variable was updated.")); + // Log config modification $changedObject = $changeEvent->getConfig(); @@ -250,27 +242,15 @@ class ConfigController extends BaseAdminController $this->redirect($changeForm->getSuccessUrl()); } catch (FormValidationException $ex) { - // Invalid data entered - $message = sprintf("Please check your input: %s", $ex->getMessage()); + // Form cannot be validated + $message = $this->createStandardFormValidationErrorMessage($ex); } catch (\Exception $ex) { // Any other error - $message = sprintf("Sorry, an error occured: %s", $ex->getMessage()); + $message = $ex->getMessage(); } - if ($message !== false) { - // Log error message - Tlog::getInstance()->error(sprintf("Error during variable modification 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) - ; - } + $this->setupFormErrorContext("variable edition", $message, $changeForm, $ex); // At this point, the form has errors, and should be redisplayed. return $this->render('variable-edit', array('variable_id' => $variable_id)); @@ -314,6 +294,9 @@ class ConfigController extends BaseAdminController $this->dispatch(TheliaEvents::CONFIG_DELETE, $event); + if ($event->hasConfig()) + $this->adminLogAppend(sprintf("Variable %s (ID %s) modified", $event->getConfig()->getName(), $event->getConfig()->getId())); + $this->redirectToRoute('admin.configuration.variables.default'); } } \ No newline at end of file diff --git a/core/lib/Thelia/Controller/Admin/CurrencyController.php b/core/lib/Thelia/Controller/Admin/CurrencyController.php index 56acfb89d..c6f5afdc3 100644 --- a/core/lib/Thelia/Controller/Admin/CurrencyController.php +++ b/core/lib/Thelia/Controller/Admin/CurrencyController.php @@ -108,10 +108,12 @@ class CurrencyController extends BaseAdminController $this->dispatch(TheliaEvents::CURRENCY_CREATE, $createEvent); + if (! $createEvent->hasCurrency()) throw new \LogicException($this->getTranslator()->trans("No currency was created.")); + $createdObject = $createEvent->getCurrency(); // Log currency creation - $this->adminLogAppend(sprintf("Variable %s (ID %s) created", $createdObject->getName(), $createdObject->getId())); + $this->adminLogAppend(sprintf("Currency %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()); @@ -121,26 +123,14 @@ class CurrencyController extends BaseAdminController } catch (FormValidationException $ex) { // Form cannot be validated - $error_msg = sprintf("Please check your input: %s", $ex->getMessage()); + $error_msg = $this->createStandardFormValidationErrorMessage($ex); } catch (\Exception $ex) { // Any other error - $error_msg = $ex; + $error_msg = $ex->getMessage(); } - if ($error_msg !== false) { - // An error has been detected: log it - Tlog::getInstance()->error(sprintf("Error during currency creation process : %s. Exception was %s", $error_msg, $ex->getMessage())); - - // Mark the form as errored - $creationForm->setErrorMessage($error_msg); - - // Pass it to the parser, along with the error currency - $this->getParserContext() - ->addForm($creationForm) - ->setGeneralError($error_msg) - ; - } + $this->setupFormErrorContext("currency creation", $error_msg, $creationForm, $ex); // At this point, the form has error, and should be redisplayed. return $this->renderList(); @@ -223,10 +213,12 @@ class CurrencyController extends BaseAdminController $this->dispatch(TheliaEvents::CURRENCY_UPDATE, $changeEvent); + if (! $changeEvent->hasCurrency()) throw new \LogicException($this->getTranslator()->trans("No currency was updated.")); + // Log currency modification $changedObject = $changeEvent->getCurrency(); - $this->adminLogAppend(sprintf("Variable %s (ID %s) modified", $changedObject->getName(), $changedObject->getId())); + $this->adminLogAppend(sprintf("Currency %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. @@ -241,27 +233,15 @@ class CurrencyController extends BaseAdminController $this->redirect($changeForm->getSuccessUrl()); } catch (FormValidationException $ex) { - // Invalid data entered - $error_msg = sprintf("Please check your input: %s", $ex->getMessage()); + // Form cannot be validated + $error_msg = $this->createStandardFormValidationErrorMessage($ex); } catch (\Exception $ex) { // Any other error - $error_msg = $ex; + $error_msg = $ex->getMessage(); } - if ($error_msg !== false) { - // Log error currency - Tlog::getInstance()->error(sprintf("Error during currency modification process : %s. Exception was %s", $error_msg, $ex->getMessage())); - - // Mark the form as errored - $changeForm->setErrorMessage($error_msg); - - // Pas the form and the error to the parser - $this->getParserContext() - ->addForm($changeForm) - ->setGeneralError($error_msg) - ; - } + $this->setupFormErrorContext("currency modification", $error_msg, $changeForm, $ex); // At this point, the form has errors, and should be redisplayed. return $this->render('currency-edit', array('currency_id' => $currency_id)); @@ -359,6 +339,9 @@ class CurrencyController extends BaseAdminController $this->dispatch(TheliaEvents::CURRENCY_DELETE, $event); + if ($event->hasCurrency()) + $this->adminLogAppend(sprintf("Currency %s (ID %s) modified", $event->getCurrency()->getName(), $event->getCurrency()->getId())); + $this->redirectToRoute('admin.configuration.currencies.default'); } } \ No newline at end of file diff --git a/core/lib/Thelia/Controller/Admin/MessageController.php b/core/lib/Thelia/Controller/Admin/MessageController.php index c024a5d34..00fcb17bd 100644 --- a/core/lib/Thelia/Controller/Admin/MessageController.php +++ b/core/lib/Thelia/Controller/Admin/MessageController.php @@ -42,6 +42,15 @@ use Thelia\Form\MessageCreationForm; */ class MessageController extends BaseAdminController { + /** + * Render the messages list + * + * @return Symfony\Component\HttpFoundation\Response the response + */ + protected function renderList() { + return $this->render('messages'); + } + /** * The default action is displaying the messages list. * @@ -51,7 +60,7 @@ class MessageController extends BaseAdminController if (null !== $response = $this->checkAuth("admin.configuration.messages.view")) return $response; - return $this->render('messages'); + return $this->renderList(); } /** @@ -66,7 +75,7 @@ class MessageController extends BaseAdminController $message = false; - // Create the Creation Form + // Create the creation Form $creationForm = new MessageCreationForm($this->getRequest()); try { @@ -87,10 +96,11 @@ class MessageController extends BaseAdminController $this->dispatch(TheliaEvents::MESSAGE_CREATE, $createEvent); + if (! $createEvent->hasMessage()) throw new \LogicException($this->getTranslator()->trans("No message was created.")); + $createdObject = $createEvent->getMessage(); - // Log message creation - $this->adminLogAppend(sprintf("Variable %s (ID %s) created", $createdObject->getName(), $createdObject->getId())); + $this->adminLogAppend(sprintf("Message %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()); @@ -100,26 +110,14 @@ class MessageController extends BaseAdminController } catch (FormValidationException $ex) { // Form cannot be validated - $message = sprintf("Please check your input: %s", $ex->getMessage()); + $message = $this->createStandardFormValidationErrorMessage($ex); } catch (\Exception $ex) { // Any other error - $message = sprintf("Sorry, an error occured: %s", $ex->getMessage()); + $message = $ex->getMessage(); } - if ($message !== false) { - // An error has been detected: log it - Tlog::getInstance()->error(sprintf("Error during message 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) - ; - } + $this->setupFormErrorContext("message modification", $message, $creationForm, $ex); // At this point, the form has error, and should be redisplayed. return $this->render('messages'); @@ -206,7 +204,8 @@ class MessageController extends BaseAdminController $this->dispatch(TheliaEvents::MESSAGE_UPDATE, $changeEvent); - // Log message modification + if (! $changeEvent->hasMessage()) throw new \LogicException($this->getTranslator()->trans("No message was updated.")); + $changedObject = $changeEvent->getMessage(); $this->adminLogAppend(sprintf("Variable %s (ID %s) modified", $changedObject->getName(), $changedObject->getId())); @@ -224,27 +223,15 @@ class MessageController extends BaseAdminController $this->redirect($changeForm->getSuccessUrl()); } catch (FormValidationException $ex) { - // Invalid data entered - $message = sprintf("Please check your input: %s", $ex->getMessage()); + // Form cannot be validated + $message = $this->createStandardFormValidationErrorMessage($ex); } catch (\Exception $ex) { // Any other error - $message = sprintf("Sorry, an error occured: %s", $ex->getMessage()); + $message = $ex->getMessage(); } - if ($message !== false) { - // Log error message - Tlog::getInstance()->error(sprintf("Error during message modification 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) - ; - } + $this->setupFormErrorContext("message modification", $message, $changeForm, $ex); // At this point, the form has errors, and should be redisplayed. return $this->render('message-edit', array('message_id' => $message_id)); @@ -265,6 +252,9 @@ class MessageController extends BaseAdminController $this->dispatch(TheliaEvents::MESSAGE_DELETE, $event); - $this->redirect(URL::getInstance()->adminViewUrl('messages')); + if ($event->hasMessage()) + $this->adminLogAppend(sprintf("Message %s (ID %s) modified", $event->getMessage()->getName(), $event->getMessage()->getId())); + + $this->redirectToRoute('admin.configuration.messages.default'); } } \ No newline at end of file diff --git a/core/lib/Thelia/Controller/Admin/SessionController.php b/core/lib/Thelia/Controller/Admin/SessionController.php index a377df208..d7385ad1b 100755 --- a/core/lib/Thelia/Controller/Admin/SessionController.php +++ b/core/lib/Thelia/Controller/Admin/SessionController.php @@ -73,32 +73,34 @@ class SessionController extends BaseAdminController // Redirect to the success URL return Redirect::exec($adminLoginForm->getSuccessUrl()); - } catch (ValidatorException $ex) { + + } + catch (FormValidationException $ex) { // Validation problem - $message = "Missing or invalid information. Please check your input."; - } catch (AuthenticationException $ex) { + $message = $this->createStandardFormValidationErrorMessage($ex); + } + catch (AuthenticationException $ex) { // Log authentication failure AdminLog::append(sprintf("Authentication failure for username '%s'", $authenticator->getUsername()), $request); - $message = "Login failed. Please check your username and password."; - } catch (\Exception $ex) { + $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); - $message = "Unable to process your request. Please try again.".$ex->getMessage(); + $message = $this->getTranslator()->trans( + "Unable to process your request. Please try again (%err).", + array("%err" => $ex->getMessage()) + ); } - // Store error information in the form - $adminLoginForm->setError(true); - $adminLoginForm->setErrorMessage($message); - - // Store the form name in session (see Form Smarty plugin to find usage of this parameter) - $this->getParserContext()->addForm($adminLoginForm); + $this->setupFormErrorContext("Login process", $message, $adminLoginForm, $ex); // Display the login form again return $this->render("login"); } -} +} \ No newline at end of file diff --git a/core/lib/Thelia/Controller/BaseController.php b/core/lib/Thelia/Controller/BaseController.php index 5fbcc56d2..e5b098f02 100755 --- a/core/lib/Thelia/Controller/BaseController.php +++ b/core/lib/Thelia/Controller/BaseController.php @@ -81,6 +81,17 @@ class BaseController extends ContainerAware return $this->container->get('event_dispatcher'); } + /** + * + * return the Translator + * + * @return mixed \Thelia\Core\Translation\Translator + */ + public function getTranslator() + { + return $this->container->get('thelia.translator'); + } + /** * Return the parser context, * diff --git a/core/lib/Thelia/Controller/Front/DeliveryController.php b/core/lib/Thelia/Controller/Front/DeliveryController.php new file mode 100644 index 000000000..ef84be6ab --- /dev/null +++ b/core/lib/Thelia/Controller/Front/DeliveryController.php @@ -0,0 +1,56 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Controller\Front; +use Thelia\Model\ModuleQuery; +use Thelia\Tools\URL; + + +/** + * Class DeliveryController + * @package Thelia\Controller\Front + * @author Manuel Raynaud + */ +class DeliveryController extends BaseFrontController +{ + public function select($delivery_id) + { + if ($this->getSecurityContext()->hasCustomerUser() === false) { + $this->redirect(URL::getInstance()->getIndexPage()); + } + + $request = $this->getRequest(); + + $deliveryModule = ModuleQuery::create() + ->filterById($delivery_id) + ->filterByActivate(1) + ->findOne() + ; + + if ($deliveryModule) { + $request->getSession()->setDelivery($delivery_id); + } else { + $this->pageNotFound(); + } + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/BaseToggleVisibilityEvent.php b/core/lib/Thelia/Core/Event/BaseToggleVisibilityEvent.php new file mode 100644 index 000000000..2dbd54374 --- /dev/null +++ b/core/lib/Thelia/Core/Event/BaseToggleVisibilityEvent.php @@ -0,0 +1,48 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; + + +class BaseToggleVisibilityEvent extends ActionEvent +{ + protected $object_id; + + protected $object; + + public function __construct($object_id) + { + $this->object_id = $object_id; + } + + public function getObjectId() + { + return $this->object_id; + } + + public function setObjectId($object_id) + { + $this->object_id = $object_id; + return $this; + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/CategoryCreateEvent.php b/core/lib/Thelia/Core/Event/CategoryCreateEvent.php index f4d5a45ee..0a6b79269 100644 --- a/core/lib/Thelia/Core/Event/CategoryCreateEvent.php +++ b/core/lib/Thelia/Core/Event/CategoryCreateEvent.php @@ -25,12 +25,11 @@ namespace Thelia\Core\Event; use Thelia\Model\Category; -class CategoryCreateEvent extends ActionEvent +class CategoryCreateEvent extends CategoryEvent { protected $title; protected $parent; protected $locale; - protected $created_category; public function __construct($title, $parent, $locale) { @@ -47,6 +46,7 @@ class CategoryCreateEvent extends ActionEvent public function setTitle($title) { $this->title = $title; + return $this; } public function getParent() @@ -57,6 +57,7 @@ class CategoryCreateEvent extends ActionEvent public function setParent($parent) { $this->parent = $parent; + return $this; } public function getLocale() @@ -67,15 +68,6 @@ class CategoryCreateEvent extends ActionEvent public function setLocale($locale) { $this->locale = $locale; + return $this; } - - public function getCreatedCategory() - { - return $this->created_category; - } - - public function setCreatedCategory(Category $created_category) - { - $this->created_category = $created_category; - } -} +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/CategoryDeleteEvent.php b/core/lib/Thelia/Core/Event/CategoryDeleteEvent.php index 3e863be8e..ad686563d 100644 --- a/core/lib/Thelia/Core/Event/CategoryDeleteEvent.php +++ b/core/lib/Thelia/Core/Event/CategoryDeleteEvent.php @@ -22,13 +22,11 @@ /*************************************************************************************/ namespace Thelia\Core\Event; + use Thelia\Model\Category; -class CategoryDeleteEvent extends ActionEvent +class CategoryDeleteEvent extends CategoryEvent { - protected $category_id; - protected $deleted_category; - public function __construct($category_id) { $this->category_id = $category_id; @@ -42,15 +40,6 @@ class CategoryDeleteEvent extends ActionEvent public function setCategoryId($category_id) { $this->category_id = $category_id; + return $this; } - - public function getDeletedCategory() - { - return $this->deleted_category; - } - - public function setDeletedCategory(Category $deleted_category) - { - $this->deleted_category = $deleted_category; - } -} +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/CategoryEvent.php b/core/lib/Thelia/Core/Event/CategoryEvent.php index c29d681d8..ac04f15c9 100644 --- a/core/lib/Thelia/Core/Event/CategoryEvent.php +++ b/core/lib/Thelia/Core/Event/CategoryEvent.php @@ -28,20 +28,26 @@ use Thelia\Core\Event\ActionEvent; class CategoryEvent extends ActionEvent { - public $category; + public $category = null; - public function __construct(Category $category) + public function __construct(Category $category = null) { $this->category = $category; } - /** - * @return \Thelia\Model\Category - */ + public function hasCategory() { + return ! is_null($this->category); + } + public function getCategory() { return $this->category; } + public function setCategory(Category $category) + { + $this->category = $category; + return $this; + } } diff --git a/core/lib/Thelia/Core/Event/CategoryToggleVisibilityEvent.php b/core/lib/Thelia/Core/Event/CategoryToggleVisibilityEvent.php index ef921a0de..103c5207e 100644 --- a/core/lib/Thelia/Core/Event/CategoryToggleVisibilityEvent.php +++ b/core/lib/Thelia/Core/Event/CategoryToggleVisibilityEvent.php @@ -22,35 +22,7 @@ /*************************************************************************************/ namespace Thelia\Core\Event; -use Thelia\Model\Category; -class CategoryToggleVisibilityEvent extends ActionEvent +class CategoryToggleVisibilityEvent extends BaseToggleVisibilityEvent { - protected $category_id; - protected $category; - - public function __construct($category_id) - { - $this->category_id = $category_id; - } - - public function getCategoryId() - { - return $this->category_id; - } - - public function setCategoryId($category_id) - { - $this->category_id = $category_id; - } - - public function getCategory() - { - return $this->category; - } - - public function setCategory(Category $category) - { - $this->category = $category; - } } \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/CategoryUpdateEvent.php b/core/lib/Thelia/Core/Event/CategoryUpdateEvent.php index 8103864c5..305cf9369 100644 --- a/core/lib/Thelia/Core/Event/CategoryUpdateEvent.php +++ b/core/lib/Thelia/Core/Event/CategoryUpdateEvent.php @@ -22,17 +22,16 @@ /*************************************************************************************/ namespace Thelia\Core\Event; - use Thelia\Model\Category; -class CategoryUpdateEvent extends ActionEvent +class CategoryUpdateEvent extends CategoryCreateEvent { protected $category_id; - protected $locale; - protected $title; + protected $chapo; protected $description; protected $postscriptum; + protected $url; protected $visibility; protected $parent; @@ -41,4 +40,81 @@ class CategoryUpdateEvent extends ActionEvent { $this->category_id = $category_id; } + + public function getCategoryId() + { + return $this->category_id; + } + + public function setCategoryId($category_id) + { + $this->category_id = $category_id; + return $this; + } + + public function getChapo() + { + return $this->chapo; + } + + public function setChapo($chapo) + { + $this->chapo = $chapo; + return $this; + } + + public function getDescription() + { + return $this->description; + } + + public function setDescription($description) + { + $this->description = $description; + return $this; + } + + public function getPostscriptum() + { + return $this->postscriptum; + } + + public function setPostscriptum($postscriptum) + { + $this->postscriptum = $postscriptum; + return $this; + } + + public function getUrl() + { + return $this->url; + } + + public function setUrl($url) + { + $this->url = $url; + return $this; + } + + public function getVisibility() + { + return $this->visibility; + } + + public function setVisibility($visibility) + { + $this->visibility = $visibility; + return $this; + } + + public function getParent() + { + return $this->parent; + } + + public function setParent($parent) + { + $this->parent = $parent; + return $this; + } } diff --git a/core/lib/Thelia/Core/Event/CategoryChangePositionEvent.php b/core/lib/Thelia/Core/Event/CategoryUpdatePositionEvent.php similarity index 96% rename from core/lib/Thelia/Core/Event/CategoryChangePositionEvent.php rename to core/lib/Thelia/Core/Event/CategoryUpdatePositionEvent.php index 3a3dbb18f..44af9b946 100644 --- a/core/lib/Thelia/Core/Event/CategoryChangePositionEvent.php +++ b/core/lib/Thelia/Core/Event/CategoryUpdatePositionEvent.php @@ -23,6 +23,6 @@ namespace Thelia\Core\Event; -class CurrencyUpdatePositionEvent extends BaseUpdatePositionEvent +class CategoryUpdatePositionEvent extends BaseUpdatePositionEvent { } \ No newline at end of file diff --git a/core/lib/Thelia/Core/Event/ConfigEvent.php b/core/lib/Thelia/Core/Event/ConfigEvent.php index eb5ec57c7..5e1c673cf 100644 --- a/core/lib/Thelia/Core/Event/ConfigEvent.php +++ b/core/lib/Thelia/Core/Event/ConfigEvent.php @@ -26,13 +26,17 @@ use Thelia\Model\Config; class ConfigEvent extends ActionEvent { - protected $config; + protected $config = null; public function __construct(Config $config = null) { $this->config = $config; } + public function hasConfig() { + return ! is_null($this->config); + } + public function getConfig() { return $this->config; diff --git a/core/lib/Thelia/Core/Event/CurrencyEvent.php b/core/lib/Thelia/Core/Event/CurrencyEvent.php index e0716da0c..65ac60513 100644 --- a/core/lib/Thelia/Core/Event/CurrencyEvent.php +++ b/core/lib/Thelia/Core/Event/CurrencyEvent.php @@ -26,13 +26,17 @@ use Thelia\Model\Currency; class CurrencyEvent extends ActionEvent { - protected $currency; + protected $currency = null; public function __construct(Currency $currency = null) { $this->currency = $currency; } + public function hasCurrency() { + return ! is_null($this->currency); + } + public function getCurrency() { return $this->currency; diff --git a/core/lib/Thelia/Core/Event/MessageEvent.php b/core/lib/Thelia/Core/Event/MessageEvent.php index 18433a36b..0f46ae590 100644 --- a/core/lib/Thelia/Core/Event/MessageEvent.php +++ b/core/lib/Thelia/Core/Event/MessageEvent.php @@ -26,13 +26,17 @@ use Thelia\Model\Message; class MessageEvent extends ActionEvent { - protected $message; + protected $message = null; public function __construct(Message $message = null) { $this->message = $message; } + public function hasMessage() { + return ! is_null($this->message); + } + public function getMessage() { return $this->message; diff --git a/core/lib/Thelia/Core/Event/TheliaEvents.php b/core/lib/Thelia/Core/Event/TheliaEvents.php index 97d92e110..1efd6c4d2 100755 --- a/core/lib/Thelia/Core/Event/TheliaEvents.php +++ b/core/lib/Thelia/Core/Event/TheliaEvents.php @@ -33,6 +33,11 @@ namespace Thelia\Core\Event; final class TheliaEvents { + /** + * sent at the beginning + */ + const BOOT = "thelia.boot"; + /** * ACTION event * diff --git a/core/lib/Thelia/Core/HttpFoundation/Session/Session.php b/core/lib/Thelia/Core/HttpFoundation/Session/Session.php index 4a486e488..8c6a241ec 100755 --- a/core/lib/Thelia/Core/HttpFoundation/Session/Session.php +++ b/core/lib/Thelia/Core/HttpFoundation/Session/Session.php @@ -164,10 +164,28 @@ class Session extends BaseSession * assign cart id in session * * @param $cart_id + * @return $this */ public function setCart($cart_id) { $this->set("thelia.cart_id", $cart_id); return $this; } + + /** + * assign delivery id in session + * + * @param $delivery_id + * @return $this + */ + public function setDelivery($delivery_id) + { + $this->set("thelia.delivery_id", $delivery_id); + return $this; + } + + public function getDelivery() + { + return $this->get("thelia.delivery_id"); + } } \ No newline at end of file diff --git a/core/lib/Thelia/Core/Template/Element/BaseLoop.php b/core/lib/Thelia/Core/Template/Element/BaseLoop.php index 98ed8af33..d74f9894b 100755 --- a/core/lib/Thelia/Core/Template/Element/BaseLoop.php +++ b/core/lib/Thelia/Core/Template/Element/BaseLoop.php @@ -243,23 +243,9 @@ abstract class BaseLoop * * this function have to be implement in your own loop class. * - * All your parameters are defined in defineArgs() and can be accessible like a class property. + * All loops parameters can be accessible via getter. * - * example : - * - * public function defineArgs() - * { - * return array ( - * "ref", - * "id" => "optional", - * "stock" => array( - * "optional", - * "default" => 10 - * ) - * ); - * } - * - * you can retrieve ref value using $this->ref + * for example, ref parameter is accessible through getRef method * * @param $pagination * @@ -271,18 +257,31 @@ abstract class BaseLoop * * define all args used in your loop * - * array key is your arg name. * * example : * - * return array ( - * "ref", - * "id" => "optional", - * "stock" => array( - * "optional", - * "default" => 10 - * ) - * ); + * public function getArgDefinitions() + * { + * return new ArgumentCollection( + * Argument::createIntListTypeArgument('id'), + * new Argument( + * 'ref', + * new TypeCollection( + * new Type\AlphaNumStringListType() + * ) + * ), + * Argument::createIntListTypeArgument('category'), + * Argument::createBooleanTypeArgument('new'), + * Argument::createBooleanTypeArgument('promo'), + * Argument::createFloatTypeArgument('min_price'), + * Argument::createFloatTypeArgument('max_price'), + * Argument::createIntTypeArgument('min_stock'), + * Argument::createFloatTypeArgument('min_weight'), + * Argument::createFloatTypeArgument('max_weight'), + * Argument::createBooleanTypeArgument('current'), + * + * ); + * } * * @return \Thelia\Core\Template\Loop\Argument\ArgumentCollection */ diff --git a/core/lib/Thelia/Core/Template/Loop/BaseSpecificModule.php b/core/lib/Thelia/Core/Template/Loop/BaseSpecificModule.php new file mode 100644 index 000000000..3b4e54be6 --- /dev/null +++ b/core/lib/Thelia/Core/Template/Loop/BaseSpecificModule.php @@ -0,0 +1,109 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Template\Loop; +use Propel\Runtime\ActiveQuery\Criteria; +use Thelia\Core\Template\Element\BaseI18nLoop; +use Thelia\Core\Template\Loop\Argument\Argument; +use Thelia\Core\Template\Loop\Argument\ArgumentCollection; +use Thelia\Model\ModuleQuery; + + +/** + * Class Delivery + * @package Thelia\Core\Template\Loop + * @author Manuel Raynaud + */ +class BaseSpecificModule extends BaseI18nLoop { + public $timestampable = true; + + /** + * + * define all args used in your loop + * + * + * example : + * + * public function getArgDefinitions() + * { + * return new ArgumentCollection( + * Argument::createIntListTypeArgument('id'), + * new Argument( + * 'ref', + * new TypeCollection( + * new Type\AlphaNumStringListType() + * ) + * ), + * Argument::createIntListTypeArgument('category'), + * Argument::createBooleanTypeArgument('new'), + * Argument::createBooleanTypeArgument('promo'), + * Argument::createFloatTypeArgument('min_price'), + * Argument::createFloatTypeArgument('max_price'), + * Argument::createIntTypeArgument('min_stock'), + * Argument::createFloatTypeArgument('min_weight'), + * Argument::createFloatTypeArgument('max_weight'), + * Argument::createBooleanTypeArgument('current'), + * + * ); + * } + * + * @return \Thelia\Core\Template\Loop\Argument\ArgumentCollection + */ + protected function getArgDefinitions() + { + return new ArgumentCollection( + Argument::createIntTypeArgument('id'), + Argument::createIntListTypeArgument('exclude') + ); + } + + /** + * + * this function have to be implement in your own loop class. + * + * All loops parameters can be accesible via getter. + * + * for example, ref parameter is accessible through getRef method + * + * @param $pagination + * + * @return \Thelia\Model\ModuleQuery + */ + public function exec(&$pagination) + { + $search = ModuleQuery::create(); + + if(null !== $id = $this->getId()) + { + $search->filterById($id); + } + + + if (null !== $exclude = $this->getExclude()) { + $search->filterById($exclude, Criteria::NOT_IN); + } + + return $search; + } + +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Template/Loop/Delivery.php b/core/lib/Thelia/Core/Template/Loop/Delivery.php new file mode 100644 index 000000000..7ef46eedc --- /dev/null +++ b/core/lib/Thelia/Core/Template/Loop/Delivery.php @@ -0,0 +1,85 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Template\Loop; +use Thelia\Core\Template\Element\LoopResult; +use Thelia\Core\Template\Element\LoopResultRow; +use Thelia\Core\Template\Loop\Argument\Argument; + + +/** + * Class Delivery + * @package Thelia\Core\Template\Loop + * @author Manuel Raynaud + */ +class Delivery extends BaseSpecificModule +{ + + public function getArgDefinitions() + { + $collection = parent::getArgDefinitions(); + + $collection->addArgument( + Argument::createIntTypeArgument("country") + ); + + return $collection; + } + + public function exec(&$pagination) + { + $search = parent::exec($pagination); + /* manage translations */ + $locale = $this->configureI18nProcessing($search); + /* perform search */ + $deliveryModules = $this->search($search, $pagination); + + $loopResult = new LoopResult($deliveryModules); + + foreach ($deliveryModules as $deliveryModule) { + $loopResultRow = new LoopResultRow($loopResult, $deliveryModule, $this->versionable, $this->timestampable, $this->countable); + + $moduleReflection = new \ReflectionClass($deliveryModule->getFullNamespace()); + if($moduleReflection->isSubclassOf("Thelia\Module\DeliveryModuleInterface") === false) { + throw new \RuntimeException(sprintf("delivery module %s is not a Thelia\Module\DeliveryModuleInterface", $deliveryModule->getCode())); + } + $moduleInstance = $moduleReflection->newInstance(); + + $moduleInstance->setRequest($this->request); + $moduleInstance->setDispatcher($this->dispatcher); + + $loopResultRow + ->set('ID', $deliveryModule->getId()) + ->set('TITLE', $deliveryModule->getVirtualColumn('i18n_TITLE')) + ->set('CHAPO', $deliveryModule->getVirtualColumn('i18n_CHAPO')) + ->set('DESCRIPTION', $deliveryModule->getVirtualColumn('i18n_DESCRIPTION')) + ->set('POSTSCRIPTUM', $deliveryModule->getVirtualColumn('i18n_POSTSCRIPTUM')) + ->set('PRICE', $moduleInstance->calculate($this->getCountry())) + ; + + $loopResult->addRow($loopResultRow); + } + + return $loopResult; + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Thelia.php b/core/lib/Thelia/Core/Thelia.php index b28b23156..64f8e9a61 100755 --- a/core/lib/Thelia/Core/Thelia.php +++ b/core/lib/Thelia/Core/Thelia.php @@ -33,12 +33,15 @@ namespace Thelia\Core; */ use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\HttpKernel\Kernel; use Symfony\Component\Config\Loader\LoaderInterface; +use Symfony\Component\Validator\Tests\Fixtures\Reference; use Symfony\Component\Yaml\Yaml; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; use Thelia\Core\Bundle; +use Thelia\Core\Event\TheliaEvents; use Thelia\Log\Tlog; use Thelia\Config\DatabaseConfiguration; use Thelia\Config\DefinePropel; @@ -81,13 +84,22 @@ class Thelia extends Kernel $serviceContainer->setConnectionManager('thelia', $manager); if ($this->isDebug()) { - $serviceContainer->setLogger('defaultLogger', Tlog::getInstance()); - + //$serviceContainer->setLogger('defaultLogger', Tlog::getInstance()); $con = Propel::getConnection(\Thelia\Model\Map\ProductTableMap::DATABASE_NAME); $con->useDebug(true); } } + /** + * dispatch an event when application is boot + */ + public function boot() + { + parent::boot(); + + $this->getContainer()->get("event_dispatcher")->dispatch(TheliaEvents::BOOT); + } + /** * * Load some configuration @@ -107,6 +119,16 @@ class Thelia extends Kernel foreach ($modules as $module) { try { + + $defintion = new Definition(); + $defintion->setClass($module->getFullNamespace()); + $defintion->addMethodCall("setContainer", array('service_container')); + + $container->setDefinition( + "module.".$module->getCode(), + $defintion + ); + $loader = new XmlFileLoader($container, new FileLocator(THELIA_MODULE_DIR . "/" . ucfirst($module->getCode()) . "/Config")); $loader->load("config.xml"); } catch (\InvalidArgumentException $e) { diff --git a/core/lib/Thelia/Core/TheliaHttpKernel.php b/core/lib/Thelia/Core/TheliaHttpKernel.php index 20197d9c6..3c0f14808 100755 --- a/core/lib/Thelia/Core/TheliaHttpKernel.php +++ b/core/lib/Thelia/Core/TheliaHttpKernel.php @@ -127,6 +127,9 @@ class TheliaHttpKernel extends HttpKernel // See Thelia\Tools\URL class. $this->container->get('thelia.url.manager'); + // Same thing for the Translator service. + $this->container->get('thelia.translator'); + $lang = $this->detectLang($request); if ($lang) { diff --git a/core/lib/Thelia/Core/Translation/Translator.php b/core/lib/Thelia/Core/Translation/Translator.php index 83114d478..d941fefb7 100755 --- a/core/lib/Thelia/Core/Translation/Translator.php +++ b/core/lib/Thelia/Core/Translation/Translator.php @@ -5,6 +5,29 @@ use Symfony\Component\Translation\Translator as BaseTranslator; class Translator extends BaseTranslator { + + protected static $instance = null; + + public function __construct() + { + // 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'); + self::$instance = $this; + } + + /** + * Return this class instance, only once instanciated. + * + * @throws \RuntimeException if the class has not been instanciated. + * @return Thelia\Core\Translation\Translator the instance. + */ + public static function getInstance() { + if (self::$instance == null) throw new \RuntimeException("Translator instance is not initialized."); + + return self::$instance; + } + /** * {@inheritdoc} * @@ -21,7 +44,7 @@ class Translator extends BaseTranslator } if ($this->catalogues[$locale]->has((string) $id, $domain)) - return parent::trans($id, $parameters, $domain = 'messages', $locale = null); + return parent::trans($id, $parameters, $domain, $locale); else return strtr($id, $parameters); } diff --git a/core/lib/Thelia/Form/BaseForm.php b/core/lib/Thelia/Form/BaseForm.php index 870f94505..0eb6b828b 100755 --- a/core/lib/Thelia/Form/BaseForm.php +++ b/core/lib/Thelia/Form/BaseForm.php @@ -141,6 +141,8 @@ abstract class BaseForm public function createView() { $this->view = $this->form->createView(); + + return $this; } public function getView() @@ -159,6 +161,8 @@ abstract class BaseForm public function setError($has_error = true) { $this->has_error = $has_error; + + return $this; } /** @@ -180,6 +184,8 @@ abstract class BaseForm { $this->setError(true); $this->error_message = $message; + + return $this; } /** diff --git a/core/lib/Thelia/Form/CategoryCreationForm.php b/core/lib/Thelia/Form/CategoryCreationForm.php index a125ad090..5dce6a049 100755 --- a/core/lib/Thelia/Form/CategoryCreationForm.php +++ b/core/lib/Thelia/Form/CategoryCreationForm.php @@ -23,6 +23,7 @@ namespace Thelia\Form; use Symfony\Component\Validator\Constraints\NotBlank; +use Thelia\Core\Translation\Translator; class CategoryCreationForm extends BaseForm { @@ -33,7 +34,7 @@ class CategoryCreationForm extends BaseForm "constraints" => array( new NotBlank() ), - "label" => "Category title *", + "label" => Translator::getInstance()->trans("Category title *"), "label_attr" => array( "for" => "title" ) diff --git a/core/lib/Thelia/Form/CategoryModificationForm.php b/core/lib/Thelia/Form/CategoryModificationForm.php new file mode 100644 index 000000000..a27389324 --- /dev/null +++ b/core/lib/Thelia/Form/CategoryModificationForm.php @@ -0,0 +1,55 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form; + +use Symfony\Component\Validator\Constraints\NotBlank; +use Thelia\Model\LangQuery; +use Propel\Runtime\ActiveQuery\Criteria; +use Symfony\Component\Validator\Constraints\GreaterThan; +use Thelia\Core\Translation\Translator; + +class CategoryModificationForm extends CategoryCreationForm +{ + use StandardDescriptionFieldsTrait; + + protected function buildForm() + { + parent::buildForm(true); + + $this->formBuilder + ->add("id", "hidden", array("constraints" => array(new GreaterThan(array('value' => 0))))) + + ->add("visible", "checkbox", array( + "label" => Translator::getInstance()->trans("This category is online on the front office.") + )) + ; + + // Add standard description fields + $this->addStandardDescFields(array('title', 'locale')); + } + + public function getName() + { + return "thelia_category_modification"; + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Form/ConfigModificationForm.php b/core/lib/Thelia/Form/ConfigModificationForm.php index 295c0403d..ce508137f 100644 --- a/core/lib/Thelia/Form/ConfigModificationForm.php +++ b/core/lib/Thelia/Form/ConfigModificationForm.php @@ -27,12 +27,12 @@ use Thelia\Model\LangQuery; use Propel\Runtime\ActiveQuery\Criteria; use Symfony\Component\Validator\Constraints\GreaterThan; -class ConfigModificationForm extends BaseDescForm +class ConfigModificationForm extends BaseForm { + use StandardDescriptionFieldsTrait; + protected function buildForm() { - parent::buildForm(true); - $this->formBuilder ->add("id", "hidden", array( "constraints" => array( @@ -61,6 +61,9 @@ class ConfigModificationForm extends BaseDescForm "label" => "Prevent variable modification or deletion, except for super-admin" )) ; + + // Add standard description fields + $this->addStandardDescFields(); } public function getName() diff --git a/core/lib/Thelia/Form/BaseDescForm.php b/core/lib/Thelia/Form/ProductCreationForm.php similarity index 67% rename from core/lib/Thelia/Form/BaseDescForm.php rename to core/lib/Thelia/Form/ProductCreationForm.php index 2b35f3e6e..396f6d0d5 100644 --- a/core/lib/Thelia/Form/BaseDescForm.php +++ b/core/lib/Thelia/Form/ProductCreationForm.php @@ -24,50 +24,44 @@ namespace Thelia\Form; use Symfony\Component\Validator\Constraints\NotBlank; -/** - * A base form for all objects with standard contents. - * - * @author Franck Allimant - */ -abstract class BaseDescForm extends BaseForm +class ProductCreationForm extends BaseForm { protected function buildForm() { $this->formBuilder - ->add("locale", "hidden", array( - "constraints" => array( - new NotBlank() - ) + ->add("ref", "text", array( + "constraints" => array( + new NotBlank() + ), + "label" => "Product reference *", + "label_attr" => array( + "for" => "ref" ) - ) + )) ->add("title", "text", array( - "constraints" => array( - new NotBlank() - ), - "label" => "Title", - "label_attr" => array( - "for" => "title" - ) - ) - ) - ->add("chapo", "text", array( - "label" => "Summary", + "constraints" => array( + new NotBlank() + ), + "label" => "Product title *", "label_attr" => array( - "for" => "summary" + "for" => "title" ) )) - ->add("description", "text", array( - "label" => "Detailed description", - "label_attr" => array( - "for" => "detailed_description" + ->add("parent", "integer", array( + "constraints" => array( + new NotBlank() ) )) - ->add("postscriptum", "text", array( - "label" => "Conclusion", - "label_attr" => array( - "for" => "conclusion" + ->add("locale", "text", array( + "constraints" => array( + new NotBlank() ) )) ; - } -} \ No newline at end of file + } + + public function getName() + { + return "thelia_product_creation"; + } +} diff --git a/core/lib/Thelia/Form/StandardDescriptionFieldsTrait.php b/core/lib/Thelia/Form/StandardDescriptionFieldsTrait.php new file mode 100644 index 000000000..7c0a51a31 --- /dev/null +++ b/core/lib/Thelia/Form/StandardDescriptionFieldsTrait.php @@ -0,0 +1,92 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form; + +use Symfony\Component\Validator\Constraints\NotBlank; + +use Thelia\Core\Translation\Translator; + +/** + * A trait to add standard localized description fields to a form. + * + * @author Franck Allimant + */ +trait StandardDescriptionFieldsTrait +{ + /** + * Add standard description fields + locale tot the form + * + * @param array $exclude name of the fields that should not be added to the form + */ + protected function addStandardDescFields($exclude = array()) + { + if (! in_array('locale', $exclude)) + $this->formBuilder + ->add("locale", "hidden", array( + "constraints" => array( + new NotBlank() + ) + ) + ); + + if (! in_array('title', $exclude)) + $this->formBuilder + ->add("title", "text", array( + "constraints" => array( + new NotBlank() + ), + "label" => Translator::getInstance()->trans("Title"), + "label_attr" => array( + "for" => "title" + ) + ) + ); + + if (! in_array('chapo', $exclude)) + $this->formBuilder + ->add("chapo", "text", array( + "label" => Translator::getInstance()->trans("Summary"), + "label_attr" => array( + "for" => "summary" + ) + )); + + if (! in_array('description', $exclude)) + $this->formBuilder + ->add("description", "text", array( + "label" => Translator::getInstance()->trans("Detailed description"), + "label_attr" => array( + "for" => "detailed_description" + ) + )); + + if (! in_array('postscriptum', $exclude)) + $this->formBuilder + ->add("postscriptum", "text", array( + "label" => Translator::getInstance()->trans("Conclusion"), + "label_attr" => array( + "for" => "conclusion" + ) + )); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Model/Base/Module.php b/core/lib/Thelia/Model/Base/Module.php index 556ef9ff6..9cc89381a 100755 --- a/core/lib/Thelia/Model/Base/Module.php +++ b/core/lib/Thelia/Model/Base/Module.php @@ -89,6 +89,12 @@ abstract class Module implements ActiveRecordInterface */ protected $position; + /** + * The value for the full_namespace field. + * @var string + */ + protected $full_namespace; + /** * The value for the created_at field. * @var string @@ -456,6 +462,17 @@ abstract class Module implements ActiveRecordInterface return $this->position; } + /** + * Get the [full_namespace] column value. + * + * @return string + */ + public function getFullNamespace() + { + + return $this->full_namespace; + } + /** * Get the [optionally formatted] temporal [created_at] column value. * @@ -601,6 +618,27 @@ abstract class Module implements ActiveRecordInterface return $this; } // setPosition() + /** + * Set the value of [full_namespace] column. + * + * @param string $v new value + * @return \Thelia\Model\Module The current object (for fluent API support) + */ + public function setFullNamespace($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->full_namespace !== $v) { + $this->full_namespace = $v; + $this->modifiedColumns[] = ModuleTableMap::FULL_NAMESPACE; + } + + + return $this; + } // setFullNamespace() + /** * Sets the value of [created_at] column to a normalized version of the date/time value specified. * @@ -695,13 +733,16 @@ abstract class Module implements ActiveRecordInterface $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : ModuleTableMap::translateFieldName('Position', TableMap::TYPE_PHPNAME, $indexType)]; $this->position = (null !== $col) ? (int) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : ModuleTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : ModuleTableMap::translateFieldName('FullNamespace', TableMap::TYPE_PHPNAME, $indexType)]; + $this->full_namespace = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : ModuleTableMap::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 ? 6 + $startcol : ModuleTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : ModuleTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } @@ -714,7 +755,7 @@ abstract class Module implements ActiveRecordInterface $this->ensureConsistency(); } - return $startcol + 7; // 7 = ModuleTableMap::NUM_HYDRATE_COLUMNS. + return $startcol + 8; // 8 = ModuleTableMap::NUM_HYDRATE_COLUMNS. } catch (Exception $e) { throw new PropelException("Error populating \Thelia\Model\Module object", 0, $e); @@ -987,6 +1028,9 @@ abstract class Module implements ActiveRecordInterface if ($this->isColumnModified(ModuleTableMap::POSITION)) { $modifiedColumns[':p' . $index++] = 'POSITION'; } + if ($this->isColumnModified(ModuleTableMap::FULL_NAMESPACE)) { + $modifiedColumns[':p' . $index++] = 'FULL_NAMESPACE'; + } if ($this->isColumnModified(ModuleTableMap::CREATED_AT)) { $modifiedColumns[':p' . $index++] = 'CREATED_AT'; } @@ -1019,6 +1063,9 @@ abstract class Module implements ActiveRecordInterface case 'POSITION': $stmt->bindValue($identifier, $this->position, PDO::PARAM_INT); break; + case 'FULL_NAMESPACE': + $stmt->bindValue($identifier, $this->full_namespace, PDO::PARAM_STR); + break; case 'CREATED_AT': $stmt->bindValue($identifier, $this->created_at ? $this->created_at->format("Y-m-d H:i:s") : null, PDO::PARAM_STR); break; @@ -1103,9 +1150,12 @@ abstract class Module implements ActiveRecordInterface return $this->getPosition(); break; case 5: - return $this->getCreatedAt(); + return $this->getFullNamespace(); break; case 6: + return $this->getCreatedAt(); + break; + case 7: return $this->getUpdatedAt(); break; default: @@ -1142,8 +1192,9 @@ abstract class Module implements ActiveRecordInterface $keys[2] => $this->getType(), $keys[3] => $this->getActivate(), $keys[4] => $this->getPosition(), - $keys[5] => $this->getCreatedAt(), - $keys[6] => $this->getUpdatedAt(), + $keys[5] => $this->getFullNamespace(), + $keys[6] => $this->getCreatedAt(), + $keys[7] => $this->getUpdatedAt(), ); $virtualColumns = $this->virtualColumns; foreach($virtualColumns as $key => $virtualColumn) @@ -1208,9 +1259,12 @@ abstract class Module implements ActiveRecordInterface $this->setPosition($value); break; case 5: - $this->setCreatedAt($value); + $this->setFullNamespace($value); break; case 6: + $this->setCreatedAt($value); + break; + case 7: $this->setUpdatedAt($value); break; } // switch() @@ -1242,8 +1296,9 @@ abstract class Module implements ActiveRecordInterface if (array_key_exists($keys[2], $arr)) $this->setType($arr[$keys[2]]); if (array_key_exists($keys[3], $arr)) $this->setActivate($arr[$keys[3]]); if (array_key_exists($keys[4], $arr)) $this->setPosition($arr[$keys[4]]); - if (array_key_exists($keys[5], $arr)) $this->setCreatedAt($arr[$keys[5]]); - if (array_key_exists($keys[6], $arr)) $this->setUpdatedAt($arr[$keys[6]]); + if (array_key_exists($keys[5], $arr)) $this->setFullNamespace($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]]); } /** @@ -1260,6 +1315,7 @@ abstract class Module implements ActiveRecordInterface if ($this->isColumnModified(ModuleTableMap::TYPE)) $criteria->add(ModuleTableMap::TYPE, $this->type); if ($this->isColumnModified(ModuleTableMap::ACTIVATE)) $criteria->add(ModuleTableMap::ACTIVATE, $this->activate); if ($this->isColumnModified(ModuleTableMap::POSITION)) $criteria->add(ModuleTableMap::POSITION, $this->position); + if ($this->isColumnModified(ModuleTableMap::FULL_NAMESPACE)) $criteria->add(ModuleTableMap::FULL_NAMESPACE, $this->full_namespace); if ($this->isColumnModified(ModuleTableMap::CREATED_AT)) $criteria->add(ModuleTableMap::CREATED_AT, $this->created_at); if ($this->isColumnModified(ModuleTableMap::UPDATED_AT)) $criteria->add(ModuleTableMap::UPDATED_AT, $this->updated_at); @@ -1329,6 +1385,7 @@ abstract class Module implements ActiveRecordInterface $copyObj->setType($this->getType()); $copyObj->setActivate($this->getActivate()); $copyObj->setPosition($this->getPosition()); + $copyObj->setFullNamespace($this->getFullNamespace()); $copyObj->setCreatedAt($this->getCreatedAt()); $copyObj->setUpdatedAt($this->getUpdatedAt()); @@ -1876,6 +1933,7 @@ abstract class Module implements ActiveRecordInterface $this->type = null; $this->activate = null; $this->position = null; + $this->full_namespace = null; $this->created_at = null; $this->updated_at = null; $this->alreadyInSave = false; diff --git a/core/lib/Thelia/Model/Base/ModuleQuery.php b/core/lib/Thelia/Model/Base/ModuleQuery.php index e1bd9de68..6f8d4b551 100755 --- a/core/lib/Thelia/Model/Base/ModuleQuery.php +++ b/core/lib/Thelia/Model/Base/ModuleQuery.php @@ -27,6 +27,7 @@ use Thelia\Model\Map\ModuleTableMap; * @method ChildModuleQuery orderByType($order = Criteria::ASC) Order by the type column * @method ChildModuleQuery orderByActivate($order = Criteria::ASC) Order by the activate column * @method ChildModuleQuery orderByPosition($order = Criteria::ASC) Order by the position column + * @method ChildModuleQuery orderByFullNamespace($order = Criteria::ASC) Order by the full_namespace column * @method ChildModuleQuery orderByCreatedAt($order = Criteria::ASC) Order by the created_at column * @method ChildModuleQuery orderByUpdatedAt($order = Criteria::ASC) Order by the updated_at column * @@ -35,6 +36,7 @@ use Thelia\Model\Map\ModuleTableMap; * @method ChildModuleQuery groupByType() Group by the type column * @method ChildModuleQuery groupByActivate() Group by the activate column * @method ChildModuleQuery groupByPosition() Group by the position column + * @method ChildModuleQuery groupByFullNamespace() Group by the full_namespace column * @method ChildModuleQuery groupByCreatedAt() Group by the created_at column * @method ChildModuleQuery groupByUpdatedAt() Group by the updated_at column * @@ -58,6 +60,7 @@ use Thelia\Model\Map\ModuleTableMap; * @method ChildModule findOneByType(int $type) Return the first ChildModule filtered by the type column * @method ChildModule findOneByActivate(int $activate) Return the first ChildModule filtered by the activate column * @method ChildModule findOneByPosition(int $position) Return the first ChildModule filtered by the position column + * @method ChildModule findOneByFullNamespace(string $full_namespace) Return the first ChildModule filtered by the full_namespace column * @method ChildModule findOneByCreatedAt(string $created_at) Return the first ChildModule filtered by the created_at column * @method ChildModule findOneByUpdatedAt(string $updated_at) Return the first ChildModule filtered by the updated_at column * @@ -66,6 +69,7 @@ use Thelia\Model\Map\ModuleTableMap; * @method array findByType(int $type) Return ChildModule objects filtered by the type column * @method array findByActivate(int $activate) Return ChildModule objects filtered by the activate column * @method array findByPosition(int $position) Return ChildModule objects filtered by the position column + * @method array findByFullNamespace(string $full_namespace) Return ChildModule objects filtered by the full_namespace column * @method array findByCreatedAt(string $created_at) Return ChildModule objects filtered by the created_at column * @method array findByUpdatedAt(string $updated_at) Return ChildModule objects filtered by the updated_at column * @@ -156,7 +160,7 @@ abstract class ModuleQuery extends ModelCriteria */ protected function findPkSimple($key, $con) { - $sql = 'SELECT ID, CODE, TYPE, ACTIVATE, POSITION, CREATED_AT, UPDATED_AT FROM module WHERE ID = :p0'; + $sql = 'SELECT ID, CODE, TYPE, ACTIVATE, POSITION, FULL_NAMESPACE, CREATED_AT, UPDATED_AT FROM module WHERE ID = :p0'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key, PDO::PARAM_INT); @@ -438,6 +442,35 @@ abstract class ModuleQuery extends ModelCriteria return $this->addUsingAlias(ModuleTableMap::POSITION, $position, $comparison); } + /** + * Filter the query on the full_namespace column + * + * Example usage: + * + * $query->filterByFullNamespace('fooValue'); // WHERE full_namespace = 'fooValue' + * $query->filterByFullNamespace('%fooValue%'); // WHERE full_namespace LIKE '%fooValue%' + * + * + * @param string $fullNamespace 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 ChildModuleQuery The current query, for fluid interface + */ + public function filterByFullNamespace($fullNamespace = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($fullNamespace)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $fullNamespace)) { + $fullNamespace = str_replace('*', '%', $fullNamespace); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(ModuleTableMap::FULL_NAMESPACE, $fullNamespace, $comparison); + } + /** * Filter the query on the created_at column * diff --git a/core/lib/Thelia/Model/Map/ModuleTableMap.php b/core/lib/Thelia/Model/Map/ModuleTableMap.php index cccaa890a..dae9fda4a 100755 --- a/core/lib/Thelia/Model/Map/ModuleTableMap.php +++ b/core/lib/Thelia/Model/Map/ModuleTableMap.php @@ -57,7 +57,7 @@ class ModuleTableMap extends TableMap /** * The total number of columns */ - const NUM_COLUMNS = 7; + const NUM_COLUMNS = 8; /** * The number of lazy-loaded columns @@ -67,7 +67,7 @@ class ModuleTableMap extends TableMap /** * The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */ - const NUM_HYDRATE_COLUMNS = 7; + const NUM_HYDRATE_COLUMNS = 8; /** * the column name for the ID field @@ -94,6 +94,11 @@ class ModuleTableMap extends TableMap */ const POSITION = 'module.POSITION'; + /** + * the column name for the FULL_NAMESPACE field + */ + const FULL_NAMESPACE = 'module.FULL_NAMESPACE'; + /** * the column name for the CREATED_AT field */ @@ -125,12 +130,12 @@ class ModuleTableMap extends TableMap * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ protected static $fieldNames = array ( - self::TYPE_PHPNAME => array('Id', 'Code', 'Type', 'Activate', 'Position', 'CreatedAt', 'UpdatedAt', ), - self::TYPE_STUDLYPHPNAME => array('id', 'code', 'type', 'activate', 'position', 'createdAt', 'updatedAt', ), - self::TYPE_COLNAME => array(ModuleTableMap::ID, ModuleTableMap::CODE, ModuleTableMap::TYPE, ModuleTableMap::ACTIVATE, ModuleTableMap::POSITION, ModuleTableMap::CREATED_AT, ModuleTableMap::UPDATED_AT, ), - self::TYPE_RAW_COLNAME => array('ID', 'CODE', 'TYPE', 'ACTIVATE', 'POSITION', 'CREATED_AT', 'UPDATED_AT', ), - self::TYPE_FIELDNAME => array('id', 'code', 'type', 'activate', 'position', 'created_at', 'updated_at', ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, ) + self::TYPE_PHPNAME => array('Id', 'Code', 'Type', 'Activate', 'Position', 'FullNamespace', 'CreatedAt', 'UpdatedAt', ), + self::TYPE_STUDLYPHPNAME => array('id', 'code', 'type', 'activate', 'position', 'fullNamespace', 'createdAt', 'updatedAt', ), + self::TYPE_COLNAME => array(ModuleTableMap::ID, ModuleTableMap::CODE, ModuleTableMap::TYPE, ModuleTableMap::ACTIVATE, ModuleTableMap::POSITION, ModuleTableMap::FULL_NAMESPACE, ModuleTableMap::CREATED_AT, ModuleTableMap::UPDATED_AT, ), + self::TYPE_RAW_COLNAME => array('ID', 'CODE', 'TYPE', 'ACTIVATE', 'POSITION', 'FULL_NAMESPACE', 'CREATED_AT', 'UPDATED_AT', ), + self::TYPE_FIELDNAME => array('id', 'code', 'type', 'activate', 'position', 'full_namespace', 'created_at', 'updated_at', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, ) ); /** @@ -140,12 +145,12 @@ class ModuleTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'Code' => 1, 'Type' => 2, 'Activate' => 3, 'Position' => 4, 'CreatedAt' => 5, 'UpdatedAt' => 6, ), - self::TYPE_STUDLYPHPNAME => array('id' => 0, 'code' => 1, 'type' => 2, 'activate' => 3, 'position' => 4, 'createdAt' => 5, 'updatedAt' => 6, ), - self::TYPE_COLNAME => array(ModuleTableMap::ID => 0, ModuleTableMap::CODE => 1, ModuleTableMap::TYPE => 2, ModuleTableMap::ACTIVATE => 3, ModuleTableMap::POSITION => 4, ModuleTableMap::CREATED_AT => 5, ModuleTableMap::UPDATED_AT => 6, ), - self::TYPE_RAW_COLNAME => array('ID' => 0, 'CODE' => 1, 'TYPE' => 2, 'ACTIVATE' => 3, 'POSITION' => 4, 'CREATED_AT' => 5, 'UPDATED_AT' => 6, ), - self::TYPE_FIELDNAME => array('id' => 0, 'code' => 1, 'type' => 2, 'activate' => 3, 'position' => 4, 'created_at' => 5, 'updated_at' => 6, ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, ) + self::TYPE_PHPNAME => array('Id' => 0, 'Code' => 1, 'Type' => 2, 'Activate' => 3, 'Position' => 4, 'FullNamespace' => 5, 'CreatedAt' => 6, 'UpdatedAt' => 7, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'code' => 1, 'type' => 2, 'activate' => 3, 'position' => 4, 'fullNamespace' => 5, 'createdAt' => 6, 'updatedAt' => 7, ), + self::TYPE_COLNAME => array(ModuleTableMap::ID => 0, ModuleTableMap::CODE => 1, ModuleTableMap::TYPE => 2, ModuleTableMap::ACTIVATE => 3, ModuleTableMap::POSITION => 4, ModuleTableMap::FULL_NAMESPACE => 5, ModuleTableMap::CREATED_AT => 6, ModuleTableMap::UPDATED_AT => 7, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'CODE' => 1, 'TYPE' => 2, 'ACTIVATE' => 3, 'POSITION' => 4, 'FULL_NAMESPACE' => 5, 'CREATED_AT' => 6, 'UPDATED_AT' => 7, ), + self::TYPE_FIELDNAME => array('id' => 0, 'code' => 1, 'type' => 2, 'activate' => 3, 'position' => 4, 'full_namespace' => 5, 'created_at' => 6, 'updated_at' => 7, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, ) ); /** @@ -169,6 +174,7 @@ class ModuleTableMap extends TableMap $this->addColumn('TYPE', 'Type', 'TINYINT', true, null, null); $this->addColumn('ACTIVATE', 'Activate', 'TINYINT', false, null, null); $this->addColumn('POSITION', 'Position', 'INTEGER', false, null, null); + $this->addColumn('FULL_NAMESPACE', 'FullNamespace', 'VARCHAR', false, 255, null); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); } // initialize() @@ -349,6 +355,7 @@ class ModuleTableMap extends TableMap $criteria->addSelectColumn(ModuleTableMap::TYPE); $criteria->addSelectColumn(ModuleTableMap::ACTIVATE); $criteria->addSelectColumn(ModuleTableMap::POSITION); + $criteria->addSelectColumn(ModuleTableMap::FULL_NAMESPACE); $criteria->addSelectColumn(ModuleTableMap::CREATED_AT); $criteria->addSelectColumn(ModuleTableMap::UPDATED_AT); } else { @@ -357,6 +364,7 @@ class ModuleTableMap extends TableMap $criteria->addSelectColumn($alias . '.TYPE'); $criteria->addSelectColumn($alias . '.ACTIVATE'); $criteria->addSelectColumn($alias . '.POSITION'); + $criteria->addSelectColumn($alias . '.FULL_NAMESPACE'); $criteria->addSelectColumn($alias . '.CREATED_AT'); $criteria->addSelectColumn($alias . '.UPDATED_AT'); } diff --git a/core/lib/Thelia/Model/Tools/PositionManagementTrait.php b/core/lib/Thelia/Model/Tools/PositionManagementTrait.php index 9e0b1f35c..eb71564eb 100644 --- a/core/lib/Thelia/Model/Tools/PositionManagementTrait.php +++ b/core/lib/Thelia/Model/Tools/PositionManagementTrait.php @@ -55,7 +55,7 @@ trait PositionManagementTrait { ->orderByPosition(Criteria::DESC) ->limit(1); - if ($parent !== null) $last->filterByParent($parent); + if ($parent !== null) $query->filterByParent($parent); $last = $query->findOne() ; diff --git a/core/lib/Thelia/Module/BaseModule.php b/core/lib/Thelia/Module/BaseModule.php index 07cc1d116..145da3c02 100755 --- a/core/lib/Thelia/Module/BaseModule.php +++ b/core/lib/Thelia/Module/BaseModule.php @@ -24,7 +24,9 @@ namespace Thelia\Module; -abstract class BaseModule +use Symfony\Component\DependencyInjection\ContainerAware; + +abstract class BaseModule extends ContainerAware { public function __construct() @@ -37,6 +39,19 @@ abstract class BaseModule } + public function hasContainer() + { + return null === $this->container; + } + + public function getContainer() + { + if($this->hasContainer() === false) { + throw new \RuntimeException("Sorry, container his not available in this context"); + } + return $this->container; + } + abstract public function install(); abstract public function destroy(); diff --git a/core/lib/Thelia/Module/BaseModuleInterface.php b/core/lib/Thelia/Module/BaseModuleInterface.php new file mode 100644 index 000000000..2db450830 --- /dev/null +++ b/core/lib/Thelia/Module/BaseModuleInterface.php @@ -0,0 +1,37 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Module; + + +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\HttpFoundation\Request; + +interface BaseModuleInterface { + + public function setRequest(Request $request); + public function getRequest(); + + public function setDispatcher(EventDispatcherInterface $dispatcher); + public function getDispatcher(); +} \ No newline at end of file diff --git a/core/lib/Thelia/Module/DeliveryModuleInterface.php b/core/lib/Thelia/Module/DeliveryModuleInterface.php new file mode 100644 index 000000000..b8ffcfc01 --- /dev/null +++ b/core/lib/Thelia/Module/DeliveryModuleInterface.php @@ -0,0 +1,36 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Module; + + +interface DeliveryModuleInterface extends BaseModuleInterface { + + /** + * + * calculate and return delivery price + * + * @return mixed + */ + public function calculate($country = null); +} \ No newline at end of file diff --git a/install/insert.sql b/install/insert.sql index a2e5868e4..344381a37 100755 --- a/install/insert.sql +++ b/install/insert.sql @@ -17,7 +17,9 @@ INSERT INTO `config` (`name`, `value`, `secured`, `hidden`, `created_at`, `updat ('currency_rate_update_url', 'http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml', 0, 0, NOW(), NOW()), ('page_not_found_view', '404.html', 0, 0, NOW(), NOW()); -INSERT INTO `module` (`code`, `type`, `activate`, `position`, `created_at`, `updated_at`) VALUES ('test', '1', '1', '1', NOW(), NOW()); + +INSERT INTO `module` (`id`, `code`, `type`, `activate`, `position`, `full_namespace`, `created_at`, `updated_at`) VALUES +(1, 'DebugBar', 1, 1, 1, 'DebugBar\\DebugBar', NOW(), NOW()); INSERT INTO `customer_title`(`id`, `by_default`, `position`, `created_at`, `updated_at`) VALUES (1, 1, 1, NOW(), NOW()), diff --git a/install/thelia.sql b/install/thelia.sql index 879f323b9..2fb3723ca 100755 --- a/install/thelia.sql +++ b/install/thelia.sql @@ -803,6 +803,7 @@ CREATE TABLE `module` `type` TINYINT NOT NULL, `activate` TINYINT, `position` INTEGER, + `full_namespace` VARCHAR(255), `created_at` DATETIME, `updated_at` DATETIME, PRIMARY KEY (`id`), diff --git a/local/config/schema.xml b/local/config/schema.xml index a9d7badc4..e6e68c4b2 100755 --- a/local/config/schema.xml +++ b/local/config/schema.xml @@ -605,6 +605,7 @@ + diff --git a/local/modules/Colissimo/Colissimo.php b/local/modules/Colissimo/Colissimo.php new file mode 100644 index 000000000..4d24cc059 --- /dev/null +++ b/local/modules/Colissimo/Colissimo.php @@ -0,0 +1,83 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Colissimo; + +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\HttpFoundation\Request; +use Thelia\Module\BaseModule; +use Thelia\Module\DeliveryModuleInterface; + +class Colissimo extends BaseModule implements DeliveryModuleInterface +{ + protected $request; + protected $dispatcher; + + public function setRequest(Request $request) + { + $this->request = $request; + } + + public function getRequest() + { + return $this->request; + } + + public function setDispatcher(EventDispatcherInterface $dispatcher) + { + $this->dispatcher = $dispatcher; + } + + public function getDispatcher() + { + return $this->dispatcher; + } + + /** + * + * calculate and return delivery price + * + * @param null $country + * @return mixed + */ + public function calculate($country = null) + { + // TODO: Implement calculate() method. + return 2; + } + + /** + * YOU HAVE TO IMPLEMENT HERE ABSTRACT METHODD FROM BaseModule Class + * Like install and destroy + */ + public function install() + { + // TODO: Implement install() method. + } + + public function destroy() + { + // TODO: Implement destroy() method. + } + +} diff --git a/local/modules/Colissimo/Config/config.xml b/local/modules/Colissimo/Config/config.xml new file mode 100644 index 000000000..2430f5027 --- /dev/null +++ b/local/modules/Colissimo/Config/config.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/templates/admin/default/product_attributes.html b/local/modules/Colissimo/Config/plugin.xml similarity index 100% rename from templates/admin/default/product_attributes.html rename to local/modules/Colissimo/Config/plugin.xml diff --git a/local/modules/Colissimo/Config/schema.xml b/local/modules/Colissimo/Config/schema.xml new file mode 100644 index 000000000..a4e2315b0 --- /dev/null +++ b/local/modules/Colissimo/Config/schema.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/local/modules/DebugBar/Config/config.xml b/local/modules/DebugBar/Config/config.xml new file mode 100644 index 000000000..6713c8ce6 --- /dev/null +++ b/local/modules/DebugBar/Config/config.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + %kernel.debug% + + + + + + + + + + + diff --git a/local/modules/DebugBar/Config/plugin.xml b/local/modules/DebugBar/Config/plugin.xml new file mode 100644 index 000000000..e69de29bb diff --git a/local/modules/DebugBar/Config/schema.xml b/local/modules/DebugBar/Config/schema.xml new file mode 100644 index 000000000..86ccca913 --- /dev/null +++ b/local/modules/DebugBar/Config/schema.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/local/modules/DebugBar/DataCollector/PropelCollector.php b/local/modules/DebugBar/DataCollector/PropelCollector.php new file mode 100644 index 000000000..881b1b64a --- /dev/null +++ b/local/modules/DebugBar/DataCollector/PropelCollector.php @@ -0,0 +1,236 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace DebugBar\DataCollector; +use Propel\Runtime\Propel; +use Psr\Log\LoggerInterface; + + +/** + * Class PropelCollector + * @package DebugBar\DataCollector + * @author Manuel Raynaud + */ +class PropelCollector extends DataCollector implements Renderable, LoggerInterface +{ + + protected $statements = array(); + + protected $accumulatedTime = 0; + + protected $peakMemory = 0; + + public function __construct() + { + $serviceContainer = Propel::getServiceContainer(); + $serviceContainer->setLogger('defaultLogger', $this); + + $con = Propel::getConnection(\Thelia\Model\Map\ProductTableMap::DATABASE_NAME); + $con->setLogMethods(array( + 'exec', + 'query', + 'execute', // these first three are the default + 'beginTransaction', + 'commit', + 'rollBack', + )); + } + + /** + * Called by the DebugBar when data needs to be collected + * + * @return array Collected data + */ + function collect() + { + return array( + 'nb_statements' => count($this->statements), + 'nb_failed_statements' => 0, + 'accumulated_duration' => '10', + 'accumulated_duration_str' => $this->formatDuration(1), + 'peak_memory_usage' => $this->peakMemory, + 'peak_memory_usage_str' => $this->formatBytes($this->peakMemory), + 'statements' => $this->statements + ); + } + + /** + * Returns the unique name of the collector + * + * @return string + */ + public function getName() + { + return 'propel'; + } + + /** + * Returns a hash where keys are control names and their values + * an array of options as defined in {@see DebugBar\JavascriptRenderer::addControl()} + * + * @return array + */ + public function getWidgets() + { + return array( + "propel" => array( + "widget" => "PhpDebugBar.Widgets.SQLQueriesWidget", + "map" => "propel", + "default" => "[]" + ), + "propel:badge" => array( + "map" => "propel.nb_statements", + "default" => 0 + ) + ); + } + + /** + * Logs with an arbitrary level. + * + * @param mixed $level + * @param string $message + * @param array $context + * @return null + */ + public function log($level, $message, array $context = array()) + { + $this->statements[] = array( + 'sql' => $message, + 'is_success' => true, + 'duration' => 0, + 'duration_str' => $this->formatDuration(1), + 'memory' => 1, + 'memory_str' => $this->formatBytes(1) + ); + } + + /** + * System is unusable. + * + * @param string $message + * @param array $context + * @return null + */ + public function emergency($message, array $context = array()) + { + $this->log(null, $message, $context); + } + + /** + * Action must be taken immediately. + * + * Example: Entire website down, database unavailable, etc. This should + * trigger the SMS alerts and wake you up. + * + * @param string $message + * @param array $context + * @return null + */ + public function alert($message, array $context = array()) + { + $this->log(null, $message, $context); + } + + /** + * Critical conditions. + * + * Example: Application component unavailable, unexpected exception. + * + * @param string $message + * @param array $context + * @return null + */ + public function critical($message, array $context = array()) + { + $this->log(null, $message, $context); + } + + /** + * Runtime errors that do not require immediate action but should typically + * be logged and monitored. + * + * @param string $message + * @param array $context + * @return null + */ + public function error($message, array $context = array()) + { + $this->log(null, $message, $context); + } + + /** + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things + * that are not necessarily wrong. + * + * @param string $message + * @param array $context + * @return null + */ + public function warning($message, array $context = array()) + { + $this->log(null, $message, $context); + } + + /** + * Normal but significant events. + * + * @param string $message + * @param array $context + * @return null + */ + public function notice($message, array $context = array()) + { + $this->log(null, $message, $context); + } + + /** + * Interesting events. + * + * Example: User logs in, SQL logs. + * + * @param string $message + * @param array $context + * @return null + */ + public function info($message, array $context = array()) + { + $this->log(null, $message, $context); + } + + /** + * Detailed debug information. + * + * @param string $message + * @param array $context + * @return null + */ + public function debug($message, array $context = array()) + { + $this->log(null, $message, $context); + } + + +} \ No newline at end of file diff --git a/core/lib/Thelia/Form/CategoryDeletionForm.php b/local/modules/DebugBar/DebugBar.php old mode 100755 new mode 100644 similarity index 81% rename from core/lib/Thelia/Form/CategoryDeletionForm.php rename to local/modules/DebugBar/DebugBar.php index 47c130fdd..7dde5fa8d --- a/core/lib/Thelia/Form/CategoryDeletionForm.php +++ b/local/modules/DebugBar/DebugBar.php @@ -20,25 +20,25 @@ /* along with this program. If not, see . */ /* */ /*************************************************************************************/ -namespace Thelia\Form; -use Symfony\Component\Validator\Constraints\NotBlank; +namespace DebugBar; -class CategoryDeletionForm extends BaseForm +use Thelia\Module\BaseModule; + +class DebugBar extends BaseModule { - protected function buildForm() + /** + * YOU HAVE TO IMPLEMENT HERE ABSTRACT METHODD FROM BaseModule Class + * Like install and destroy + */ + + public function install() { - $this->formBuilder - ->add("category_id", "integer", array( - "constraints" => array( - new NotBlank() - ) - )) - ; + // TODO: Implement install() method. } - public function getName() + public function destroy() { - return "thelia_category_deletion"; + // TODO: Implement destroy() method. } } diff --git a/local/modules/DebugBar/Listeners/DebugBarListeners.php b/local/modules/DebugBar/Listeners/DebugBarListeners.php new file mode 100644 index 000000000..7d0981d5d --- /dev/null +++ b/local/modules/DebugBar/Listeners/DebugBarListeners.php @@ -0,0 +1,72 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace DebugBar\Listeners; +use DebugBar\DataCollector\PropelCollector; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpKernel\KernelEvents; +use Thelia\Action\BaseAction; +use Thelia\Core\Event\TheliaEvents; + + +/** + * Class DebugBarListeners + * @package DebugBar\Listeners + * @author Manuel Raynaud + */ +class DebugBarListeners extends BaseAction implements EventSubscriberInterface { + + public function initDebugBar() + { + $debugBar = $this->container->get("debugBar"); + + $debugBar->addCollector(new PropelCollector()); + } + + /** + * Returns an array of event names this subscriber wants to listen to. + * + * The array keys are event names and the value can be: + * + * * The method name to call (priority defaults to 0) + * * An array composed of the method name to call and the priority + * * An array of arrays composed of the method names to call and respective + * priorities, or 0 if unset + * + * For instance: + * + * * array('eventName' => 'methodName') + * * array('eventName' => array('methodName', $priority)) + * * array('eventName' => array(array('methodName1', $priority), array('methodName2')) + * + * @return array The event names to listen to + * + * @api + */ + public static function getSubscribedEvents() + { + return array( + TheliaEvents::BOOT => array("initDebugBar", 128) + ); + } +} \ No newline at end of file diff --git a/local/modules/DebugBar/Smarty/Plugin/DebugBar.php b/local/modules/DebugBar/Smarty/Plugin/DebugBar.php new file mode 100644 index 000000000..9a333b1d6 --- /dev/null +++ b/local/modules/DebugBar/Smarty/Plugin/DebugBar.php @@ -0,0 +1,82 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace DebugBar\Smarty\Plugin; +use Thelia\Core\Template\Smarty\AbstractSmartyPlugin; +use Thelia\Core\Template\Smarty\an; +use Thelia\Core\Template\Smarty\SmartyPluginDescriptor; +use DebugBar\DebugBar as BaseDebugBar; + +/** + * Class DebugBar + * @author Manuel Raynaud + */ +class DebugBar extends AbstractSmartyPlugin +{ + protected $debugBar; + protected $debugMode; + + public function __construct(BaseDebugBar $debugbar, $debugMode) + { + $this->debugBar = $debugbar; + $this->debugMode = $debugMode; + } + + public function render($params, \Smarty_Internal_Template $template) + { + $render = ""; + if ($this->debugMode) { + $render = $this->debugBar->getJavascriptRenderer()->render(); + } + + return $render; + } + + public function renderHead($params, \Smarty_Internal_Template $template) + { + $render = ""; + if ($this->debugMode) { + $javascriptRenderer = $this->debugBar->getJavascriptRenderer(); + $assets = $javascriptRenderer->getAsseticCollection(); + + $cssCollection = $assets[0]; + $jsCollection = $assets[1]; + + $render .= sprintf('', $cssCollection->dump()); + $render .= sprintf('', $jsCollection->dump()); + } + + return $render; + } + + /** + * @return an array of SmartyPluginDescriptor + */ + public function getPluginDescriptors() + { + return array( + new SmartyPluginDescriptor("function", "debugbar_renderHead", $this, "renderHead"), + new SmartyPluginDescriptor("function", "debugbar_render", $this, "render") + ); + } +} \ No newline at end of file diff --git a/reset_install.bat b/reset_install.bat new file mode 100644 index 000000000..d117e525b --- /dev/null +++ b/reset_install.bat @@ -0,0 +1,35 @@ +echo off +REM @author Guillaume MOREL +REM v0.1 + +echo [WARN] This script will reset this Thelia2 install + +if exist local\config\database.yml ( + echo [INFO] Downloading vendors + composer install --prefer-dist + + cd local\config\ + + echo [INFO] Building Models file + ..\..\bin\propel build -v --output-dir=../../core/lib/ + + echo [INFO] Building SQL CREATE file + ..\..\bin\propel sql:build -v --output-dir=../../install/ + + + echo [INFO] Reloaded Thelia2 database + cd ..\.. + del install\sqldb.map + php Thelia thelia:dev:reloadDB + + echo [INFO] Installing fixtures + php install\faker.php + + echo [INFO] Adding admin + php Thelia thelia:create-admin + + echo [SUCCESS] Reset done +) +) else ( + echo [FAILED] Please add your database informations in local\config\database.yml and start this script again. +) \ No newline at end of file diff --git a/templates/admin/default/admin-layout.tpl b/templates/admin/default/admin-layout.tpl index 3752c355b..59004fdc7 100644 --- a/templates/admin/default/admin-layout.tpl +++ b/templates/admin/default/admin-layout.tpl @@ -18,11 +18,13 @@ {* -- Bootstrap CSS section --------------------------------------------- *} {block name="before-bootstrap-css"}{/block} - + {stylesheets file='assets/less/*' filters='less,cssembed'} {/stylesheets} + {debugbar_renderHead} + {block name="after-bootstrap-css"}{/block} {* -- Admin CSS section ------------------------------------------------- *} @@ -47,15 +49,15 @@
- +
{intl l='Version %ver' ver="{$THELIA_VERSION}"}
- {module_include location='inside_topbar'} - -
+ {module_include location='inside_topbar'} + +
- +
@@ -82,7 +84,7 @@ {module_include location='before_top_menu'} @@ -219,7 +230,7 @@ {/javascripts} {block name="javascript-initialization"}{/block} - + {debugbar_render} {* Modules scripts are included now *} {module_include location='footer_js'} diff --git a/templates/admin/default/categories.html b/templates/admin/default/categories.html index a3097f722..f08721828 100755 --- a/templates/admin/default/categories.html +++ b/templates/admin/default/categories.html @@ -8,9 +8,7 @@
- + {include file="includes/catalog-breadcrumb.html"} {module_include location='catalog_top'} @@ -20,7 +18,7 @@ + + @@ -59,8 +67,8 @@ current_order=$category_order order='visible' reverse_order='visible_reverse' - path={url path='/admin/catalog/category' id="{$current_category_id}"} - label={intl l='Online'} + path={url path='/admin/catalog' id_category=$current_category_id} + label="{intl l='Online'}" } @@ -69,8 +77,8 @@ current_order=$category_order order='manual' reverse_order='manual_reverse' - path={url path='/admin/catalog/category' id="{$current_category_id}"} - label={intl l='Position'} + path={url path='/admin/catalog' id_category=$current_category_id} + label="{intl l='Position'}" } @@ -81,22 +89,24 @@ {loop name="category_list" type="category" visible="*" parent=$current_category_id order=$category_order backend_context="1" lang=$lang_id} + + {module_include location='category_list_row'}
{* display parent category name, and get current cat ID *} - {loop name="category_title" type="category" visible="*" id="{$current_category_id}"} + {loop name="category_title" type="category" visible="*" id=$current_category_id} {intl l="Categories in %cat" cat=$TITLE} {$cat_id = $ID} {/loop} @@ -30,7 +28,7 @@ {module_include location='category_list_caption'} - {loop type="auth" name="can_create" roles="ADMIN" permissions="admin.category.create"} + {loop type="auth" name="can_create" roles="ADMIN" permissions="admin.categories.create"} @@ -40,6 +38,16 @@ {ifloop rel="category_list"}
+ {admin_sortable_header + current_order=$category_order + order='id' + reverse_order='id_reverse' + path={url path='/admin/catalog' id_category=$current_category_id} + label="{intl l='ID'}" + } +   @@ -47,8 +55,8 @@ current_order=$category_order order='alpha' reverse_order='alpha_reverse' - path={url path='/admin/catalog/category' id="{$current_category_id}"} - label={intl l='Category title'} + path={url path='/admin/catalog' id_category=$current_category_id} + label="{intl l='Category title'}" }
{$ID} - i={$ID} {loop type="image" name="cat_image" source="category" source_id="$ID" limit="1" width="50" height="50" resize_mode="crop" backend_context="1"} - #TITLE + {loop type="image" name="cat_image" source="category" source_id="$ID" limit="1" width="50" height="50" resize_mode="crop" backend_context="1"} + #TITLE {/loop} - - {$ID} p={$POSITION} {$TITLE} + + {$TITLE} - {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.category.edit"} + {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.categories.edit"}
@@ -111,24 +121,24 @@
{admin_position_block - permission="admin.category.edit" - path={url path='admin/catalog/category' category_id="{$ID}"} + permission="admin.categories.edit" + path={url path='admin/category/update-position' category_id=$ID} url_parameter="category_id" in_place_edit_class="categoryPositionChange" - position="$POSITION" - id="$ID" + position=$POSITION + id=$ID }
- + - {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.category.edit"} - + {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.categories.edit"} + {/loop} - {loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.category.delete"} + {loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.categories.delete"} {/loop}
@@ -143,7 +153,7 @@
- {loop type="auth" name="can_create" roles="ADMIN" permissions="admin.category.create"} + {loop type="auth" name="can_create" roles="ADMIN" permissions="admin.categories.create"} {intl l="This category has no sub-categories. To create a new one, click the + button above."} {/loop} @@ -166,9 +176,10 @@ + + + @@ -211,8 +241,8 @@ current_order=$product_order order='manual' reverse_order='manual_reverse' - path={url path='/admin/catalog/product' id="{$current_category_id}"} - label={intl l='Position'} + path={url path='/admin/product' category_id=$current_category_id} + label="{intl l='Position'}" } @@ -221,39 +251,58 @@ - {loop name="product_list" type="product" category="{$current_category_id}" order="manual"} + {loop name="product_list" type="product" category=$current_category_id order="manual"} + + + + + {module_include location='product_list_row'} {/loop} @@ -276,8 +325,82 @@ -{include file="includes/add-category-dialog.html"} -{include file="includes/delete-category-dialog.html"} + {* Adding a new Category *} + + + {form name="thelia.admin.category.creation"} + + {* Capture the dialog body, to pass it to the generic dialog *} + {capture "category_creation_dialog"} + + {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 object ID, see controller *} + + {/form_field} + + {form_field form=$form field='parent'} + + {/form_field} + + {form_field form=$form field='title'} +
+ + + {loop type="lang" name="default-lang" default_only="1"} + +
+ + $TITLE +
+ +
{intl l='Enter here the category name in the default language (%title)' title="$TITLE"}
+ + {* Switch edition to the current locale *} + + + {form_field form=$form field='locale'} + + {/form_field} + {/loop} +
+ {/form_field} + {/capture} + + {include + file = "includes/generic-create-dialog.html" + + dialog_id = "add_category_dialog" + dialog_title = {intl l="Create a new category"} + dialog_body = {$smarty.capture.category_creation_dialog nofilter} + + dialog_ok_label = {intl l="Create this category"} + dialog_cancel_label = {intl l="Cancel"} + + form_action = {url path='/admin/categories/create'} + form_enctype = {form_enctype form=$form} + form_error_message = $form_error_message + } + {/form} + + {* Delete category confirmation dialog *} + + {capture "category_delete_dialog"} + + + {/capture} + + {include + file = "includes/generic-confirm-dialog.html" + + dialog_id = "delete_category_dialog" + dialog_title = {intl l="Delete a category"} + dialog_message = {intl l="Do you really want to delete this category, and all its contents ?"} + + form_action = {url path='/admin/categories/delete'} + form_content = {$smarty.capture.category_delete_dialog nofilter} + } {/block} {block name="javascript-initialization"} @@ -290,68 +413,100 @@ {/javascripts} - + {* Inline editing of object position using bootstrap-editable *} + + $('.categoryPositionChange').editable({ + type : 'text', + title : '{intl l="Enter new category position"}', + mode : 'popup', + inputclass : 'input-mini', + placement : 'left', + success : function(response, newValue) { + // The URL template + var url = "{url path='/admin/categories/update-position' category_id='__ID__' position='__POS__'}"; + + // Perform subtitutions + url = url.replace('__ID__', $(this).data('id')) + .replace('__POS__', newValue); + + // Reload the page + location.href = url; + } + }); + + $('.productPositionChange').editable({ + type : 'text', + title : '{intl l="Enter new product position"}', + mode : 'popup', + inputclass : 'input-mini', + placement : 'left', + success : function(response, newValue) { + // The URL template + var url = "{url path='/admin/products/update-position' product_id='__ID__' position='__POS__'}"; + + // Perform subtitutions + url = url.replace('__ID__', $(this).data('id')) + .replace('__POS__', newValue); + + // Reload the page + location.href = url; + } + }); + +}) + {/block} \ No newline at end of file diff --git a/templates/admin/default/edit_category.html b/templates/admin/default/category-edit.html similarity index 99% rename from templates/admin/default/edit_category.html rename to templates/admin/default/category-edit.html index 85e6d42bd..13327ca3d 100755 --- a/templates/admin/default/edit_category.html +++ b/templates/admin/default/category-edit.html @@ -7,9 +7,8 @@ {block name="main-content"}
- + + {include file="includes/catalog-breadcrumb.html"}
{loop name="category_edit" type="category" visible="*" id="{$current_category_id}" backend_context="1" lang="$edit_language_id"} @@ -27,6 +26,7 @@
+
- + {loop name="mailing-templates" type="message" secured="*" backend_context="1" lang="$lang_id"} @@ -71,7 +71,7 @@ {/loop} {loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.configuration.messages.delete"} - + {/loop} {else} @@ -79,7 +79,7 @@ {/if} - {/loop} + {/loop} {elseloop rel="mailing-templates"}
{* display parent category name *} - {loop name="category_title" type="category" visible="*" id="{$current_category_id}"} + {loop name="category_title" type="category" visible="*" id=$current_category_id} {intl l="Products in %cat" cat=$TITLE} {/loop} + {elseloop rel="category_title"} {intl l="Top level Products"} {/elseloop} @@ -183,15 +194,34 @@ {ifloop rel="product_list"}
+ {admin_sortable_header + current_order=$product_order + order='id' + reverse_order='id_reverse' + path={url path='/admin/product' category_id=$current_category_id} + label="{intl l='ID'}" + } +   + {admin_sortable_header + current_order=$product_order + order='ref' + reverse_order='ref_reverse' + path={url path='/admin/product' category_id=$current_category_id} + label="{intl l='Reference'}" + } + {admin_sortable_header current_order=$product_order order='alpha' reverse_order='alpha_reverse' - path={url path='/admin/catalog/product' id="{$current_category_id}"} - label={intl l='Product title'} + path={url path='/admin/product' category_id=$current_category_id} + label="{intl l='Product title'}" } {module_include location='product_list_header'} @@ -201,8 +231,8 @@ current_order=$product_order order='visible' reverse_order='visible_reverse' - path={url path='/admin/catalog/product' id="{$current_category_id}"} - label={intl l='Online'} + path={url path='/admin/product' category_id=$current_category_id} + label="{intl l='Online'}" }
{$ID} {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} - {$TITLE}{$REF}{$TITLE} + {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.products.edit"} +
+ +
+ {/loop} + + {elseloop rel="can_change"}
+ {/elseloop}
{admin_position_block permission="admin.product.edit" - path={url path='admin/catalog/product' category_id="{$ID}"} + path={url path='admin/product' category_id=$ID} url_parameter="product_id" in_place_edit_class="productPositionChange" - position="$POSITION" - id="$ID" + position=$POSITION + id=$ID } - - +
+ {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.product.edit"} + + {/loop} + + {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.product.delete"} + + {/loop} +
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.currencies.change"} - {$NAME} + {$NAME} {/loop} {elseloop rel="can_change"} {$NAME} @@ -163,7 +163,7 @@ {/loop} {loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.configuration.currencies.delete"} - + {/loop} @@ -199,116 +199,96 @@ {* Adding a new currency *} - + form_action = {url path='/admin/configuration/currencies/create'} + form_enctype = {form_enctype form=$form} + form_error_message = $form_error_message + } + {/form} {* Delete confirmation dialog *} - + form_action = {url path='/admin/configuration/currencies/delete'} + form_content = {$smarty.capture.delete_dialog nofilter} + } {/block} {block name="javascript-initialization"} @@ -329,27 +309,12 @@ $('#currency_delete_id').val($(this).data('id')); }); - {* display the form creation dialog if it contains errors *} - - {form name="thelia.admin.currency.creation"} - {if #form_error} - $('#add_currency_dialog').modal(); - {/if} - {/form} - - {* Always reset create dialog on close *} - - $('#add_currency_dialog').on('hidden',function() { - - // Hide error currency - $('#add_currency_dialog_error').remove(); - - // Clear error status - $("#add_currency_dialog .error").removeClass('error'); - - // Empty field values - $("#add_currency_dialog input[type=text]").val(''); - }); + // JS stuff for creation form + {include + file = "includes/generic-js-dialog.html" + dialog_id = "creation_dialog" + form_name = "thelia.admin.currency.creation" + } {* Inline editing of object position using bootstrap-editable *} diff --git a/templates/admin/default/includes/add-category-dialog.html b/templates/admin/default/includes/add-category-dialog.html deleted file mode 100755 index 631d0c06e..000000000 --- a/templates/admin/default/includes/add-category-dialog.html +++ /dev/null @@ -1,70 +0,0 @@ - -{* Adding a new Category *} - - \ No newline at end of file diff --git a/templates/admin/default/includes/catalog-breadcrumb.html b/templates/admin/default/includes/catalog-breadcrumb.html new file mode 100644 index 000000000..b9312f0dd --- /dev/null +++ b/templates/admin/default/includes/catalog-breadcrumb.html @@ -0,0 +1,26 @@ +{* Breadcrumb for categories browsing and editing *} + + \ No newline at end of file diff --git a/templates/admin/default/includes/category_breadcrumb.html b/templates/admin/default/includes/category_breadcrumb.html deleted file mode 100755 index bf14142b5..000000000 --- a/templates/admin/default/includes/category_breadcrumb.html +++ /dev/null @@ -1,13 +0,0 @@ -{* Breadcrumb for categories browsing and editing *} - -
  • Home
  • -
  • Catalog {ifloop rel="category_path"}
  • - -{loop name="category_path" type="category-path" visible="*" category="{$current_category_id}"} {if $ID == $current_category_id} -
  • {if $action == 'edit'} {intl l='Editing %cat' cat="{$TITLE}"} {else} {$TITLE} {intl l="(edit)"} {/if} -
  • -{else} -
  • {$TITLE}
  • -{/if} {/loop} {/ifloop} {elseloop rel="category_path"} - -{/elseloop} diff --git a/templates/admin/default/includes/delete-category-dialog.html b/templates/admin/default/includes/delete-category-dialog.html deleted file mode 100755 index 38e93a340..000000000 --- a/templates/admin/default/includes/delete-category-dialog.html +++ /dev/null @@ -1,48 +0,0 @@ - -{* Adding a new Category *} - - diff --git a/templates/admin/default/includes/generic-confirm-dialog.html b/templates/admin/default/includes/generic-confirm-dialog.html new file mode 100644 index 000000000..b5f3ad700 --- /dev/null +++ b/templates/admin/default/includes/generic-confirm-dialog.html @@ -0,0 +1,43 @@ +{* + +A generic modal confirmation dialog template. + +Parameters: + + dialog_id = the dialog id attribute + dialog_title = the dialog title + dialog_message = the dialog confirmation message + + dialog_ok_label = The OK button label (default: yes) + dialog_cancel_label = The Cancel button label (default: no) + + form_action = the form action URL, subtitted by a click on OK button + form_method = the form method, default "POST" + form_content = the form content + +*} + \ No newline at end of file diff --git a/templates/admin/default/includes/generic-create-dialog.html b/templates/admin/default/includes/generic-create-dialog.html new file mode 100755 index 000000000..c6a00a01b --- /dev/null +++ b/templates/admin/default/includes/generic-create-dialog.html @@ -0,0 +1,43 @@ +{* + +A generic modal creation dialog template. Parameters + + dialog_id = the dialog id attribute + dialog_title = the dialog title + dialog_body = the dialog body. In most cases, this is a creation form + + dialog_ok_label = The OK button label. Default create + dialog_cancel_label = The cancel button label. Default create + + form_action = The form action URL. Form is submitted when OK button is clicked + form_enctype = The form encoding + form_error_message = The form error message (optional) +*} + diff --git a/templates/admin/default/includes/generic-js-dialog.html b/templates/admin/default/includes/generic-js-dialog.html new file mode 100644 index 000000000..f1be39f03 --- /dev/null +++ b/templates/admin/default/includes/generic-js-dialog.html @@ -0,0 +1,35 @@ +{* +Javascript code to manage create dialog. Insert it in your template, in the javascript +initialisation: + + $(function() { + + } + +Parameters: + $dialog_id = the dialog ID + $form_name = the form name + +*} + +{* re-display the form creation dialog if it contains errors *} + +{form name="{$form_name}"} + {if #form_error} + $('#{$dialog_id}').modal(); + {/if} +{/form} + +{* Always reset create dialog on close *} + +$('#{$dialog_id}').on('hidden', function() { + + // Hide error message + $('#{$dialog_id}_error').remove(); + + // Clear error status + $("#{$dialog_id} .error").removeClass('error'); + + // Empty field values + $("#{$dialog_id} input[type=text]").val(''); +}); \ No newline at end of file diff --git a/templates/admin/default/messages.html b/templates/admin/default/messages.html index 08031bd3c..755388fcf 100644 --- a/templates/admin/default/messages.html +++ b/templates/admin/default/messages.html @@ -25,7 +25,7 @@
    {intl l='Thelia mailing templates'} {loop type="auth" name="can_create" roles="ADMIN" permissions="admin.configuration.messages.create"} - + {/loop} @@ -41,7 +41,7 @@
     
    @@ -102,110 +102,89 @@ -{* Adding a new message *} - - + {* Adding a new message *} -{* Delete confirmation dialog *} + {form name="thelia.admin.message.creation"} - + {form_field form=$form field='title'} +
    + + + {loop type="lang" name="default-lang" default_only="1"} + + {* Switch edition to the current locale *} + + +
    + + {intl l=$TITLE} +
    + +
    {intl l="Enter here the mailing template purpose in the default language ($TITLE)"}
    + + {form_field form=$form field='locale'} + + {/form_field} + {/loop} + +
    + {/form_field} + {/capture} + + {include + file = "includes/generic-create-dialog.html" + + dialog_id = "creation_dialog" + dialog_title = {intl l="Create a new mailing template"} + dialog_body = {$smarty.capture.creation_dialog nofilter} + + dialog_ok_label = {intl l="Create this mailing template"} + + form_action = {url path='/admin/configuration/messages/create'} + form_enctype = {form_enctype form=$form} + form_error_message = $form_error_message + } + {/form} + + {* Delete confirmation dialog *} + + {capture "delete_dialog"} + + {/capture} + + {include + file = "includes/generic-confirm-dialog.html" + + dialog_id = "delete_dialog" + dialog_title = {intl l="Delete mailing template"} + dialog_message = {intl l="Do you really want to delete this mailing template ?"} + + form_action = {url path='/admin/configuration/messages/delete'} + form_content = {$smarty.capture.delete_dialog nofilter} + } {/block} {block name="javascript-initialization"} @@ -217,26 +196,12 @@ $('#message_delete_id').val($(this).data('id')); }); - {* display the form creation dialog if it contains errors *} - - {form name="thelia.admin.message.creation"} - {if #form_error} - $('#add_message_dialog').modal(); - {/if} - {/form} - - {* Always reset create dialog on close *} - - $('#add_message_dialog').on('hidden',function() { - // Hide error message - $('#add_message_dialog_error').remove(); - - // Clear error status - $("#add_message_dialog .error").removeClass('error'); - - // Empty field values - $("#add_message_dialog input[type=text]").val(''); - }); + // JS stuff for creation form + {include + file = "includes/generic-js-dialog.html" + dialog_id = "creation_dialog" + form_name = "thelia.admin.message.creation" + } }); {/block} \ No newline at end of file diff --git a/templates/admin/default/product-attributes-edit.html b/templates/admin/default/product-attributes-edit.html new file mode 100644 index 000000000..30d74d258 --- /dev/null +++ b/templates/admin/default/product-attributes-edit.html @@ -0,0 +1 @@ +test \ No newline at end of file diff --git a/templates/admin/default/product-attributes.html b/templates/admin/default/product-attributes.html new file mode 100644 index 000000000..921674b03 --- /dev/null +++ b/templates/admin/default/product-attributes.html @@ -0,0 +1,142 @@ +{extends file="admin-layout.tpl"} + +{block name="page-title"}{intl l='Thelia Product Attributes'}{/block} + +{block name="check-permissions"}admin.configuration.product_attributes.view{/block} + +{block name="main-content"} +
    + +
    + + + +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + +
    + {intl l='Thelia product attributes'} + + + + +
    {intl l="Title"}{intl l="Position"}{intl l="Actions"}
    Title here1 +
    + + + +
    +
    +
    +
    +
    +
    + +
    +
    + + +{* Adding a new message *} + + + + +{* Delete confirmation dialog *} + + +{/block} \ No newline at end of file diff --git a/templates/admin/default/variables.html b/templates/admin/default/variables.html index 6373618f9..0d1c948a0 100644 --- a/templates/admin/default/variables.html +++ b/templates/admin/default/variables.html @@ -26,7 +26,7 @@ {intl l='Thelia system variables'} {loop type="auth" name="can_create" roles="ADMIN" permissions="admin.configuration.variables.create"}
    - + @@ -135,148 +135,116 @@ {* Adding a new variable *} - + {include + file = "includes/generic-create-dialog.html" + dialog_id = "creation_dialog" + dialog_title = {intl l="Create a new variable"} + dialog_body = {$smarty.capture.creation_dialog nofilter} -{* Delete confirmation dialog *} + dialog_ok_label = {intl l="Create this variable"} - + dialog_id = "delete_variable_dialog" + dialog_title = {intl l="Delete a variable"} + dialog_message = {intl l="Do you really want to delete this variable ?"} + + form_action = {url path='/admin/configuration/variables/delete'} + form_content = {$smarty.capture.delete_dialog nofilter} + } {/block} {block name="javascript-initialization"} - + {debugbar_render} \ No newline at end of file diff --git a/templates/default/includes/header.html b/templates/default/includes/header.html index 38e78478e..b605ecbb7 100755 --- a/templates/default/includes/header.html +++ b/templates/default/includes/header.html @@ -7,6 +7,7 @@ {stylesheets file='../assets/css/*' filters='less,cssembed'} {/stylesheets} + {debugbar_renderHead}