Started category management

This commit is contained in:
franck
2013-09-16 18:58:45 +02:00
parent 5a7794b0cc
commit 2f41d4db6f
32 changed files with 772 additions and 1211 deletions

View File

@@ -24,52 +24,88 @@
namespace Thelia\Action;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Model\Category as CategoryModel;
use Thelia\Model\CategoryQuery;
use Thelia\Model\Category as CategoryModel;
use Propel\Runtime\ActiveQuery\Criteria;
use Propel\Runtime\Propel;
use Thelia\Model\Map\CategoryTableMap;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\Event\CategoryUpdateEvent;
use Thelia\Core\Event\CategoryCreateEvent;
use Thelia\Core\Event\CategoryDeleteEvent;
use Thelia\Model\ConfigQuery;
use Thelia\Core\Event\UpdatePositionEvent;
use Thelia\Core\Event\CategoryToggleVisibilityEvent;
use Thelia\Core\Event\CategoryChangePositionEvent;
class Category extends BaseAction implements EventSubscriberInterface
{
/**
* Create a new category entry
*
* @param CategoryCreateEvent $event
*/
public function create(CategoryCreateEvent $event)
{
$category = new CategoryModel();
$category
->setDispatcher($this->getDispatcher())
->create(
$event->getTitle(),
$event->getParent(),
$event->getLocale()
);
->setLocale($event->getLocale())
->setTitle($event->getTitle())
->setParent($event->getParent())
->setVisible($event->getVisible())
->save()
;
$event->setCategory($category);
}
public function update(CategoryChangeEvent $event)
/**
* Change a category
*
* @param CategoryUpdateEvent $event
*/
public function update(CategoryUpdateEvent $event)
{
$search = CategoryQuery::create();
if (null !== $category = CategoryQuery::create()->findPk($event->getCategoryId())) {
$category
->setDispatcher($this->getDispatcher())
->setLocale($event->getLocale())
->setTitle($event->getTitle())
->setDescription($event->getDescription())
->setChapo($event->getChapo())
->setPostscriptum($event->getPostscriptum())
->setParent($event->getParent())
->setVisible($event->getVisible())
->save();
$event->setCategory($category);
}
}
/**
* Delete a category
* Delete a category entry
*
* @param ActionEvent $event
* @param CategoryDeleteEvent $event
*/
public function delete(CategoryDeleteEvent $event)
{
$category = CategoryQuery::create()->findPk($event->getCategoryId());
if (null !== $category = CategoryQuery::create()->findPk($event->getCategoryId())) {
if ($category !== null) {
$category
->setDispatcher($this->getDispatcher())
->delete()
;
$category->setDispatcher($this->getDispatcher())->delete();
$event->setCategory($category);
}
}
@@ -80,178 +116,48 @@ class Category extends BaseAction implements EventSubscriberInterface
*/
public function toggleVisibility(CategoryToggleVisibilityEvent $event)
{
$category = CategoryQuery::create()->findPk($event->getCategoryId());
$category = $event->getCategory();
if ($category !== null) {
$category
->setDispatcher($this->getDispatcher())
->setVisible($category->getVisible() ? false : true)
->save()
$category
->setDispatcher($this->getDispatcher())
->setVisible($category->getVisible() ? false : true)
->save()
;
}
/**
* Changes position, selecting absolute ou relative change.
*
* @param CategoryChangePositionEvent $event
*/
public function updatePosition(UpdatePositionEvent $event)
{
if (null !== $category = CategoryQuery::create()->findPk($event->getObjectId())) {
$category->setDispatcher($this->getDispatcher());
$mode = $event->getMode();
if ($mode == UpdatePositionEvent::POSITION_ABSOLUTE)
return $category->changeAbsolutePosition($event->getPosition());
else if ($mode == UpdatePositionEvent::POSITION_UP)
return $category->movePositionUp();
else if ($mode == UpdatePositionEvent::POSITION_DOWN)
return $category->movePositionDown();
}
}
/**
* Changes category position, selecting absolute ou relative change.
*
* @param CategoryChangePositionEvent $event
*/
public function changePosition(CategoryChangePositionEvent $event)
{
if ($event->getMode() == CategoryChangePositionEvent::POSITION_ABSOLUTE)
return $this->changeAbsolutePosition($event);
else
return $this->exchangePosition($event);
}
/**
* Move up or down a category
*
* @param CategoryChangePositionEvent $event
*/
protected function exchangePosition(CategoryChangePositionEvent $event)
{
$category = CategoryQuery::create()->findPk($event->getCategoryId());
if ($category !== null) {
// The current position of the category
$my_position = $category->getPosition();
// Find category to exchange position with
$search = CategoryQuery::create()
->filterByParent($category->getParent());
// Up or down ?
if ($event->getMode() == CategoryChangePositionEvent::POSITION_UP) {
// Find the category immediately before me
$search->filterByPosition(array('max' => $my_position-1))->orderByPosition(Criteria::DESC);
} elseif ($event->getMode() == CategoryChangePositionEvent::POSITION_DOWN) {
// Find the category immediately after me
$search->filterByPosition(array('min' => $my_position+1))->orderByPosition(Criteria::ASC);
} else
return;
$result = $search->findOne();
// If we found the proper category, exchange their positions
if ($result) {
$cnx = Propel::getWriteConnection(CategoryTableMap::DATABASE_NAME);
$cnx->beginTransaction();
try {
$category
->setDispatcher($this->getDispatcher())
->setPosition($result->getPosition())
->save()
;
$result->setPosition($my_position)->save();
$cnx->commit();
} catch (Exception $e) {
$cnx->rollback();
}
}
}
}
/**
* Changes category position
*
* @param CategoryChangePositionEvent $event
*/
protected function changeAbsolutePosition(CategoryChangePositionEvent $event)
{
$category = CategoryQuery::create()->findPk($event->getCategoryId());
if ($category !== null) {
// The required position
$new_position = $event->getPosition();
// The current position
$current_position = $category->getPosition();
if ($new_position != null && $new_position > 0 && $new_position != $current_position) {
// Find categories to offset
$search = CategoryQuery::create()->filterByParent($category->getParent());
if ($new_position > $current_position) {
// The new position is after the current position -> we will offset + 1 all categories located between us and the new position
$search->filterByPosition(array('min' => 1+$current_position, 'max' => $new_position));
$delta = -1;
} else {
// The new position is brefore the current position -> we will offset - 1 all categories located between us and the new position
$search->filterByPosition(array('min' => $new_position, 'max' => $current_position - 1));
$delta = 1;
}
$results = $search->find();
$cnx = Propel::getWriteConnection(CategoryTableMap::DATABASE_NAME);
$cnx->beginTransaction();
try {
foreach ($results as $result) {
$result->setPosition($result->getPosition() + $delta)->save($cnx);
}
$category
->setDispatcher($this->getDispatcher())
->setPosition($new_position)
->save($cnx)
;
$cnx->commit();
} catch (Exception $e) {
$cnx->rollback();
}
}
}
}
/**
* Returns an array of event names this subscriber listens 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
* {@inheritDoc}
*/
public static function getSubscribedEvents()
{
return array(
TheliaEvents::CATEGORY_CREATE => array("create", 128),
TheliaEvents::CATEGORY_UPDATE => array("update", 128),
TheliaEvents::CATEGORY_DELETE => array("delete", 128),
TheliaEvents::CATEGORY_CREATE => array("create", 128),
TheliaEvents::CATEGORY_UPDATE => array("update", 128),
TheliaEvents::CATEGORY_DELETE => array("delete", 128),
TheliaEvents::CATEGORY_TOGGLE_VISIBILITY => array("toggleVisibility", 128),
TheliaEvents::CATEGORY_CHANGE_POSITION => array("changePosition", 128),
"action.updateCategoryPositionU" => array("changePositionUp", 128),
"action.updateCategoryPositionDown" => array("changePositionDown", 128),
"action.updateCategoryPosition" => array("changePosition", 128),
TheliaEvents::CATEGORY_UPDATE_POSITION => array("updatePosition", 128)
);
}
}

View File

@@ -22,7 +22,6 @@
/*************************************************************************************/
namespace Thelia\Action;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Thelia\Model\ConfigQuery;
@@ -45,18 +44,9 @@ class Config extends BaseAction implements EventSubscriberInterface
{
$config = new ConfigModel();
$config
->setDispatcher($this->getDispatcher())
->setName($event->getEventName())
->setValue($event->getValue())
->setLocale($event->getLocale())
->setTitle($event->getTitle())
->setHidden($event->getHidden())
->setSecured($event->getSecured())
->save()
;
$config->setDispatcher($this->getDispatcher())->setName($event->getEventName())->setValue($event->getValue())
->setLocale($event->getLocale())->setTitle($event->getTitle())->setHidden($event->getHidden())
->setSecured($event->getSecured())->save();
$event->setConfig($config);
}
@@ -70,18 +60,13 @@ class Config extends BaseAction implements EventSubscriberInterface
{
$search = ConfigQuery::create();
if (null !== $config = $search->findOneById($event->getConfigId())) {
if (null !== $config = $search->findPk($event->getConfigId())) {
if ($event->getValue() !== $config->getValue()) {
$config
->setDispatcher($this->getDispatcher())
$config->setDispatcher($this->getDispatcher())->setValue($event->getValue())->save();
->setValue($event->getValue())
->save()
;
$event->setConfig($config);
$event->setConfig($config);
}
}
}
@@ -95,23 +80,12 @@ class Config extends BaseAction implements EventSubscriberInterface
{
$search = ConfigQuery::create();
if (null !== $config = ConfigQuery::create()->findOneById($event->getConfigId())) {
if (null !== $config = ConfigQuery::create()->findPk($event->getConfigId())) {
$config
->setDispatcher($this->getDispatcher())
->setName($event->getEventName())
->setValue($event->getValue())
->setHidden($event->getHidden())
->setSecured($event->getSecured())
->setLocale($event->getLocale())
->setTitle($event->getTitle())
->setDescription($event->getDescription())
->setChapo($event->getChapo())
->setPostscriptum($event->getPostscriptum())
->save();
$config->setDispatcher($this->getDispatcher())->setName($event->getEventName())->setValue($event->getValue())
->setHidden($event->getHidden())->setSecured($event->getSecured())->setLocale($event->getLocale())
->setTitle($event->getTitle())->setDescription($event->getDescription())->setChapo($event->getChapo())
->setPostscriptum($event->getPostscriptum())->save();
$event->setConfig($config);
}
@@ -125,14 +99,11 @@ class Config extends BaseAction implements EventSubscriberInterface
public function delete(ConfigDeleteEvent $event)
{
if (null !== ($config = ConfigQuery::create()->findOneById($event->getConfigId()))) {
if (null !== ($config = ConfigQuery::create()->findPk($event->getConfigId()))) {
if (! $config->getSecured()) {
if (!$config->getSecured()) {
$config
->setDispatcher($this->getDispatcher())
->delete()
;
$config->setDispatcher($this->getDispatcher())->delete();
$event->setConfig($config);
}
@@ -145,10 +116,15 @@ class Config extends BaseAction implements EventSubscriberInterface
public static function getSubscribedEvents()
{
return array(
TheliaEvents::CONFIG_CREATE => array("create", 128),
TheliaEvents::CONFIG_SETVALUE => array("setValue", 128),
TheliaEvents::CONFIG_UPDATE => array("modify", 128),
TheliaEvents::CONFIG_DELETE => array("delete", 128),
TheliaEvents::CONFIG_CREATE => array(
"create", 128
), TheliaEvents::CONFIG_SETVALUE => array(
"setValue", 128
), TheliaEvents::CONFIG_UPDATE => array(
"modify", 128
), TheliaEvents::CONFIG_DELETE => array(
"delete", 128
),
);
}
}

View File

@@ -71,7 +71,7 @@ class Currency extends BaseAction implements EventSubscriberInterface
{
$search = CurrencyQuery::create();
if (null !== $currency = CurrencyQuery::create()->findOneById($event->getCurrencyId())) {
if (null !== $currency = CurrencyQuery::create()->findPk($event->getCurrencyId())) {
$currency
->setDispatcher($this->getDispatcher())
@@ -97,7 +97,7 @@ class Currency extends BaseAction implements EventSubscriberInterface
{
$search = CurrencyQuery::create();
if (null !== $currency = CurrencyQuery::create()->findOneById($event->getCurrencyId())) {
if (null !== $currency = CurrencyQuery::create()->findPk($event->getCurrencyId())) {
if ($currency->getByDefault() != $event->getIsDefault()) {
@@ -123,7 +123,7 @@ class Currency extends BaseAction implements EventSubscriberInterface
public function delete(CurrencyDeleteEvent $event)
{
if (null !== ($currency = CurrencyQuery::create()->findOneById($event->getCurrencyId()))) {
if (null !== ($currency = CurrencyQuery::create()->findPk($event->getCurrencyId()))) {
$currency
->setDispatcher($this->getDispatcher())

View File

@@ -70,7 +70,7 @@ class Message extends BaseAction implements EventSubscriberInterface
{
$search = MessageQuery::create();
if (null !== $message = MessageQuery::create()->findOneById($event->getMessageId())) {
if (null !== $message = MessageQuery::create()->findPk($event->getMessageId())) {
$message
->setDispatcher($this->getDispatcher())
@@ -99,7 +99,7 @@ class Message extends BaseAction implements EventSubscriberInterface
public function delete(MessageDeleteEvent $event)
{
if (null !== ($message = MessageQuery::create()->findOneById($event->getMessageId()))) {
if (null !== ($message = MessageQuery::create()->findPk($event->getMessageId()))) {
$message
->setDispatcher($this->getDispatcher())

View File

@@ -51,7 +51,7 @@
<form name="thelia.address.update" class="Thelia\Form\AddressUpdateForm" />
<form name="thelia.admin.category.creation" class="Thelia\Form\CategoryCreationForm"/>
<form name="thelia.admin.category.deletion" class="Thelia\Form\CategoryModificationForm"/>
<form name="thelia.admin.category.modification" class="Thelia\Form\CategoryModificationForm"/>
<form name="thelia.admin.product.creation" class="Thelia\Form\ProductCreationForm"/>
<form name="thelia.admin.product.deletion" class="Thelia\Form\ProductModificationForm"/>

View File

@@ -85,7 +85,7 @@
</route>
<route id="admin.categories.set-default" path="/admin/categories/toggle-online">
<default key="_controller">Thelia\Controller\Admin\CategoryController::toggleOnlineAction</default>
<default key="_controller">Thelia\Controller\Admin\CategoryController::setToggleVisibilityAction</default>
</route>
<route id="admin.categories.delete" path="/admin/categories/delete">

View File

@@ -240,6 +240,17 @@ abstract class AbstractCrudController extends BaseAdminController
return null;
}
/**
* Put in this method post object position change processing if required.
*
* @param unknown $deleteEvent the delete event
* @return Response a response, or null to continue normal processing
*/
protected function performAdditionalUpdatePositionAction($positionChangeEvent)
{
return null;
}
/**
* Return the current list order identifier, updating it in the same time.
*/
@@ -309,14 +320,18 @@ abstract class AbstractCrudController extends BaseAdminController
$this->adminLogAppend(sprintf("%s %s (ID %s) created", ucfirst($this->objectName), $this->getObjectLabel($createdObject), $this->getObjectId($createdObject)));
}
$this->performAdditionalCreateAction($createEvent);
$response = $this->performAdditionalCreateAction($createEvent);
// Substitute _ID_ in the URL with the ID of the created object
$successUrl = str_replace('_ID_', $this->getObjectId($createdObject), $creationForm->getSuccessUrl());
// Redirect to the success URL
$this->redirect($successUrl);
if ($response == null) {
// Substitute _ID_ in the URL with the ID of the created object
$successUrl = str_replace('_ID_', $this->getObjectId($createdObject), $creationForm->getSuccessUrl());
// Redirect to the success URL
$this->redirect($successUrl);
}
else {
return $response;
}
}
catch (FormValidationException $ex) {
// Form cannot be validated
@@ -396,16 +411,21 @@ abstract class AbstractCrudController extends BaseAdminController
$this->adminLogAppend(sprintf("%s %s (ID %s) modified", ucfirst($this->objectName), $this->getObjectLabel($changedObject), $this->getObjectId($changedObject)));
}
$this->performAdditionalUpdateAction($changeEvent);
$response = $this->performAdditionalUpdateAction($changeEvent);
// 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->redirectToEditionTemplate($this->getRequest());
if ($response == null) {
// 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->redirectToEditionTemplate($this->getRequest());
}
// Redirect to the success URL
$this->redirect($changeForm->getSuccessUrl());
}
else {
return $response;
}
// Redirect to the success URL
$this->redirect($changeForm->getSuccessUrl());
}
catch (FormValidationException $ex) {
// Form cannot be validated
@@ -452,7 +472,14 @@ abstract class AbstractCrudController extends BaseAdminController
return $this->errorPage($ex);
}
$this->redirectToListTemplate();
$response = $this->performAdditionalUpdatePositionAction($event);
if ($response == null) {
$this->redirectToListTemplate();
}
else {
return $response;
}
}
/**
@@ -475,7 +502,7 @@ abstract class AbstractCrudController extends BaseAdminController
return $this->errorPage($ex);
}
$this->redirectToRoute('admin.categories.default');
$this->redirectToListTemplate();
}
/**

View File

@@ -33,7 +33,7 @@ use Thelia\Form\AttributeAvCreationForm;
use Thelia\Core\Event\UpdatePositionEvent;
/**
* Manages attributes-av sent by mail
* Manages attributes-av
*
* @author Franck Allimant <franck@cqfdev.fr>
*/

View File

@@ -37,7 +37,7 @@ use Thelia\Core\Event\AttributeAvUpdateEvent;
use Thelia\Core\Event\AttributeEvent;
/**
* Manages attributes sent by mail
* Manages attributes
*
* @author Franck Allimant <franck@cqfdev.fr>
*/

View File

@@ -23,226 +23,160 @@
namespace Thelia\Controller\Admin;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\Event\CategoryCreateEvent;
use Thelia\Form\CategoryCreationForm;
use Thelia\Core\Event\CategoryDeleteEvent;
use Thelia\Core\Event\CategoryUpdatePositionEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\Event\CategoryUpdateEvent;
use Thelia\Core\Event\CategoryCreateEvent;
use Thelia\Model\CategoryQuery;
use Thelia\Form\CategoryModificationForm;
use Thelia\Form\CategoryCreationForm;
use Thelia\Core\Event\UpdatePositionEvent;
use Thelia\Core\Event\CategoryToggleVisibilityEvent;
class CategoryController extends BaseAdminController
/**
* Manages categories
*
* @author Franck Allimant <franck@cqfdev.fr>
*/
class CategoryController extends AbstractCrudController
{
/**
* 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());
public function __construct() {
parent::__construct(
'category',
'manual',
'category_order',
'admin.categories.default',
'admin.categories.create',
'admin.categories.update',
'admin.categories.delete',
TheliaEvents::CATEGORY_CREATE,
TheliaEvents::CATEGORY_UPDATE,
TheliaEvents::CATEGORY_DELETE,
TheliaEvents::CATEGORY_TOGGLE_VISIBILITY,
TheliaEvents::CATEGORY_UPDATE_POSITION
);
}
protected function getTemplateArgs()
{
// Get the category ID
$category_id = $this->getRequest()->get('category_id', 0);
protected function getCreationForm() {
return new CategoryCreationForm($this->getRequest());
}
// Find the current category order
$category_order = $this->getRequest()->get(
'order',
$this->getSession()->get('admin.category_order', 'manual')
protected function getUpdateForm() {
return new CategoryModificationForm($this->getRequest());
}
protected function getCreationEvent($formData) {
$createEvent = new CategoryCreateEvent();
$createEvent
->setTitle($formData['title'])
->setLocale($formData["locale"])
->setParent($formData['parent'])
->setVisible($formData['visible'])
;
return $createEvent;
}
protected function getUpdateEvent($formData) {
$changeEvent = new CategoryUpdateEvent($formData['id']);
// Create and dispatch the change event
$changeEvent
->setLocale($formData['locale'])
->setTitle($formData['title'])
->setChapo($formData['chapo'])
->setDescription($formData['description'])
->setPostscriptum($formData['postscriptum'])
->setVisible($formData['visible'])
->setUrl($formData['url'])
->setParent($formData['parent'])
;
return $changeEvent;
}
protected function createUpdatePositionEvent($positionChangeMode, $positionValue) {
return new UpdatePositionEvent(
$this->getRequest()->get('category_id', null),
$positionChangeMode,
$positionValue
);
}
protected function getDeleteEvent() {
return new CategoryDeleteEvent($this->getRequest()->get('category_id', 0));
}
protected function eventContainsObject($event) {
return $event->hasCategory();
}
protected function hydrateObjectForm($object) {
// Prepare the data that will hydrate the form
$data = array(
'id' => $object->getId(),
'locale' => $object->getLocale(),
'title' => $object->getTitle(),
'chapo' => $object->getChapo(),
'description' => $object->getDescription(),
'postscriptum' => $object->getPostscriptum(),
'visible' => $object->getVisible(),
'url' => $object->getUrl($this->getCurrentEditionLocale()),
'parent' => $object->getParent()
);
$args = array(
'current_category_id' => $category_id,
'category_order' => $category_order,
// Setup the object form
return new CategoryModificationForm($this->getRequest(), "form", $data);
}
protected function getObjectFromEvent($event) {
return $event->hasCategory() ? $event->getCategory() : null;
}
protected function getExistingObject() {
return CategoryQuery::create()
->joinWithI18n($this->getCurrentEditionLocale())
->findOneById($this->getRequest()->get('category_id', 0));
}
protected function getObjectLabel($object) {
return $object->getTitle();
}
protected function getObjectId($object) {
return $object->getId();
}
protected function renderListTemplate($currentOrder) {
return $this->render('categories',
array(
'category_order' => $currentOrder,
'category_id' => $this->getRequest()->get('category_id', 0)
)
);
}
protected function renderEditionTemplate() {
return $this->render('category-edit', array('category_id' => $this->getRequest()->get('category_id', 0)));
}
protected function redirectToEditionTemplate() {
$this->redirectToRoute(
"admin.categories.update",
array('category_id' => $this->getRequest()->get('category_id', 0))
);
// Store the current sort order in session
$this->getSession()->set('admin.category_order', $category_order);
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 {
// Validate the form, create the CategoryCreation event and dispatch it.
$form = $this->validateForm($creationForm, "POST");
$data = $form->getData();
$createEvent = new CategoryCreateEvent(
$data["title"],
$data["parent"],
$data["locale"]
);
$this->dispatch(TheliaEvents::CATEGORY_CREATE, $createEvent);
if (! $createEvent->hasCategory()) throw new \LogicException($this->getTranslator()->trans("No category was created."));
$createdObject = $createEvent->getCategory();
// Log category creation
$this->adminLogAppend(sprintf("Category %s (ID %s) created", $createdObject->getTitle(), $createdObject->getId()));
// Substitute _ID_ in the URL with the ID of the created object
$successUrl = str_replace('_ID_', $createdObject->getId(), $creationForm->getSuccessUrl());
// Redirect to the success URL
$this->redirect($successUrl);
} catch (FormValidationException $ex) {
// Form cannot be validated
$error_msg = $this->createStandardFormValidationErrorMessage($ex);
} catch (\Exception $ex) {
// Any other error
$error_msg = $ex->getMessage();
}
$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)
protected function redirectToListTemplate() {
$this->redirectToRoute(
'admin.categories.default',
array('category_id' => $this->getRequest()->get('category_id', 0))
);
}
// 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));
}
/**
@@ -253,74 +187,41 @@ class CategoryController extends BaseAdminController
// 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);
$event = new CategoryToggleVisibilityEvent($this->getExistingObject());
try {
$this->dispatch(TheliaEvents::CATEGORY_SET_DEFAULT, $changeEvent);
$this->dispatch(TheliaEvents::CATEGORY_TOGGLE_VISIBILITY, $event);
} catch (\Exception $ex) {
// Any error
return $this->errorPage($ex);
}
$this->redirectToRoute('admin.categories.default');
// Ajax response -> no action
return $this->nullResponse();
}
/**
* Update categoryposition
*/
public function updatePositionAction()
protected function performAdditionalDeleteAction($deleteEvent)
{
// Check current user authorization
if (null !== $response = $this->checkAuth("admin.categories.update")) return $response;
// Redirect to parent category list
$this->redirectToRoute(
'admin.categories.default',
array('category_id' => $deleteEvent->getCategory()->getParent())
);
}
try {
$mode = $this->getRequest()->get('mode', null);
protected function performAdditionalUpdatePositionAction($event)
{
if ($mode == 'up')
$mode = CategoryUpdatePositionEvent::POSITION_UP;
else if ($mode == 'down')
$mode = CategoryUpdatePositionEvent::POSITION_DOWN;
else
$mode = CategoryUpdatePositionEvent::POSITION_ABSOLUTE;
$category = CategoryQuery::create()->findPk($event->getObjectId());
$position = $this->getRequest()->get('position', null);
$event = new CategoryUpdatePositionEvent(
$this->getRequest()->get('category_id', null),
$mode,
$this->getRequest()->get('position', null)
if ($category != null) {
// Redirect to parent category list
$this->redirectToRoute(
'admin.categories.default',
array('category_id' => $category->getParent())
);
$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');
return null;
}
}

View File

@@ -33,7 +33,7 @@ use Thelia\Form\ConfigCreationForm;
use Thelia\Core\Event\UpdatePositionEvent;
/**
* Manages variables sent by mail
* Manages variables
*
* @author Franck Allimant <franck@cqfdev.fr>
*/

View File

@@ -33,7 +33,7 @@ use Thelia\Form\CurrencyCreationForm;
use Thelia\Core\Event\UpdatePositionEvent;
/**
* Manages currencies sent by mail
* Manages currencies
*
* @author Franck Allimant <franck@cqfdev.fr>
*/

View File

@@ -33,7 +33,7 @@ use Thelia\Form\FeatureAvCreationForm;
use Thelia\Core\Event\UpdatePositionEvent;
/**
* Manages features-av sent by mail
* Manages features-av
*
* @author Franck Allimant <franck@cqfdev.fr>
*/

View File

@@ -37,7 +37,7 @@ use Thelia\Core\Event\FeatureAvUpdateEvent;
use Thelia\Core\Event\FeatureEvent;
/**
* Manages features sent by mail
* Manages features
*
* @author Franck Allimant <franck@cqfdev.fr>
*/

View File

@@ -41,7 +41,7 @@ use Thelia\Core\Event\TemplateAddFeatureEvent;
use Thelia\Core\Event\TemplateDeleteFeatureEvent;
/**
* Manages templates sent by mail
* Manages product templates
*
* @author Franck Allimant <franck@cqfdev.fr>
*/

View File

@@ -28,13 +28,7 @@ class CategoryCreateEvent extends CategoryEvent
protected $title;
protected $parent;
protected $locale;
public function __construct($title, $parent, $locale)
{
$this->title = $title;
$this->parent = $parent;
$this->locale = $locale;
}
protected $visible;
public function getTitle()
{
@@ -71,4 +65,16 @@ class CategoryCreateEvent extends CategoryEvent
return $this;
}
public function getVisible()
{
return $this->visible;
}
public function setVisible($visible)
{
$this->visible = $visible;
return $this;
}
}

View File

@@ -0,0 +1,28 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Core\Event;
class CategoryToggleVisibilityEvent extends CategoryEvent
{
}

View File

@@ -32,7 +32,6 @@ class CategoryUpdateEvent extends CategoryCreateEvent
protected $postscriptum;
protected $url;
protected $visibility;
protected $parent;
public function __construct($category_id)
@@ -100,18 +99,6 @@ class CategoryUpdateEvent extends CategoryCreateEvent
return $this;
}
public function getVisibility()
{
return $this->visibility;
}
public function setVisibility($visibility)
{
$this->visibility = $visibility;
return $this;
}
public function getParent()
{
return $this->parent;

View File

@@ -145,50 +145,21 @@ final class TheliaEvents
// -- END ADDRESS MANAGEMENT ---------------------------------------------------------
/**
* Sent once the category creation form has been successfully validated, and before category insertion in the database.
*/
const BEFORE_CREATECATEGORY = "action.before_createcategory";
// -- Categories management -----------------------------------------------
/**
* Create, change or delete a category
*/
const CATEGORY_CREATE = "action.createCategory";
const CATEGORY_UPDATE = "action.updateCategory";
const CATEGORY_DELETE = "action.deleteCategory";
/**
* Toggle category visibility
*/
const CATEGORY_CREATE = "action.createCategory";
const CATEGORY_UPDATE = "action.updateCategory";
const CATEGORY_DELETE = "action.deleteCategory";
const CATEGORY_TOGGLE_VISIBILITY = "action.toggleCategoryVisibility";
const CATEGORY_UPDATE_POSITION = "action.updateCategoryPosition";
/**
* Change category position
*/
const CATEGORY_CHANGE_POSITION = "action.updateCategoryPosition";
/**
* Sent just after a successful insert of a new category in the database.
*/
const BEFORE_CREATECATEGORY = "action.before_createcategory";
const AFTER_CREATECATEGORY = "action.after_createcategory";
/**
* Sent befonre deleting a category
*/
const BEFORE_DELETECATEGORY = "action.before_deletecategory";
/**
* Sent just after a successful delete of a category from the database.
*/
const BEFORE_DELETECATEGORY = "action.before_deletecategory";
const AFTER_DELETECATEGORY = "action.after_deletecategory";
/**
* Sent just before a successful change of a category in the database.
*/
const BEFORE_UPDATECATEGORY = "action.before_updateCategory";
/**
* Sent just after a successful change of a category in the database.
*/
const AFTER_UPDATECATEGORY = "action.after_updateCategory";
/**

View File

@@ -59,7 +59,7 @@ class CategoryTree extends BaseI18nLoop
}
// changement de rubrique
protected function buildCategoryTree($parent, $visible, $level, $max_level, array $exclude, LoopResult &$loopResult)
protected function buildCategoryTree($parent, $visible, $level, $max_level, $exclude, LoopResult &$loopResult)
{
if ($level > $max_level) return;
@@ -73,7 +73,7 @@ class CategoryTree extends BaseI18nLoop
if ($visible != BooleanOrBothType::ANY) $search->filterByVisible($visible);
$search->filterById($exclude, Criteria::NOT_IN);
if ($exclude != null) $search->filterById($exclude, Criteria::NOT_IN);
$search->orderByPosition(Criteria::ASC);

View File

@@ -39,7 +39,8 @@ class CategoryCreationForm extends BaseForm
"for" => "title"
)
))
->add("parent", "integer", array(
->add("parent", "text", array(
"label" => Translator::getInstance()->trans("Parent category *"),
"constraints" => array(
new NotBlank()
)
@@ -49,6 +50,9 @@ class CategoryCreationForm extends BaseForm
new NotBlank()
)
))
->add("visible", "integer", array(
"label" => Translator::getInstance()->trans("This category is online on the front office.")
))
;
}

View File

@@ -24,6 +24,7 @@ namespace Thelia\Form;
use Symfony\Component\Validator\Constraints\GreaterThan;
use Thelia\Core\Translation\Translator;
use Symfony\Component\Validator\Constraints\NotBlank;
class CategoryModificationForm extends CategoryCreationForm
{
@@ -36,12 +37,13 @@ class CategoryModificationForm extends CategoryCreationForm
$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("url", "text", array(
"label" => Translator::getInstance()->trans("Rewriten URL *"),
"constraints" => array(new NotBlank())
))
;
// Add standard description fields
// Add standard description fields, excluding title and locale, which a re defined in parent class
$this->addStandardDescFields(array('title', 'locale'));
}

View File

@@ -28,26 +28,6 @@ class Category extends BaseCategory
return URL::getInstance()->retrieve('category', $this->getId(), $locale)->toString();
}
/**
* Create a new category.
*
* @param string $title the category title
* @param int $parent the ID of the parent category
* @param string $locale the locale of the title
*/
public function create($title, $parent, $locale)
{
$this
->setLocale($locale)
->setTitle($title)
->setParent($parent)
->setVisible(1)
->setPosition($this->getNextPosition($parent))
;
$this->save();
}
/**
*
* count all products for current category and sub categories
@@ -73,6 +53,8 @@ class Category extends BaseCategory
public function preInsert(ConnectionInterface $con = null)
{
$this->setPosition($this->getNextPosition($this->parent));
$this->dispatchEvent(TheliaEvents::BEFORE_CREATECATEGORY, new CategoryEvent($this));
return true;
@@ -98,6 +80,8 @@ class Category extends BaseCategory
public function preDelete(ConnectionInterface $con = null)
{
$this->dispatchEvent(TheliaEvents::BEFORE_DELETECATEGORY, new CategoryEvent($this));
return true;
}
public function postDelete(ConnectionInterface $con = null)