Removed InternalEvent, simplified SecurityContext
This commit is contained in:
@@ -40,52 +40,6 @@ class BaseAction
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a BaseForm
|
||||
*
|
||||
* @param BaseForm $aBaseForm the form
|
||||
* @param string $expectedMethod the expected method, POST or GET, or null for any of them
|
||||
* @throws FormValidationException is the form contains error, or the method is not the right one
|
||||
* @return \Symfony\Component\Form\Form Form the symfony form object
|
||||
*/
|
||||
protected function validateForm(BaseForm $aBaseForm, $expectedMethod = null)
|
||||
{
|
||||
$form = $aBaseForm->getForm();
|
||||
|
||||
if ($expectedMethod == null || $aBaseForm->getRequest()->isMethod($expectedMethod)) {
|
||||
|
||||
$form->bind($aBaseForm->getRequest());
|
||||
|
||||
if ($form->isValid()) {
|
||||
return $form;
|
||||
} else {
|
||||
throw new FormValidationException("Missing or invalid data");
|
||||
}
|
||||
} else {
|
||||
throw new FormValidationException(sprintf("Wrong form method, %s expected.", $expectedMethod));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Propagate a form error in the action event
|
||||
*
|
||||
* @param BaseForm $aBaseForm the form
|
||||
* @param string $error_message an error message that may be displayed to the customer
|
||||
* @param ActionEvent $event the action event
|
||||
*/
|
||||
protected function propagateFormError(BaseForm $aBaseForm, $error_message, ActionEvent $event)
|
||||
{
|
||||
// The form has an error
|
||||
$aBaseForm->setError(true);
|
||||
$aBaseForm->setErrorMessage($error_message);
|
||||
|
||||
// Store the form in the parser context
|
||||
$event->setErrorForm($aBaseForm);
|
||||
|
||||
// Stop event propagation
|
||||
$event->stopPropagation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the event dispatcher,
|
||||
*
|
||||
@@ -96,4 +50,33 @@ class BaseAction
|
||||
return $this->container->get('event_dispatcher');
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* Check current user authorisations.
|
||||
*
|
||||
* @param mixed $roles a single role or an array of roles.
|
||||
* @param mixed $permissions a single permission or an array of permissions.
|
||||
*
|
||||
* @throws AuthenticationException if permissions are not granted to the current user.
|
||||
*/
|
||||
protected function checkAuth($roles, $permissions) {
|
||||
|
||||
if (! $this->getSecurityContext()->isGranted(
|
||||
is_array($roles) ? $roles : array($roles),
|
||||
is_array($permissions) ? $permissions : array($permissions)) ) {
|
||||
|
||||
Tlog::getInstance()->addAlert("Authorization roles:", $roles, " permissions:", $permissions, " refused.");
|
||||
|
||||
throw new AuthorizationException("Sorry, you're not allowed to perform this action");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the security context
|
||||
*
|
||||
* @return Thelia\Core\Security\SecurityContext
|
||||
*/
|
||||
protected function getSecurityContext()
|
||||
{
|
||||
return $this->container->get('thelia.securityContext');
|
||||
}
|
||||
}
|
||||
@@ -24,134 +24,46 @@
|
||||
namespace Thelia\Action;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Thelia\Core\Event\ActionEvent;
|
||||
use Thelia\Core\Event\TheliaEvents;
|
||||
use Thelia\Model\Category as CategoryModel;
|
||||
use Thelia\Form\CategoryCreationForm;
|
||||
use Thelia\Core\Event\CategoryEvent;
|
||||
use Thelia\Tools\Redirect;
|
||||
use Thelia\Model\CategoryQuery;
|
||||
use Thelia\Model\AdminLog;
|
||||
use Thelia\Form\CategoryDeletionForm;
|
||||
use Thelia\Action\Exception\FormValidationException;
|
||||
|
||||
use Propel\Runtime\ActiveQuery\Criteria;
|
||||
use Propel\Runtime\Propel;
|
||||
use Thelia\Model\Map\CategoryTableMap;
|
||||
use Propel\Runtime\Exception\PropelException;
|
||||
|
||||
use Thelia\Core\Event\CategoryCreateEvent;
|
||||
use Thelia\Core\Event\CategoryDeleteEvent;
|
||||
use Thelia\Core\Event\CategoryToggleVisibilityEvent;
|
||||
use Thelia\Core\Event\CategoryChangePositionEvent;
|
||||
|
||||
class Category extends BaseAction implements EventSubscriberInterface
|
||||
{
|
||||
public function create(ActionEvent $event)
|
||||
public function create(CategoryCreateEvent $event)
|
||||
{
|
||||
|
||||
$this->checkAuth("ADMIN", "admin.category.create");
|
||||
|
||||
$request = $event->getRequest();
|
||||
$category = new CategoryModel();
|
||||
|
||||
try {
|
||||
$categoryCreationForm = new CategoryCreationForm($request);
|
||||
$event->getDispatcher()->dispatch(TheliaEvents::BEFORE_CREATECATEGORY, $event);
|
||||
|
||||
$form = $this->validateForm($categoryCreationForm, "POST");
|
||||
$category->create(
|
||||
$event->getTitle(),
|
||||
$event->getParent(),
|
||||
$event->getLocale()
|
||||
);
|
||||
|
||||
$data = $form->getData();
|
||||
$event->setCreatedCategory($category);
|
||||
|
||||
$category = new CategoryModel();
|
||||
|
||||
$event->getDispatcher()->dispatch(TheliaEvents::BEFORE_CREATECATEGORY, $event);
|
||||
|
||||
$category->create(
|
||||
$data["title"],
|
||||
$data["parent"],
|
||||
$data["locale"]
|
||||
);
|
||||
|
||||
AdminLog::append(sprintf("Category %s (ID %s) created", $category->getTitle(), $category->getId()), $request, $request->getSession()->getAdminUser());
|
||||
|
||||
$categoryEvent = new CategoryEvent($category);
|
||||
|
||||
$event->getDispatcher()->dispatch(TheliaEvents::AFTER_CREATECATEGORY, $categoryEvent);
|
||||
|
||||
// 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 (PropelException $e) {
|
||||
Tlog::getInstance()->error(sprintf('error during creating category with message "%s"', $e->getMessage()));
|
||||
|
||||
$message = "Failed to create this category, please try again.";
|
||||
}
|
||||
|
||||
// The form has errors, propagate it.
|
||||
$this->propagateFormError($categoryCreationForm, $message, $event);
|
||||
$event->getDispatcher()->dispatch(TheliaEvents::AFTER_CREATECATEGORY, $event);
|
||||
}
|
||||
|
||||
public function modify(ActionEvent $event)
|
||||
public function modify(CategoryChangeEvent $event)
|
||||
{
|
||||
$this->checkAuth("ADMIN", "admin.category.change");
|
||||
|
||||
$this->checkAuth("ADMIN", "admin.category.delete");
|
||||
|
||||
$request = $event->getRequest();
|
||||
|
||||
$customerModification = new CustomerModification($request);
|
||||
|
||||
$form = $customerModification->getForm();
|
||||
|
||||
if ($request->isMethod("post")) {
|
||||
|
||||
$form->bind($request);
|
||||
|
||||
if ($form->isValid()) {
|
||||
$data = $form->getData();
|
||||
|
||||
$customer = CustomerQuery::create()->findPk(1);
|
||||
try {
|
||||
$customerEvent = new CustomerEvent($customer);
|
||||
$event->getDispatcher()->dispatch(TheliaEvents::BEFORE_CHANGECUSTOMER, $customerEvent);
|
||||
|
||||
$data = $form->getData();
|
||||
|
||||
$customer->createOrUpdate(
|
||||
$data["title"],
|
||||
$data["firstname"],
|
||||
$data["lastname"],
|
||||
$data["address1"],
|
||||
$data["address2"],
|
||||
$data["address3"],
|
||||
$data["phone"],
|
||||
$data["cellphone"],
|
||||
$data["zipcode"],
|
||||
$data["country"]
|
||||
);
|
||||
|
||||
$customerEvent->customer = $customer;
|
||||
$event->getDispatcher()->dispatch(TheliaEvents::AFTER_CHANGECUSTOMER, $customerEvent);
|
||||
|
||||
// Update the logged-in user, and redirect to the success URL (exits)
|
||||
// We don-t send the login event, as the customer si already logged.
|
||||
$this->processSuccessfullLogin($event, $customer, $customerModification);
|
||||
} catch (PropelException $e) {
|
||||
|
||||
Tlog::getInstance()->error(sprintf('error during modifying customer on action/modifyCustomer with message "%s"', $e->getMessage()));
|
||||
|
||||
$message = "Failed to change your account, please try again.";
|
||||
}
|
||||
} else {
|
||||
$message = "Missing or invalid data";
|
||||
}
|
||||
} else {
|
||||
$message = "Wrong form method !";
|
||||
}
|
||||
|
||||
// The form has an error
|
||||
$customerModification->setError(true);
|
||||
$customerModification->setErrorMessage($message);
|
||||
|
||||
// Dispatch the errored form
|
||||
$event->setErrorForm($customerModification);
|
||||
|
||||
// TODO !!
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -159,50 +71,22 @@ class Category extends BaseAction implements EventSubscriberInterface
|
||||
*
|
||||
* @param ActionEvent $event
|
||||
*/
|
||||
public function delete(ActionEvent $event)
|
||||
public function delete(CategoryDeleteEvent $event)
|
||||
{
|
||||
|
||||
$this->checkAuth("ADMIN", "admin.category.delete");
|
||||
|
||||
$request = $event->getRequest();
|
||||
$category = CategoryQuery::create()->findPk($event->getId());
|
||||
|
||||
try {
|
||||
$categoryDeletionForm = new CategoryDeletionForm($request);
|
||||
if ($category !== null) {
|
||||
|
||||
$form = $this->validateForm($categoryDeletionForm, "POST");
|
||||
$event->setDeletedCategory($category);
|
||||
|
||||
$data = $form->getData();
|
||||
|
||||
$category = CategoryQuery::create()->findPk($data['id']);
|
||||
|
||||
$categoryEvent = new CategoryEvent($category);
|
||||
|
||||
$event->getDispatcher()->dispatch(TheliaEvents::BEFORE_DELETECATEGORY, $categoryEvent);
|
||||
$event->getDispatcher()->dispatch(TheliaEvents::BEFORE_DELETECATEGORY, $event);
|
||||
|
||||
$category->delete();
|
||||
|
||||
AdminLog::append(sprintf("Category %s (ID %s) deleted", $category->getTitle(), $category->getId()), $request, $request->getSession()->getAdminUser());
|
||||
|
||||
$categoryEvent->category = $category;
|
||||
|
||||
$event->getDispatcher()->dispatch(TheliaEvents::AFTER_DELETECATEGORY, $categoryEvent);
|
||||
|
||||
// Substitute _ID_ in the URL with the ID of the created category
|
||||
$successUrl = str_replace('_ID_', $category->getParent(), $categoryDeletionForm->getSuccessUrl());
|
||||
|
||||
// Redirect to the success URL
|
||||
Redirect::exec($successUrl);
|
||||
} catch (PropelException $e) {
|
||||
|
||||
\Thelia\Log\Tlog::getInstance()->error(sprintf('error during deleting category ID=%s on action/modifyCustomer with message "%s"', $data['id'], $e->getMessage()));
|
||||
|
||||
$message = "Failed to change your account, please try again.";
|
||||
} catch (FormValidationException $e) {
|
||||
|
||||
$message = $e->getMessage();
|
||||
$event->getDispatcher()->dispatch(TheliaEvents::AFTER_DELETECATEGORY, $event);
|
||||
}
|
||||
|
||||
$this->propagateFormError($categoryDeletionForm, $message, $event);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -210,63 +94,55 @@ class Category extends BaseAction implements EventSubscriberInterface
|
||||
*
|
||||
* @param ActionEvent $event
|
||||
*/
|
||||
public function toggleVisibility(ActionEvent $event)
|
||||
public function toggleVisibility(CategoryToggleVisibilityEvent $event)
|
||||
{
|
||||
|
||||
$this->checkAuth("ADMIN", "admin.category.edit");
|
||||
|
||||
$request = $event->getRequest();
|
||||
|
||||
$category = CategoryQuery::create()->findPk($request->get('category_id', 0));
|
||||
$category = CategoryQuery::create()->findPk($event->getId());
|
||||
|
||||
if ($category !== null) {
|
||||
|
||||
$event->setCategory($category);
|
||||
$event->getDispatcher()->dispatch(TheliaEvents::BEFORE_CHANGECATEGORY, $event);
|
||||
|
||||
$category->setVisible($category->getVisible() ? false : true);
|
||||
|
||||
$category->save();
|
||||
|
||||
$categoryEvent = new CategoryEvent($category);
|
||||
|
||||
$event->getDispatcher()->dispatch(TheliaEvents::AFTER_CHANGECATEGORY, $categoryEvent);
|
||||
$event->setCategory($category);
|
||||
$event->getDispatcher()->dispatch(TheliaEvents::AFTER_CHANGECATEGORY, $event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move category up
|
||||
* Changes category position, selecting absolute ou relative change.
|
||||
*
|
||||
* @param ActionEvent $event
|
||||
* @param CategoryChangePositionEvent $event
|
||||
*/
|
||||
public function changePositionUp(ActionEvent $event)
|
||||
public function changePosition(CategoryChangePositionEvent $event)
|
||||
{
|
||||
return $this->exchangePosition($event, 'up');
|
||||
}
|
||||
$this->checkAuth("ADMIN", "admin.category.edit");
|
||||
|
||||
/**
|
||||
* Move category down
|
||||
*
|
||||
* @param ActionEvent $event
|
||||
*/
|
||||
public function changePositionDown(ActionEvent $event)
|
||||
{
|
||||
return $this->exchangePosition($event, 'down');
|
||||
if ($event->getMode() == CategoryChangePositionEvent::POSITION_ABSOLUTE)
|
||||
return $this->changeAbsolutePosition($event);
|
||||
else
|
||||
return $this->exchangePosition($event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move up or down a category
|
||||
*
|
||||
* @param ActionEvent $event
|
||||
* @param string $direction up to move up, down to move down
|
||||
* @param CategoryChangePositionEvent $event
|
||||
*/
|
||||
protected function exchangePosition(ActionEvent $event, $direction)
|
||||
protected function exchangePosition(CategoryChangePositionEvent $event)
|
||||
{
|
||||
$this->checkAuth("ADMIN", "admin.category.edit");
|
||||
|
||||
$request = $event->getRequest();
|
||||
|
||||
$category = CategoryQuery::create()->findPk($request->get('category_id', 0));
|
||||
$category = CategoryQuery::create()->findPk($event->getId());
|
||||
|
||||
if ($category !== null) {
|
||||
|
||||
$event->setCategory($category);
|
||||
$event->getDispatcher()->dispatch(TheliaEvents::BEFORE_CHANGECATEGORY, $event);
|
||||
|
||||
// The current position of the category
|
||||
$my_position = $category->getPosition();
|
||||
|
||||
@@ -275,10 +151,10 @@ class Category extends BaseAction implements EventSubscriberInterface
|
||||
->filterByParent($category->getParent());
|
||||
|
||||
// Up or down ?
|
||||
if ($direction == 'up') {
|
||||
if ($event->getMode() == CategoryChangePositionEvent::POSITION_UP) {
|
||||
// Find the category immediately before me
|
||||
$search->filterByPosition(array('max' => $my_position-1))->orderByPosition(Criteria::DESC);
|
||||
} elseif ($direction == 'down') {
|
||||
} elseif ($event->getMode() == CategoryChangePositionEvent::POSITION_DOWN) {
|
||||
// Find the category immediately after me
|
||||
$search->filterByPosition(array('min' => $my_position+1))->orderByPosition(Criteria::ASC);
|
||||
} else
|
||||
@@ -304,26 +180,30 @@ class Category extends BaseAction implements EventSubscriberInterface
|
||||
$cnx->rollback();
|
||||
}
|
||||
}
|
||||
|
||||
$event->setCategory($category);
|
||||
$event->getDispatcher()->dispatch(TheliaEvents::AFTER_CHANGECATEGORY, $event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes category position
|
||||
*
|
||||
* @param ActionEvent $event
|
||||
* @param CategoryChangePositionEvent $event
|
||||
*/
|
||||
public function changePosition(ActionEvent $event)
|
||||
protected function changeAbsolutePosition(CategoryChangePositionEvent $event)
|
||||
{
|
||||
$this->checkAuth("ADMIN", "admin.category.edit");
|
||||
|
||||
$request = $event->getRequest();
|
||||
|
||||
$category = CategoryQuery::create()->findPk($request->get('category_id', 0));
|
||||
$category = CategoryQuery::create()->findPk($event->getId());
|
||||
|
||||
if ($category !== null) {
|
||||
|
||||
$event->setCategory($category);
|
||||
$event->getDispatcher()->dispatch(TheliaEvents::BEFORE_CHANGECATEGORY, $event);
|
||||
|
||||
// The required position
|
||||
$new_position = $request->get('position', null);
|
||||
$new_position = $event->getPosition();
|
||||
|
||||
// The current position
|
||||
$current_position = $category->getPosition();
|
||||
@@ -363,6 +243,9 @@ class Category extends BaseAction implements EventSubscriberInterface
|
||||
$cnx->rollback();
|
||||
}
|
||||
}
|
||||
|
||||
$event->setCategory($category);
|
||||
$event->getDispatcher()->dispatch(TheliaEvents::AFTER_CHANGECATEGORY, $event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -389,12 +272,14 @@ class Category extends BaseAction implements EventSubscriberInterface
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
"action.createCategory" => array("create", 128),
|
||||
"action.modifyCategory" => array("modify", 128),
|
||||
"action.deleteCategory" => array("delete", 128),
|
||||
TheliaEvents::CATEGORY_CREATE => array("create", 128),
|
||||
TheliaEvents::CATEGORY_MODIFY => array("modify", 128),
|
||||
TheliaEvents::CATEGORY_DELETE => array("delete", 128),
|
||||
|
||||
"action.toggleCategoryVisibility" => array("toggleVisibility", 128),
|
||||
"action.changeCategoryPositionUp" => array("changePositionUp", 128),
|
||||
TheliaEvents::CATEGORY_TOGGLE_VISIBILITY => array("toggleVisibility", 128),
|
||||
TheliaEvents::CATEGORY_CHANGE_POSITION => array("changePosition", 128),
|
||||
|
||||
"action.changeCategoryPositionU" => array("changePositionUp", 128),
|
||||
"action.changeCategoryPositionDown" => array("changePositionDown", 128),
|
||||
"action.changeCategoryPosition" => array("changePosition", 128),
|
||||
);
|
||||
|
||||
@@ -96,7 +96,7 @@ class Customer extends BaseAction implements EventSubscriberInterface
|
||||
{
|
||||
$event->getDispatcher()->dispatch(TheliaEvents::CUSTOMER_LOGOUT, $event);
|
||||
|
||||
$this->getFrontSecurityContext()->clear();
|
||||
$this->getSecurityContext()->clearCustomerUser();
|
||||
}
|
||||
|
||||
public function changePassword(ActionEvent $event)
|
||||
@@ -127,8 +127,8 @@ class Customer extends BaseAction implements EventSubscriberInterface
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
"action.createCustomer" => array("create", 128),
|
||||
"action.modifyCustomer" => array("modify", 128),
|
||||
TheliaEvents::CUSTOMER_CREATEACCOUNT => array("create", 128),
|
||||
TheliaEvents::CUSTOMER_UPDATEACCOUNT => array("modify", 128),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,8 +28,8 @@ use Thelia\Model\ConfigQuery;
|
||||
use Thelia\Model\Customer;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Thelia\Core\HttpFoundation\Session\Session;
|
||||
use Thelia\Core\Event\Internal\CartEvent;
|
||||
use Thelia\Core\Event\TheliaEvents;
|
||||
use Thelia\Core\Event\CartEvent;
|
||||
|
||||
trait CartTrait
|
||||
{
|
||||
@@ -42,8 +42,9 @@ trait CartTrait
|
||||
*/
|
||||
public function getCart(Request $request)
|
||||
{
|
||||
$session = $request->getSession();
|
||||
|
||||
if (null !== $cart = $request->getSession()->getCart()) {
|
||||
if (null !== $cart = $session->getCart()) {
|
||||
return $cart;
|
||||
}
|
||||
|
||||
@@ -55,26 +56,26 @@ trait CartTrait
|
||||
|
||||
if ($cart) {
|
||||
//le panier existe en base
|
||||
$customer = $request->getSession()->getCustomerUser();
|
||||
$customer = $session->getCustomerUser();
|
||||
|
||||
if ($customer) {
|
||||
if ($cart->getCustomerId() != $customer->getId()) {
|
||||
//le customer du panier n'est pas le mm que celui connecté, il faut cloner le panier sans le customer_id
|
||||
$cart = $this->duplicateCart($cart, $request->getSession(), $customer);
|
||||
$cart = $this->duplicateCart($cart, $session, $customer);
|
||||
}
|
||||
} else {
|
||||
if ($cart->getCustomerId() != null) {
|
||||
//il faut dupliquer le panier sans le customer_id
|
||||
$cart = $this->duplicateCart($cart, $request->getSession());
|
||||
$cart = $this->duplicateCart($cart, $session);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
$cart = $this->createCart($request->getSession());
|
||||
$cart = $this->createCart($session);
|
||||
}
|
||||
} else {
|
||||
//le cookie de panier n'existe pas, il va falloir le créer et faire un enregistrement en base.
|
||||
$cart = $this->createCart($request->getSession());
|
||||
$cart = $this->createCart($session);
|
||||
}
|
||||
|
||||
return $cart;
|
||||
@@ -116,7 +117,7 @@ trait CartTrait
|
||||
$cartEvent = new CartEvent($newCart);
|
||||
$this->getDispatcher()->dispatch(TheliaEvents::CART_DUPLICATE, $cartEvent);
|
||||
|
||||
return $cartEvent->cart;
|
||||
return $cartEvent->getCart();
|
||||
}
|
||||
|
||||
protected function generateCookie()
|
||||
@@ -131,4 +132,4 @@ trait CartTrait
|
||||
return $id;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,16 +22,16 @@
|
||||
<tag name="kernel.event_subscriber"/>
|
||||
</service>
|
||||
|
||||
<service id="thelia.action.category" class="Thelia\Action\Category">
|
||||
<argument type="service" id="service_container"/>
|
||||
<tag name="kernel.event_subscriber"/>
|
||||
</service>
|
||||
|
||||
<service id="thelia.action.category" class="Thelia\Action\Image">
|
||||
<argument type="service" id="service_container"/>
|
||||
<tag name="kernel.event_subscriber"/>
|
||||
</service>
|
||||
|
||||
<service id="thelia.action.customer" class="Thelia\Action\Category">
|
||||
<argument type="service" id="service_container"/>
|
||||
<tag name="kernel.event_subscriber"/>
|
||||
</service>
|
||||
|
||||
</services>
|
||||
|
||||
</config>
|
||||
|
||||
@@ -85,8 +85,6 @@
|
||||
<argument type="service" id="request" />
|
||||
</service>
|
||||
|
||||
<service id="thelia.envContext" class="Thelia\Core\Context"/>
|
||||
|
||||
<!-- Parser context -->
|
||||
|
||||
<service id="thelia.parser.context" class="Thelia\Core\Template\ParserContext" scope="request">
|
||||
|
||||
@@ -30,11 +30,22 @@ use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Thelia\Core\Security\Exception\AuthenticationException;
|
||||
use Thelia\Tools\URL;
|
||||
use Thelia\Tools\Redirect;
|
||||
use Thelia\Core\Security\SecurityContext;
|
||||
use Thelia\Model\AdminLog;
|
||||
|
||||
class BaseAdminController extends BaseController
|
||||
{
|
||||
const TEMPLATE_404 = "404";
|
||||
|
||||
/**
|
||||
* Helper to append a message to the admin log.
|
||||
*
|
||||
* @param unknown $message
|
||||
*/
|
||||
public function adminLogAppend($message) {
|
||||
AdminLog::append($message, $this->getRequest(), $this->getSecurityContext()->getAdminUser());
|
||||
}
|
||||
|
||||
public function processTemplateAction($template)
|
||||
{
|
||||
try {
|
||||
|
||||
@@ -25,12 +25,52 @@ namespace Thelia\Controller\Admin;
|
||||
|
||||
use Thelia\Core\Security\Exception\AuthenticationException;
|
||||
use Thelia\Core\Security\Exception\AuthorizationException;
|
||||
use Thelia\Log\Tlog;
|
||||
use Thelia\Core\Event\TheliaEvents;
|
||||
use Thelia\Core\Event\CategoryCreateEvent;
|
||||
use Thelia\Form\CategoryCreationForm;
|
||||
use Thelia\Core\Event\CategoryDeleteEvent;
|
||||
use Thelia\Core\Event\CategoryToggleVisibilityEvent;
|
||||
use Thelia\Core\Event\CategoryChangePositionEvent;
|
||||
use Thelia\Form\CategoryDeletionForm;
|
||||
|
||||
class CategoryController extends BaseAdminController
|
||||
{
|
||||
protected function createNewCategory($args)
|
||||
{
|
||||
$this->dispatchEvent("createCategory");
|
||||
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()->setErrorForm($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);
|
||||
@@ -45,9 +85,35 @@ class CategoryController extends BaseAdminController
|
||||
|
||||
protected function deleteCategory($args)
|
||||
{
|
||||
$this->dispatchEvent("deleteCategory");
|
||||
try {
|
||||
$categoryDeletionForm = new CategoryDeletionForm($this->getRequest());
|
||||
|
||||
// Something was wrong, category was not deleted. Display parent category list
|
||||
$data = $this->validateForm($categoryDeletionForm, "POST")->getData();
|
||||
var_dump($data);
|
||||
$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()->getId(), $categoryDeletionForm->getSuccessUrl());
|
||||
|
||||
// Redirect to the success URL
|
||||
$this->redirect($successUrl);
|
||||
}
|
||||
catch (FormValidationException $e) {
|
||||
$categoryDeletionForm->setErrorMessage($e->getMessage());
|
||||
$this->getParserContext()->setErrorForm($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);
|
||||
}
|
||||
|
||||
@@ -60,28 +126,48 @@ class CategoryController extends BaseAdminController
|
||||
|
||||
protected function visibilityToggle($args)
|
||||
{
|
||||
$this->dispatchEvent("toggleCategoryVisibility");
|
||||
$event = new CategoryToggleVisibilityEvent($this->getRequest()->get('category_id', 0));
|
||||
|
||||
$this->dispatch(TheliaEvents::CATEGORY_TOGGLE_VISIBILITY, $event);
|
||||
|
||||
return $this->nullResponse();
|
||||
}
|
||||
|
||||
protected function changePosition($args)
|
||||
{
|
||||
$this->dispatchEvent("changeCategoryPosition");
|
||||
$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)
|
||||
{
|
||||
$this->dispatchEvent("changeCategoryPositionDown");
|
||||
$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)
|
||||
{
|
||||
$this->dispatchEvent("changeCategoryPositionUp");
|
||||
$event = new CategoryChangePositionEvent(
|
||||
$this->getRequest()->get('category_id', 0),
|
||||
CategoryChangePositionEvent::POSITION_UP
|
||||
);
|
||||
|
||||
$this->dispatch(TheliaEvents::CATEGORY_CHANGE_POSITION, $event);
|
||||
|
||||
return $this->render('categories', $args);
|
||||
}
|
||||
@@ -138,9 +224,11 @@ class CategoryController extends BaseAdminController
|
||||
|
||||
return $this->positionDown($args);
|
||||
}
|
||||
} catch (AuthorizationException $ex) {
|
||||
}
|
||||
catch (AuthorizationException $ex) {
|
||||
return $this->errorPage($ex->getMessage());
|
||||
} catch (AuthenticationException $ex) {
|
||||
}
|
||||
catch (AuthenticationException $ex) {
|
||||
return $this->errorPage($ex->getMessage());
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ class SessionController extends BaseAdminController
|
||||
{
|
||||
$this->dispatch(TheliaEvents::ADMIN_LOGOUT);
|
||||
|
||||
$this->getSecurityContext()->clear();
|
||||
$this->getSecurityContext()->clearAdminUser();
|
||||
|
||||
// Go back to login page.
|
||||
return Redirect::exec(URL::absoluteUrl('/admin/login')); // FIXME - should be a parameter
|
||||
@@ -61,7 +61,7 @@ class SessionController extends BaseAdminController
|
||||
$user = $authenticator->getAuthentifiedUser();
|
||||
|
||||
// Success -> store user in security context
|
||||
$this->getSecurityContext()->setUser($user);
|
||||
$this->getSecurityContext()->setAdminUser($user);
|
||||
|
||||
// Log authentication success
|
||||
AdminLog::append("Authentication successful", $request, $user);
|
||||
|
||||
@@ -34,6 +34,7 @@ use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
use Thelia\Core\Factory\ActionEventFactory;
|
||||
use Thelia\Form\BaseForm;
|
||||
use Thelia\Form\Exception\FormValidationException;
|
||||
use Symfony\Component\EventDispatcher\Event;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -56,34 +57,12 @@ class BaseController extends ContainerAware
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an action event
|
||||
* Dispatch a Thelia event
|
||||
*
|
||||
* @param string $action
|
||||
* @return EventDispatcher
|
||||
* @param string $eventName a TheliaEvent name, as defined in TheliaEvents class
|
||||
* @param Event $event the event
|
||||
*/
|
||||
protected function dispatchEvent($action)
|
||||
{
|
||||
// Create the
|
||||
$eventFactory = new ActionEventFactory($this->getRequest(), $action, $this->container->getParameter("thelia.actionEvent"));
|
||||
|
||||
$actionEvent = $eventFactory->createActionEvent();
|
||||
|
||||
$this->dispatch("action.$action", $actionEvent);
|
||||
|
||||
if ($actionEvent->hasErrorForm()) {
|
||||
$this->getParserContext()->setErrorForm($actionEvent->getErrorForm());
|
||||
}
|
||||
|
||||
return $actionEvent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch a Thelia event to modules
|
||||
*
|
||||
* @param string $eventName a TheliaEvent name, as defined in TheliaEvents class
|
||||
* @param ActionEvent $event the event
|
||||
*/
|
||||
protected function dispatch($eventName, ActionEvent $event = null)
|
||||
protected function dispatch($eventName, Event $event = null)
|
||||
{
|
||||
$this->getDispatcher()->dispatch($eventName, $event);
|
||||
}
|
||||
@@ -113,13 +92,9 @@ class BaseController extends ContainerAware
|
||||
*
|
||||
* @return \Thelia\Core\Security\SecurityContext
|
||||
*/
|
||||
protected function getSecurityContext($context = false)
|
||||
protected function getSecurityContext()
|
||||
{
|
||||
$securityContext = $this->container->get('thelia.securityContext');
|
||||
|
||||
$securityContext->setContext($context === false ? SecurityContext::CONTEXT_BACK_OFFICE : $context);
|
||||
|
||||
return $securityContext;
|
||||
return $this->container->get('thelia.securityContext');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,6 +36,7 @@ use Thelia\Form\CustomerModification;
|
||||
use Thelia\Form\Exception\FormValidationException;
|
||||
use Thelia\Model\Customer;
|
||||
use Thelia\Core\Event\TheliaEvents;
|
||||
use Thelia\Core\Event\CustomerEvent;
|
||||
|
||||
class CustomerController extends BaseFrontController
|
||||
{
|
||||
@@ -76,7 +77,7 @@ class CustomerController extends BaseFrontController
|
||||
|
||||
try {
|
||||
|
||||
$customer = $this->getSecurityContext(SecurityContext::CONTEXT_FRONT_OFFICE)->getUser();
|
||||
$customer = $this->getSecurityContext()->getCustomerUser();
|
||||
|
||||
$form = $this->validateForm($customerModification, "post");
|
||||
|
||||
@@ -116,9 +117,7 @@ class CustomerController extends BaseFrontController
|
||||
try {
|
||||
$customer = $authenticator->getAuthentifiedUser();
|
||||
|
||||
$customerLoginEvent = new CustomerLoginEvent($customer);
|
||||
|
||||
$this->processLogin($customer, $customerLoginEvent);
|
||||
$this->processLogin($customer);
|
||||
|
||||
$this->redirectSuccess();
|
||||
} catch (ValidatorException $e) {
|
||||
@@ -132,11 +131,11 @@ class CustomerController extends BaseFrontController
|
||||
}
|
||||
}
|
||||
|
||||
public function processLogin(Customer $customer,$event = null)
|
||||
public function processLogin(Customer $customer)
|
||||
{
|
||||
$this->getSecurityContext(SecurityContext::CONTEXT_FRONT_OFFICE)->setUser($customer);
|
||||
$this->getSecurityContext()->setCustomerUser($customer);
|
||||
|
||||
if($event) $this->dispatch(TheliaEvents::CUSTOMER_LOGIN, $event);
|
||||
if($event) $this->dispatch(TheliaEvents::CUSTOMER_LOGIN, new CustomerLoginEvent($customer));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -35,27 +35,8 @@ use Thelia\Form\BaseForm;
|
||||
*/
|
||||
abstract class ActionEvent extends Event
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Symfony\Component\HttpFoundation\Request
|
||||
*/
|
||||
protected $request;
|
||||
|
||||
protected $errorForm = null;
|
||||
|
||||
protected $parameters = array();
|
||||
|
||||
/**
|
||||
*
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* @param string $action
|
||||
*/
|
||||
public function __construct(Request $request)
|
||||
{
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
public function __set($name, $value)
|
||||
{
|
||||
$this->parameters[$name] = $value;
|
||||
@@ -69,30 +50,4 @@ abstract class ActionEvent extends Event
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Request
|
||||
*/
|
||||
public function getRequest()
|
||||
{
|
||||
return $this->request;
|
||||
}
|
||||
|
||||
public function setErrorForm(BaseForm $form)
|
||||
{
|
||||
$this->errorForm = $form;
|
||||
|
||||
if ($form != null) $this->stopPropagation();
|
||||
}
|
||||
|
||||
public function getErrorForm()
|
||||
{
|
||||
return $this->errorForm;
|
||||
}
|
||||
|
||||
public function hasErrorForm()
|
||||
{
|
||||
return $this->errorForm != null ? true : false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ namespace Thelia\Core\Event;
|
||||
|
||||
use Thelia\Model\CartItem;
|
||||
|
||||
class CartItemEvent extends InternalEvent
|
||||
class CartItemEvent extends ActionEvent
|
||||
{
|
||||
protected $cartItem;
|
||||
|
||||
|
||||
68
core/lib/Thelia/Core/Context.php → core/lib/Thelia/Core/Event/CategoryChangePositionEvent.php
Executable file → Normal file
68
core/lib/Thelia/Core/Context.php → core/lib/Thelia/Core/Event/CategoryChangePositionEvent.php
Executable file → Normal file
@@ -21,34 +21,64 @@
|
||||
/* */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\Core;
|
||||
namespace Thelia\Core\Event;
|
||||
use Thelia\Model\Category;
|
||||
|
||||
class Context
|
||||
class CategoryChangePositionEvent extends ActionEvent
|
||||
{
|
||||
const CONTEXT_FRONT_OFFICE = 'front';
|
||||
const CONTEXT_BACK_OFFICE = 'admin';
|
||||
const POSITION_UP = 1;
|
||||
const POSITION_DOWN = 2;
|
||||
const POSITION_ABSOLUTE = 3;
|
||||
|
||||
protected $defineContext = array(
|
||||
self::CONTEXT_BACK_OFFICE,
|
||||
self::CONTEXT_FRONT_OFFICE
|
||||
);
|
||||
protected $id;
|
||||
protected $mode;
|
||||
protected $position;
|
||||
protected $category;
|
||||
|
||||
protected $currentContext = self::CONTEXT_FRONT_OFFICE;
|
||||
|
||||
public function isValidContext($context)
|
||||
public function __construct($id, $mode, $position = null)
|
||||
{
|
||||
return in_array($context, $this->defineContext);
|
||||
$this->id = $id;
|
||||
$this->mode = $mode;
|
||||
$this->position = $position;
|
||||
}
|
||||
|
||||
public function setContext($context)
|
||||
public function getId()
|
||||
{
|
||||
if ($this->isValidContext($context)) {
|
||||
$this->currentContext = $context;
|
||||
}
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getContext()
|
||||
public function setId($id)
|
||||
{
|
||||
return $this->currentContext;
|
||||
$this->id = $id;
|
||||
}
|
||||
}
|
||||
|
||||
public function getMode()
|
||||
{
|
||||
return $this->mode;
|
||||
}
|
||||
|
||||
public function setMode($mode)
|
||||
{
|
||||
$this->mode = $mode;
|
||||
}
|
||||
|
||||
public function getPosition()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
public function setPosition($position)
|
||||
{
|
||||
$this->position = $position;
|
||||
}
|
||||
|
||||
public function getCategory()
|
||||
{
|
||||
return $this->category;
|
||||
}
|
||||
|
||||
public function setCategory($category)
|
||||
{
|
||||
$this->category = $category;
|
||||
}
|
||||
}
|
||||
64
core/lib/Thelia/Core/Event/Internal/InternalEvent.php → core/lib/Thelia/Core/Event/CategoryCreateEvent.php
Executable file → Normal file
64
core/lib/Thelia/Core/Event/Internal/InternalEvent.php → core/lib/Thelia/Core/Event/CategoryCreateEvent.php
Executable file → Normal file
@@ -21,16 +21,62 @@
|
||||
/* */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\Core\Event\Internal;
|
||||
namespace Thelia\Core\Event;
|
||||
|
||||
use Symfony\Component\EventDispatcher\Event;
|
||||
use Thelia\Model\Category;
|
||||
|
||||
/**
|
||||
* Base class used for internal event like creating new Customer, adding item to cart, etc
|
||||
*
|
||||
* Class InternalEvent
|
||||
* @package Thelia\Core\Event
|
||||
*/
|
||||
abstract class InternalEvent extends Event
|
||||
class CategoryCreateEvent extends ActionEvent
|
||||
{
|
||||
protected $title;
|
||||
protected $parent;
|
||||
protected $locale;
|
||||
protected $created_category;
|
||||
|
||||
public function __construct($title, $parent, $locale)
|
||||
{
|
||||
$this->title = $title;
|
||||
$this->parent = $parent;
|
||||
$this->locale = $locale;
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
public function setTitle($title)
|
||||
{
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
public function getParent()
|
||||
{
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
public function setParent($parent)
|
||||
{
|
||||
$this->parent = $parent;
|
||||
}
|
||||
|
||||
public function getLocale()
|
||||
{
|
||||
return $this->locale;
|
||||
}
|
||||
|
||||
public function setLocale($locale)
|
||||
{
|
||||
$this->locale = $locale;
|
||||
}
|
||||
|
||||
public function getCreatedCategory()
|
||||
{
|
||||
return $this->created_category;
|
||||
}
|
||||
|
||||
public function setCreatedCategory(Category $created_category)
|
||||
{
|
||||
$this->created_category = $created_category;
|
||||
var_dump($this->created_category);
|
||||
}
|
||||
}
|
||||
33
core/lib/Thelia/Core/Event/Internal/CartEvent.php → core/lib/Thelia/Core/Event/CategoryDeleteEvent.php
Executable file → Normal file
33
core/lib/Thelia/Core/Event/Internal/CartEvent.php → core/lib/Thelia/Core/Event/CategoryDeleteEvent.php
Executable file → Normal file
@@ -21,17 +21,36 @@
|
||||
/* */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\Core\Event\Internal;
|
||||
namespace Thelia\Core\Event;
|
||||
use Thelia\Model\Category;
|
||||
|
||||
use Thelia\Model\Cart;
|
||||
|
||||
class CartEvent extends InternalEvent
|
||||
class CategoryDeleteEvent extends ActionEvent
|
||||
{
|
||||
public $cart;
|
||||
protected $id;
|
||||
protected $deleted_category;
|
||||
|
||||
public function __construct(Cart $cart)
|
||||
public function __construct($id)
|
||||
{
|
||||
$this->cart = $cart;
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setId($id)
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
public function getDeletedCategory()
|
||||
{
|
||||
return $this->deleted_category;
|
||||
}
|
||||
|
||||
public function setDeletedCategory(Category $deleted_category)
|
||||
{
|
||||
$this->deleted_category = $deleted_category;
|
||||
}
|
||||
}
|
||||
30
core/lib/Thelia/Core/Event/CategoryEvent.php → core/lib/Thelia/Core/Event/CategoryToggleVisibilityEvent.php
Executable file → Normal file
30
core/lib/Thelia/Core/Event/CategoryEvent.php → core/lib/Thelia/Core/Event/CategoryToggleVisibilityEvent.php
Executable file → Normal file
@@ -22,15 +22,35 @@
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\Core\Event;
|
||||
|
||||
use Thelia\Model\Category;
|
||||
|
||||
class CategoryEvent extends InternalEvent
|
||||
class CategoryToggleVisibilityEvent extends ActionEvent
|
||||
{
|
||||
public $category;
|
||||
protected $id;
|
||||
protected $category;
|
||||
|
||||
public function __construct(Category $category)
|
||||
public function __construct($id)
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setId($id)
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
public function getCategory()
|
||||
{
|
||||
return $this->category;
|
||||
}
|
||||
|
||||
public function setCategory(Category $category)
|
||||
{
|
||||
$this->category = $category;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,11 +21,12 @@
|
||||
/* */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\Core\Event\Internal;
|
||||
namespace Thelia\Core\Event;
|
||||
|
||||
use Thelia\Model\Customer;
|
||||
use Thelia\Core\Event\ActionEvent;
|
||||
|
||||
class CustomerEvent extends InternalEvent
|
||||
class CustomerEvent extends ActionEvent
|
||||
{
|
||||
public $customer;
|
||||
|
||||
@@ -94,11 +94,29 @@ final class TheliaEvents
|
||||
*/
|
||||
const AFTER_CHANGECUSTOMER = "action.after_changecustomer";
|
||||
|
||||
|
||||
/**
|
||||
* Sent once the category creation form has been successfully validated, and before category insertion in the database.
|
||||
*/
|
||||
const BEFORE_CREATECATEGORY = "action.before_createcategory";
|
||||
|
||||
/**
|
||||
* Create, change or delete a category
|
||||
*/
|
||||
const CATEGORY_CREATE = "action.createCategory";
|
||||
const CATEGORY_MODIFY = "action.modifyCategory";
|
||||
const CATEGORY_DELETE = "action.deleteCategory";
|
||||
|
||||
/**
|
||||
* Toggle category visibility
|
||||
*/
|
||||
const CATEGORY_TOGGLE_VISIBILITY = "action.toggleCategoryVisibility";
|
||||
|
||||
/**
|
||||
* Change category position
|
||||
*/
|
||||
const CATEGORY_CHANGE_POSITION = "action.changeCategoryPosition";
|
||||
|
||||
/**
|
||||
* Sent just after a successful insert of a new category in the database.
|
||||
*/
|
||||
@@ -113,6 +131,11 @@ final class TheliaEvents
|
||||
*/
|
||||
const AFTER_DELETECATEGORY = "action.after_deletecategory";
|
||||
|
||||
/**
|
||||
* Sent just before a successful change of a category in the database.
|
||||
*/
|
||||
const BEFORE_CHANGECATEGORY = "action.before_changecategory";
|
||||
|
||||
/**
|
||||
* Sent just after a successful change of a category in the database.
|
||||
*/
|
||||
@@ -154,5 +177,4 @@ final class TheliaEvents
|
||||
* Sent on cimage cache clear request
|
||||
*/
|
||||
const IMAGE_CLEAR_CACHE = "action.clearImageCache";
|
||||
|
||||
}
|
||||
|
||||
@@ -33,36 +33,11 @@ use Thelia\Core\HttpFoundation\Request;
|
||||
*/
|
||||
class SecurityContext
|
||||
{
|
||||
const CONTEXT_FRONT_OFFICE = 'front';
|
||||
const CONTEXT_BACK_OFFICE = 'admin';
|
||||
|
||||
private $request;
|
||||
private $context;
|
||||
|
||||
public function __construct(Request $request)
|
||||
{
|
||||
$this->request = $request;
|
||||
|
||||
$this->context = null;
|
||||
}
|
||||
|
||||
public function setContext($context)
|
||||
{
|
||||
if ($context !== self::CONTEXT_FRONT_OFFICE && $context !== self::CONTEXT_BACK_OFFICE) {
|
||||
throw new \InvalidArgumentException(sprintf("Invalid or empty context identifier '%s'", $context));
|
||||
}
|
||||
|
||||
$this->context = $context;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getContext($exception_if_context_undefined = false)
|
||||
{
|
||||
if (null === $this->context && $exception_if_context_undefined === true)
|
||||
throw new \LogicException("No context defined. Please use setContext() first.");
|
||||
|
||||
return $this->context;
|
||||
}
|
||||
|
||||
private function getSession()
|
||||
@@ -76,28 +51,47 @@ class SecurityContext
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the currently authenticated user in the current context, or null if none is defined
|
||||
* Gets the currently authenticated user in the admin, or null if none is defined
|
||||
*
|
||||
* @return UserInterface|null A UserInterface instance or null if no user is available
|
||||
*/
|
||||
public function getUser()
|
||||
public function getAdminUser()
|
||||
{
|
||||
$context = $this->getContext(true);
|
||||
|
||||
if ($context === self::CONTEXT_FRONT_OFFICE)
|
||||
$user = $this->getSession()->getCustomerUser();
|
||||
else if ($context == self::CONTEXT_BACK_OFFICE)
|
||||
$user = $this->getSession()->getAdminUser();
|
||||
else
|
||||
$user = null;
|
||||
|
||||
return $user;
|
||||
return $this->getSession()->getAdminUser();
|
||||
}
|
||||
|
||||
final public function isAuthenticated()
|
||||
/**
|
||||
* Gets the currently authenticated customer, or null if none is defined
|
||||
*
|
||||
* @return UserInterface|null A UserInterface instance or null if no user is available
|
||||
*/
|
||||
public function getCustomerUser()
|
||||
{
|
||||
if (null !== $this->getUser()) {
|
||||
return true;
|
||||
return $this->getSession()->getCustomerUser();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a user has at least one of the required roles
|
||||
*
|
||||
* @param UserInterface $user the user
|
||||
* @param array $roles the roles
|
||||
* @return boolean true if the user has the required role, false otherwise
|
||||
*/
|
||||
final public function hasRequiredRole($user, array $roles) {
|
||||
|
||||
if ($user != null) {
|
||||
// Check if user's roles matches required roles
|
||||
$userRoles = $user->getRoles();
|
||||
|
||||
$roleFound = false;
|
||||
|
||||
foreach ($userRoles as $role) {
|
||||
if (in_array($role, $roles)) {
|
||||
$roleFound = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -110,85 +104,88 @@ class SecurityContext
|
||||
*/
|
||||
final public function isGranted(array $roles, array $permissions)
|
||||
{
|
||||
if ($this->isAuthenticated() === true) {
|
||||
// Find a user which matches the required roles.
|
||||
$user = $this->getCustomerUser();
|
||||
|
||||
$user = $this->getUser();
|
||||
if (! $this->hasRequiredRole($user, $roles)) {
|
||||
$user = $this->getAdminUser();
|
||||
|
||||
// Check if user's roles matches required roles
|
||||
$userRoles = $user->getRoles();
|
||||
if (! $this->hasRequiredRole($user, $roles)) {
|
||||
$user = null;
|
||||
}
|
||||
}
|
||||
|
||||
$roleFound = false;
|
||||
if ($user != null) {
|
||||
|
||||
foreach ($userRoles as $role) {
|
||||
if (in_array($role, $roles)) {
|
||||
$roleFound = true;
|
||||
|
||||
break;
|
||||
}
|
||||
if (empty($permissions)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($roleFound) {
|
||||
// Get permissions from profile
|
||||
// $userPermissions = $user->getPermissions(); FIXME
|
||||
|
||||
if (empty($permissions)) {
|
||||
return true;
|
||||
}
|
||||
// TODO: Finalize permissions system !;
|
||||
|
||||
// Get permissions from profile
|
||||
// $userPermissions = $user->getPermissions(); FIXME
|
||||
$userPermissions = array('*'); // FIXME !
|
||||
|
||||
// TODO: Finalize permissions system !;
|
||||
$permissionsFound = true;
|
||||
|
||||
$userPermissions = array('*'); // FIXME !
|
||||
// User have all permissions ?
|
||||
if (in_array('*', $userPermissions))
|
||||
return true;
|
||||
|
||||
$permissionsFound = true;
|
||||
// Check that user's permissions matches required permissions
|
||||
foreach ($permissions as $permission) {
|
||||
if (! in_array($permission, $userPermissions)) {
|
||||
$permissionsFound = false;
|
||||
|
||||
// User have all permissions ?
|
||||
if (in_array('*', $userPermissions))
|
||||
return true;
|
||||
|
||||
// Check that user's permissions matches required permissions
|
||||
foreach ($permissions as $permission) {
|
||||
if (! in_array($permission, $userPermissions)) {
|
||||
$permissionsFound = false;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $permissionsFound;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $permissionsFound;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the authenticated user.
|
||||
* Sets the authenticated admin user.
|
||||
*
|
||||
* @param UserInterface $user A UserInterface, or null if no further user should be stored
|
||||
*/
|
||||
public function setUser(UserInterface $user)
|
||||
public function setAdminUser(UserInterface $user)
|
||||
{
|
||||
$context = $this->getContext(true);
|
||||
|
||||
$user->eraseCredentials();
|
||||
|
||||
if ($context === self::CONTEXT_FRONT_OFFICE)
|
||||
$this->getSession()->setCustomerUser($user);
|
||||
else if ($context == self::CONTEXT_BACK_OFFICE)
|
||||
$this->getSession()->setAdminUser($user);
|
||||
$this->getSession()->setAdminUser($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the user from the security context
|
||||
* Sets the authenticated customer user.
|
||||
*
|
||||
* @param UserInterface $user A UserInterface, or null if no further user should be stored
|
||||
*/
|
||||
public function clear()
|
||||
public function setCustomerUser(UserInterface $user)
|
||||
{
|
||||
$context = $this->getContext(true);
|
||||
$user->eraseCredentials();
|
||||
|
||||
if ($context === self::CONTEXT_FRONT_OFFICE)
|
||||
$this->getSession()->clearCustomerUser();
|
||||
else if ($context == self::CONTEXT_BACK_OFFICE)
|
||||
$this->getSession()->clearAdminUser();
|
||||
$this->getSession()->setCustomerUser($user);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the customer from the security context
|
||||
*/
|
||||
public function clearCustomerUser()
|
||||
{
|
||||
$this->getSession()->clearCustomerUser();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the admin from the security context
|
||||
*/
|
||||
public function clearAdminUser()
|
||||
{
|
||||
$this->getSession()->clearAdminUser();
|
||||
}
|
||||
}
|
||||
@@ -68,15 +68,12 @@ class Auth extends BaseLoop
|
||||
*/
|
||||
public function exec(&$pagination)
|
||||
{
|
||||
$context = $this->getContext();
|
||||
$roles = $this->_explode($this->getRoles());
|
||||
$permissions = $this->_explode($this->getPermissions());
|
||||
|
||||
$loopResult = new LoopResult();
|
||||
|
||||
try {
|
||||
$this->securityContext->setContext($context);
|
||||
|
||||
if (true === $this->securityContext->isGranted($roles, $permissions == null ? array() : $permissions)) {
|
||||
|
||||
// Create an empty row: loop is no longer empty :)
|
||||
|
||||
@@ -52,7 +52,7 @@ class DataAccessFunctions extends AbstractSmartyPlugin
|
||||
*/
|
||||
public function adminDataAccess($params, &$smarty)
|
||||
{
|
||||
return $this->userDataAccess("Admin User", SecurityContext::CONTEXT_BACK_OFFICE, $params);
|
||||
return $this->userDataAccess("Admin User", $this->securityContext->getAdminUser(), $params);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,7 +64,7 @@ class DataAccessFunctions extends AbstractSmartyPlugin
|
||||
*/
|
||||
public function customerDataAccess($params, &$smarty)
|
||||
{
|
||||
return $this->userDataAccess("Customer User", SecurityContext::CONTEXT_FRONT_OFFICE, $params);
|
||||
return $this->userDataAccess("Customer User", $this->securityContext->getCustomerUser(), $params);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,12 +75,11 @@ class DataAccessFunctions extends AbstractSmartyPlugin
|
||||
* @return string the value of the requested attribute
|
||||
* @throws InvalidArgumentException if the object does not have the requested attribute.
|
||||
*/
|
||||
protected function userDataAccess($objectLabel, $context, $params)
|
||||
protected function userDataAccess($objectLabel, $user, $params)
|
||||
{
|
||||
$attribute = $this->getNormalizedParam($params, array('attribute', 'attrib', 'attr'));
|
||||
|
||||
if (! empty($attribute)) {
|
||||
$user = $this->securityContext->setContext($context)->getUser();
|
||||
|
||||
if (null != $user) {
|
||||
$getter = sprintf("get%s", ucfirst($attribute));
|
||||
|
||||
@@ -46,11 +46,6 @@ class Security extends AbstractSmartyPlugin
|
||||
*/
|
||||
public function checkAuthFunction($params, &$smarty)
|
||||
{
|
||||
// Context: 'front' or 'admin'
|
||||
$context = $this->getNormalizedParam($params, 'context');
|
||||
|
||||
$this->securityContext->setContext($context);
|
||||
|
||||
$roles = $this->_explode($this->getParam($params, 'roles'));
|
||||
$permissions = $this->_explode($this->getParam($params, 'permissions'));
|
||||
|
||||
|
||||
@@ -4,10 +4,10 @@ namespace Thelia\Model;
|
||||
|
||||
use Propel\Runtime\Connection\ConnectionInterface;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Thelia\Core\Event\Internal\CartEvent;
|
||||
use Thelia\Core\Event\TheliaEvents;
|
||||
use Thelia\Model\Base\CartItem as BaseCartItem;
|
||||
use Thelia\Model\ConfigQuery;
|
||||
use Thelia\Core\Event\CartEvent;
|
||||
|
||||
class CartItem extends BaseCartItem
|
||||
{
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace Thelia\Model;
|
||||
|
||||
use Symfony\Component\Config\Definition\Exception\Exception;
|
||||
use Thelia\Core\Event\Internal\CustomerEvent;
|
||||
use Thelia\Model\Base\Customer as BaseCustomer;
|
||||
|
||||
use Thelia\Model\Exception\InvalidArgumentException;
|
||||
@@ -17,6 +16,7 @@ use Propel\Runtime\Connection\ConnectionInterface;
|
||||
use Propel\Runtime\Propel;
|
||||
use Thelia\Model\Map\CustomerTableMap;
|
||||
use Thelia\Core\Security\Role\Role;
|
||||
use Thelia\Core\Event\CustomerEvent;
|
||||
|
||||
/**
|
||||
* Skeleton subclass for representing a row from the 'customer' table.
|
||||
|
||||
Reference in New Issue
Block a user