Merge branch 'master' into loops

This commit is contained in:
Etienne Roudeix
2013-07-31 14:03:09 +02:00
40 changed files with 1257 additions and 132 deletions

View File

@@ -26,6 +26,10 @@ namespace Thelia\Action;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Thelia\Core\Event\ActionEvent;
use Thelia\Core\HttpFoundation\Session\Session;
use Thelia\Model\CartQuery;
use Thelia\Model\Cart as CartModel;
use Thelia\Model\Customer;
class Cart implements EventSubscriberInterface
@@ -91,4 +95,87 @@ class Cart implements EventSubscriberInterface
"action.modifyArticle" => array("modifyArticle", 128),
);
}
public function getCart(Request $request)
{
if(null !== $cart = $request->getSession()->getCart()){
return $cart;
}
if ($request->cookies->has("thelia_cart")) {
//le cookie de panier existe, on le récupère
$token = $request->cookies->get("thelia_cart");
$cart = CartQuery::create()->findOneByToken($token);
if ($cart) {
//le panier existe en base
$customer = $request->getSession()->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);
}
} else {
if ($cart->getCustomerId() != null) {
//il faut dupliquer le panier sans le customer_id
$cart = $this->duplicateCart($cart, $request->getSession());
}
}
} else {
$cart = $this->createCart($request->getSession());
}
} 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());
}
return $cart;
}
/**
* @param Session $session
* @return CartModel
*/
protected function createCart(Session $session)
{
$cart = new CartModel();
$cart->setToken($this->generateCookie());
if(null !== $customer = $session->getCustomerUser()) {
$cart->setCustomer($customer);
}
$cart->save();
$session->setCart($cart->getId());
return $cart;
}
/**
* @param CartModel $cart
* @param Session $session
* @param Customer $customer
* @return CartModel
*/
protected function duplicateCart(CartModel $cart, Session $session, Customer $customer = null)
{
$newCart = $cart->duplicate($this->generateCookie(), $customer);
$session->setCart($newCart->getId());
return $newCart;
}
protected function generateCookie()
{
$id = uniqid('', true);
setcookie("thelia_cart", $id, time()+(60*60*24*365));
return $id;
}
}

View File

@@ -56,8 +56,6 @@ class Customer implements EventSubscriberInterface
public function create(ActionEvent $event)
{
$event->getDispatcher()->dispatch(TheliaEvents::BEFORE_CREATECUSTOMER, $event);
$request = $event->getRequest();
$customerCreationForm = new CustomerCreation($request);
@@ -71,8 +69,11 @@ class Customer implements EventSubscriberInterface
if ($form->isValid()) {
$data = $form->getData();
$customer = new CustomerModel();
try {
$customer->createOrUpdate(
$event->getDispatcher()->dispatch(TheliaEvents::BEFORE_CREATECUSTOMER, $event);
$customer->createOrUpdate(
$data["title"],
$data["firstname"],
$data["lastname"],
@@ -120,8 +121,6 @@ class Customer implements EventSubscriberInterface
public function modify(ActionEvent $event)
{
$event->getDispatcher()->dispatch(TheliaEvents::BEFORE_CHANGECUSTOMER, $event);
$request = $event->getRequest();
$customerModification = new CustomerModification($request);
@@ -137,7 +136,10 @@ class Customer implements EventSubscriberInterface
$customer = CustomerQuery::create()->findPk(1);
try {
$data = $form->getData();
$event->getDispatcher()->dispatch(TheliaEvents::BEFORE_CHANGECUSTOMER, $event);
$data = $form->getData();
$customer->createOrUpdate(
$data["title"],
$data["firstname"],

View File

@@ -37,6 +37,7 @@ use Thelia\Core\Security\SecurityContext;
use Thelia\Tools\URL;
use Thelia\Tools\Redirect;
use Thelia\Core\Template\ParserContext;
use Thelia\Core\Event\ActionEvent;
/**
*
@@ -133,10 +134,21 @@ class BaseAdminController extends ContainerAware
return $this->container->get('request');
}
/**
* 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) {
$this->container->get("event_dispatcher")->dispatch($eventName, $event);
}
/**
* Returns the session from the current request
*
* @return Ambigous <NULL, \Symfony\Component\HttpFoundation\Session\SessionInterface>
* @return \Symfony\Component\HttpFoundation\Session\SessionInterface
*/
protected function getSession() {
@@ -146,8 +158,7 @@ class BaseAdminController extends ContainerAware
}
/**
*
* @return a ParserInterface instance parser, as configured.
* @return a ParserInterface instance parser
*/
protected function getParser()
{
@@ -159,16 +170,6 @@ class BaseAdminController extends ContainerAware
return $parser;
}
protected function getFormFactory()
{
return BaseForm::getFormFactory($this->getRequest(), ConfigQuery::read("form.secret.admin", md5(__DIR__)));
}
protected function getFormBuilder()
{
return $this->getFormFactory()->createBuilder("form");
}
/**
* Forwards the request to another controller.
*

View File

@@ -31,6 +31,7 @@ use Thelia\Core\Security\Exception\AuthenticationException;
use Symfony\Component\Validator\Exception\ValidatorException;
use Thelia\Tools\URL;
use Thelia\Tools\Redirect;
use Thelia\Core\Event\TheliaEvents;
class SessionController extends BaseAdminController {
@@ -41,6 +42,8 @@ class SessionController extends BaseAdminController {
public function checkLogoutAction()
{
$this->dispatch(TheliaEvents::ADMIN_LOGOUT);
$this->getSecurityContext()->clear();
// Go back to login page.
@@ -64,6 +67,8 @@ class SessionController extends BaseAdminController {
// Log authentication success
AdminLog::append("Authentication successuful", $request, $user);
$this->dispatch(TheliaEvents::ADMIN_LOGIN);
// Redirect to the success URL
return Redirect::exec($adminLoginForm->getSuccessUrl());
}

View File

@@ -14,6 +14,8 @@
<loop class="Thelia\Core\Template\Loop\Feature" name="feature"/>
<loop class="Thelia\Core\Template\Loop\FeatureAvailable" name="feature_available"/>
<loop class="Thelia\Core\Template\Loop\FeatureValue" name="feature_value"/>
<loop class="Thelia\Core\Template\Loop\Order" name="order"/>
<loop class="Thelia\Core\Template\Loop\OrderStatus" name="order-status"/>
<loop class="Thelia\Core\Template\Loop\Product" name="product"/>
<loop class="Thelia\Core\Template\Loop\Feed" name="feed"/>
<loop class="Thelia\Core\Template\Loop\Title" name="title"/>
@@ -137,6 +139,12 @@
<argument type="service" id="thelia.securityContext" />
</service>
<service id="smarty.plugin.dataAccess" class="Thelia\Core\Template\Smarty\Plugins\DataAccessFunctions" scope="request">
<tag name="thelia.parser.register_plugin"/>
<argument type="service" id="thelia.securityContext" />
<argument type="service" id="thelia.parser.context"/>
</service>
<service id="http_kernel" class="Thelia\Core\TheliaHttpKernel">
<argument type="service" id="event_dispatcher" />
<argument type="service" id="service_container" />

View File

@@ -25,8 +25,7 @@ namespace Thelia\Core\Event;
/**
*
* Class containing all Thelia events name using in Thelia Core
*
* This class contains all Thelia events identifiers used by Thelia Core
*
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
@@ -37,25 +36,56 @@ final class TheliaEvents
/**
* ACTION event
*
* Send if no action are already present in Thelia action process ( see Thelia\Routing\Matcher\ActionMatcher)
* Sent if no action are already present in Thelia action process ( see Thelia\Routing\Matcher\ActionMatcher)
*/
const ACTION = "thelia.action";
/**
* INCLUDE event
*
* Send before starting thelia inclusion
* Sent before starting thelia inclusion
*/
const INCLUSION = "thelia.include";
/**
* Sent before the logout of the customer.
*/
const CUSTOMER_LOGOUT = "action.customer_logout";
/**
* Sent once the customer is successfully logged in.
*/
const CUSTOMER_LOGIN = "action.customer_login";
/**
* Sent before the logout of the administrator.
*/
const ADMIN_LOGOUT = "action.admin_logout";
/**
* Sent once the administrator is successfully logged in.
*/
const ADMIN_LOGIN = "action.admin_login";
/**
* Sent once the customer creation form has been successfully validated, and before customer insertion in the database.
*/
const BEFORE_CREATECUSTOMER = "action.before_createcustomer";
/**
* Sent just after a successful insert of a new customer in the database.
*/
const AFTER_CREATECUSTOMER = "action.after_createcustomer";
/**
* Sent once the customer change form has been successfully validated, and before customer update in the database.
*/
const BEFORE_CHANGECUSTOMER = "action.before_changecustomer";
/**
* Sent just after a successful update of a customer in the database.
*/
const AFTER_CHANGECUSTOMER = "action.after_changecustomer";
/**
* Sent before customer insertion, to allow modules to create a custom customer reference.
*/
const CREATECUSTOMER_CUSTOMREF = "customer.creation.customref";
}
}

View File

@@ -25,13 +25,14 @@ namespace Thelia\Core\HttpFoundation\Session;
use Symfony\Component\HttpFoundation\Session\Session as BaseSession;
use Thelia\Core\Security\User\UserInterface;
use Thelia\Form\BaseForm;
use Thelia\Model\ConfigQuery;
use Thelia\Exception\InvalidCartException;
use Thelia\Model\CartQuery;
use Thelia\Model\Cart;
use Thelia\Tools\URL;
class Session extends BaseSession {
// -- Language ------------------------------------------------------------
class Session extends BaseSession
{
// -- Language ------------------------------------------------------------
public function getLocale()
{
@@ -47,41 +48,61 @@ class Session extends BaseSession {
public function setCustomerUser(UserInterface $user)
{
$this->set('customer_user', $user);
$this->set('customer_user', $user);
}
public function getCustomerUser()
{
return $this->get('customer_user');
return $this->get('customer_user');
}
public function clearCustomerUser()
{
return $this->remove('customer_user');
return $this->remove('customer_user');
}
// -- Admin user -----------------------------------------------------------
public function setAdminUser(UserInterface $user)
{
$this->set('admin_user', $user);
$this->set('admin_user', $user);
}
public function getAdminUser()
{
return $this->get('admin_user');
return $this->get('admin_user');
}
public function clearAdminUser()
{
return $this->remove('admin_user');
return $this->remove('admin_user');
}
// -- Error form -----------------------------------------------------------
/**
* @param string $formName the form name
*/
public function setErrorFormName($formName)
{
$this->set('error_form', $formName);
}
public function getErrorFormName()
{
return $this->get('error_form', null);
}
public function clearErrorFormName()
{
return $this->remove('error_form');
}
// -- Return page ----------------------------------------------------------
public function setReturnToUrl($url)
{
$this->set('return_to_url', $url);
$this->set('return_to_url', $url);
}
/**
@@ -90,7 +111,56 @@ class Session extends BaseSession {
*/
public function getReturnToUrl()
{
return $this->get('return_to_url', URL::getIndexPage());
return $this->get('return_to_url', URL::getIndexPage());
}
// -- Cart ------------------------------------------------------------------
/**
* return cart if exists and is valid (checking customer)
*
* @return \Thelia\Model\Cart|null
*/
public function getCart()
{
$cart_id = $this->get("cart_id");
$cart = null;
if ($cart_id) {
$cart = CartQuery::create()->findPk($cart_id);
try {
$this->verifyValidCart($cart);
} catch (InvalidCartException $e) {
$cart = null;
}
}
return $cart;
}
/**
*
*
* @param \Thelia\Model\Cart $cart
* @throws \Thelia\Exception\InvalidCartException
*/
protected function verifyValidCart(Cart $cart)
{
$customer = $this->getCustomerUser();
if ($customer && $cart->getCustomerId() != $customer->getId()) {
throw new InvalidCartException("customer in session and customer_id in cart are not the same");
} else if($customer === null && $cart->getCustomerId() !== null) {
throw new InvalidCartException("Customer exists in cart and not in session");
}
}
/**
* assign cart id in session
*
* @param $cart_id
*/
public function setCart($cart_id)
{
$this->set("cart_id", $cart_id);
}
}

View File

@@ -55,6 +55,8 @@ class SecurityContext {
}
$this->context = $context;
return $this;
}
public function getContext($exception_if_context_undefined = false) {
@@ -133,7 +135,7 @@ class SecurityContext {
// Get permissions from profile
// $userPermissions = $user->getPermissions();
echo "TODO: Finalize permissions system !";
// TODO: Finalize permissions system !;
$userPermissions = array('*'); // FIXME !

View File

@@ -0,0 +1,59 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Core\Template\Loop;
use Thelia\Core\Template\Element\BaseLoop;
use Thelia\Core\Template\Element\LoopResult;
use Thelia\Core\Template\Element\LoopResultRow;
use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Type\TypeCollection;
use Thelia\Type;
/**
*
* @package Thelia\Core\Template\Loop
*
* @author Franck Allimant <franck@cqfdev.fr>
*/
class Order extends BaseLoop
{
public function getArgDefinitions()
{
return new ArgumentCollection();
}
/**
*
*
* @return \Thelia\Core\Template\Element\LoopResult
*/
public function exec(&$pagination)
{
// TODO : a coder !
return new LoopResult();
}
}

View File

@@ -0,0 +1,59 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Core\Template\Loop;
use Thelia\Core\Template\Element\BaseLoop;
use Thelia\Core\Template\Element\LoopResult;
use Thelia\Core\Template\Element\LoopResultRow;
use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Type\TypeCollection;
use Thelia\Type;
/**
*
* @package Thelia\Core\Template\Loop
*
* @author Franck Allimant <franck@cqfdev.fr>
*/
class OrderStatus extends BaseLoop
{
public function getArgDefinitions()
{
return new ArgumentCollection();
}
/**
*
*
* @return \Thelia\Core\Template\Element\LoopResult
*/
public function exec(&$pagination)
{
// TODO : a coder !
return new LoopResult();
}
}

View File

@@ -44,6 +44,7 @@ class ParserContext implements \IteratorAggregate
->set('BASE_URL' , ConfigQuery::read('base_url', '/'))
->set('INDEX_PAGE' , URL::getIndexPage())
->set('RETURN_TO_URL' , URL::absoluteUrl($request->getSession()->getReturnToUrl()))
->set('THELIA_VERSION' , ConfigQuery::read('thelia_version', 'undefined'))
;
}

View File

@@ -0,0 +1,58 @@
<?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\Template\Smarty;
/**
*
* The class all Smarty Thelia plugin shoud extend
*
* Class AbstractSmartyPlugin
* @package Thelia\Core\Template\Smarty
*/
abstract class AbstractSmartyPlugin
{
/**
* Explode a comma separated list in a array, trimming all array elements
*
* @param unknown $commaSeparatedValues
* @return multitype:
*/
protected function _explode($commaSeparatedValues)
{
$array = explode(',', $commaSeparatedValues);
if (array_walk($array, function(&$item) {
$item = strtoupper(trim($item));
})) {
return $array;
}
return array();
}
/**
* @return an array of SmartyPluginDescriptor
*/
public abstract function getPluginDescriptors();
}

View File

@@ -50,10 +50,7 @@ class SmartyAssetsManager
$this->assetic_manager = new AsseticHelper();
}
public function processSmartyPluginCall($assetType, $params, $content, \Smarty_Internal_Template $template, &$repeat)
{
// Opening tag (first call only)
if ($repeat) {
public function computeAssetUrl($assetType, $params, \Smarty_Internal_Template $template) {
$file = $params['file'];
$filters = isset($params['filters']) ? $params['filters'] : '';
$debug = isset($params['debug']) ? trim(strtolower($params['debug'])) == 'true' : false;
@@ -79,7 +76,17 @@ class SmartyAssetsManager
$debug
);
return $url;
}
public function processSmartyPluginCall($assetType, $params, $content, \Smarty_Internal_Template $template, &$repeat)
{
// Opening tag (first call only)
if ($repeat) {
$url = $this->computeAssetUrl($assetType, $params, $template);
$template->assign('asset_url', $url);
} elseif (isset($content)) {
return $content;
}

View File

@@ -24,12 +24,12 @@
namespace Thelia\Core\Template\Smarty\Plugins;
use Thelia\Core\Template\Smarty\SmartyPluginDescriptor;
use Thelia\Core\Template\Smarty\SmartyPluginInterface;
use Thelia\Core\Template\Smarty\AbstractSmartyPlugin;
use Thelia\Core\Template\Smarty\Assets\SmartyAssetsManager;
class Assetic implements SmartyPluginInterface
class Assetic extends AbstractSmartyPlugin
{
public $asset_manager;
public $assetManager;
public function __construct()
{
@@ -37,22 +37,27 @@ class Assetic implements SmartyPluginInterface
$asset_dir_from_web_root = 'assets/admin/default'; // FIXME
$this->asset_manager = new SmartyAssetsManager($web_root, $asset_dir_from_web_root);
$this->assetManager = new SmartyAssetsManager($web_root, $asset_dir_from_web_root);
}
public function theliaBlockJavascripts($params, $content, \Smarty_Internal_Template $template, &$repeat)
public function blockJavascripts($params, $content, \Smarty_Internal_Template $template, &$repeat)
{
return $this->asset_manager->processSmartyPluginCall('js', $params, $content, $template, $repeat);
return $this->assetManager->processSmartyPluginCall('js', $params, $content, $template, $repeat);
}
public function theliaBlockImages($params, $content, \Smarty_Internal_Template $template, &$repeat)
public function blockImages($params, $content, \Smarty_Internal_Template $template, &$repeat)
{
return $this->asset_manager->processSmartyPluginCall(SmartyAssetsManager::ASSET_TYPE_AUTO, $params, $content, $template, $repeat);
return $this->assetManager->processSmartyPluginCall(SmartyAssetsManager::ASSET_TYPE_AUTO, $params, $content, $template, $repeat);
}
public function theliaBlockStylesheets($params, $content, \Smarty_Internal_Template $template, &$repeat)
public function blockStylesheets($params, $content, \Smarty_Internal_Template $template, &$repeat)
{
return $this->asset_manager->processSmartyPluginCall('css', $params, $content, $template, $repeat);
return $this->assetManager->processSmartyPluginCall('css', $params, $content, $template, $repeat);
}
public function functionImage($params, \Smarty_Internal_Template $template)
{
return $this->assetManager->computeAssetUrl(SmartyAssetsManager::ASSET_TYPE_AUTO, $params, $template);
}
/**
@@ -63,9 +68,10 @@ class Assetic implements SmartyPluginInterface
public function getPluginDescriptors()
{
return array(
new SmartyPluginDescriptor('block', 'stylesheets', $this, 'theliaBlockStylesheets'),
new SmartyPluginDescriptor('block', 'javascripts', $this, 'theliaBlockJavascripts'),
new SmartyPluginDescriptor('block', 'images' , $this, 'theliaBlockImages')
new SmartyPluginDescriptor('block' , 'stylesheets', $this, 'blockStylesheets'),
new SmartyPluginDescriptor('block' , 'javascripts', $this, 'blockJavascripts'),
new SmartyPluginDescriptor('block' , 'images' , $this, 'blockImages'),
new SmartyPluginDescriptor('function', 'image' , $this, 'functionImage')
);
}
}

View File

@@ -0,0 +1,112 @@
<?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\Template\Smarty\Plugins;
use Thelia\Core\Template\Smarty\AbstractSmartyPlugin;
use Thelia\Core\Security\SecurityContext;
use Thelia\Core\Template\ParserContext;
use Thelia\Core\Template\Smarty\SmartyPluginDescriptor;
/**
* Implementation of data access to main Thelia objects (users, cart, etc.)
*
* @author Franck Allimant <franck@cqfdev.fr>
*
*/
class DataAccessFunctions extends AbstractSmartyPlugin
{
private $securityContext;
protected $parserContext;
public function __construct(SecurityContext $securityContext, ParserContext $parserContext)
{
$this->securityContext = $securityContext;
}
/**
* Provides access to the current logged administrator attributes using the accessors.
*
* @param array $params
* @param unknown $smarty
* @return string the value of the requested attribute
*/
public function adminDataAccess($params, &$smarty)
{
return $this->userDataAccess("Admin User", SecurityContext::CONTEXT_BACK_OFFICE, $params);
}
/**
* Provides access to the current logged customer attributes throught the accessor
*
* @param array $params
* @param unknown $smarty
* @return string the value of the requested attribute
*/
public function customerDataAccess($params, &$smarty)
{
return $this->userDataAccess("Customer User", SecurityContext::CONTEXT_FRONT_OFFICE, $params);
}
/**
* Provides access to user attributes using the accessors.
*
* @param array $params
* @param unknown $smarty
* @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)
{
$attribute = $params['attr'];
if (! empty($attribute)) {
$user = $this->securityContext->setContext($context)->getUser();
if (null != $user) {
$getter = sprintf("get%s", ucfirst(strtolower($attribute)));
if (method_exists($user, $getter)) {
return $user->$getter();
}
throw new \InvalidArgumentException(sprintf("%s has no '%s' attribute", $objectLabel, $attribute));
}
}
return '';
}
/**
* Define the various smarty plugins hendled by this class
*
* @return an array of smarty plugin descriptors
*/
public function getPluginDescriptors()
{
return array(
new SmartyPluginDescriptor('function', 'admin', $this, 'adminDataAccess'),
new SmartyPluginDescriptor('function', 'customer', $this, 'customerDataAccess')
);
}
}

View File

@@ -27,7 +27,7 @@ use Thelia\Form\BaseForm;
use Thelia\Core\Template\Element\Exception\ElementNotFoundException;
use Symfony\Component\HttpFoundation\Request;
use Thelia\Core\Template\Smarty\SmartyPluginDescriptor;
use Thelia\Core\Template\Smarty\SmartyPluginInterface;
use Thelia\Core\Template\Smarty\AbstractSmartyPlugin;
use Thelia\Log\Tlog;
use Thelia\Core\Template\ParserContext;
@@ -55,7 +55,7 @@ use Thelia\Core\Template\ParserContext;
* Class Form
* @package Thelia\Core\Template\Smarty\Plugins
*/
class Form implements SmartyPluginInterface
class Form extends AbstractSmartyPlugin
{
protected $request;

View File

@@ -24,9 +24,9 @@
namespace Thelia\Core\Template\Smarty\Plugins;
use Thelia\Core\Template\Smarty\SmartyPluginDescriptor;
use Thelia\Core\Template\Smarty\SmartyPluginInterface;
use Thelia\Core\Template\Smarty\AbstractSmartyPlugin;
class Module implements SmartyPluginInterface
class Module extends AbstractSmartyPlugin
{
/**
* Process theliaModule template inclusion function

View File

@@ -24,12 +24,12 @@
namespace Thelia\Core\Template\Smarty\Plugins;
use Thelia\Core\Template\Smarty\SmartyPluginDescriptor;
use Thelia\Core\Template\Smarty\SmartyPluginInterface;
use Thelia\Core\Template\Smarty\AbstractSmartyPlugin;
use Thelia\Core\Template\Smarty\Assets\SmartyAssetsManager;
use Thelia\Core\Security\SecurityContext;
use Thelia\Core\Security\Exception\AuthenticationException;
class Security implements SmartyPluginInterface
class Security extends AbstractSmartyPlugin
{
private $securityContext;
@@ -38,19 +38,6 @@ class Security implements SmartyPluginInterface
$this->securityContext = $securityContext;
}
private function _explode($commaSeparatedValues)
{
$array = explode(',', $commaSeparatedValues);
if (array_walk($array, function(&$item) {
$item = strtoupper(trim($item));
})) {
return $array;
}
return array();
}
/**
* Process security check function
*

View File

@@ -24,7 +24,7 @@
namespace Thelia\Core\Template\Smarty\Plugins;
use Thelia\Core\Template\Element\BaseLoop;
use Thelia\Core\Template\Smarty\SmartyPluginInterface;
use Thelia\Core\Template\Smarty\AbstractSmartyPlugin;
use Thelia\Core\Template\Smarty\SmartyPluginDescriptor;
use Thelia\Core\Template\Element\Exception\ElementNotFoundException;
@@ -34,7 +34,7 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Thelia\Core\Security\SecurityContext;
class TheliaLoop implements SmartyPluginInterface
class TheliaLoop extends AbstractSmartyPlugin
{
protected static $pagination = null;
@@ -68,6 +68,23 @@ class TheliaLoop implements SmartyPluginInterface
}
}
/**
* Process the count function: executes a loop and return the number of items found
*/
public function theliaCount($params, $template) {
if (empty($params['type']))
throw new \InvalidArgumentException("Missing 'type' parameter in count arguments");
$loop = $this->createLoopInstance($params);
$dummy = null;
$loopResults = $loop->exec($dummy);
return $loopResults->valid() ? $loopResults->getCount() : 0;
}
/**
* Process {loop name="loop name" type="loop type" ... } ... {/loop} block
*
@@ -343,10 +360,11 @@ class TheliaLoop implements SmartyPluginInterface
{
return array(
new SmartyPluginDescriptor('block', 'loop' , $this, 'theliaLoop'),
new SmartyPluginDescriptor('block', 'elseloop' , $this, 'theliaElseloop'),
new SmartyPluginDescriptor('block', 'ifloop' , $this, 'theliaIfLoop'),
new SmartyPluginDescriptor('block', 'pageloop' , $this, 'theliaPageLoop'),
new SmartyPluginDescriptor('function', 'count' , $this, 'theliaCount'),
new SmartyPluginDescriptor('block' , 'loop' , $this, 'theliaLoop'),
new SmartyPluginDescriptor('block' , 'elseloop' , $this, 'theliaElseloop'),
new SmartyPluginDescriptor('block' , 'ifloop' , $this, 'theliaIfLoop'),
new SmartyPluginDescriptor('block' , 'pageloop' , $this, 'theliaPageLoop'),
);
}
}

View File

@@ -23,7 +23,7 @@
namespace Thelia\Core\Template\Smarty\Plugins;
use Thelia\Core\Template\Smarty\SmartyPluginDescriptor;
use Thelia\Core\Template\Smarty\SmartyPluginInterface;
use Thelia\Core\Template\Smarty\AbstractSmartyPlugin;
/**
* Class TheliaSyntax
@@ -31,7 +31,7 @@ use Thelia\Core\Template\Smarty\SmartyPluginInterface;
*
* @author Etienne Roudeix <eroudeix@openstudio.fr>
*/
class TheliaSyntax implements SmartyPluginInterface
class TheliaSyntax extends AbstractSmartyPlugin
{
public function dieseCancel($value, $diese)
{

View File

@@ -24,10 +24,10 @@
namespace Thelia\Core\Template\Smarty\Plugins;
use Thelia\Core\Template\Smarty\SmartyPluginDescriptor;
use Thelia\Core\Template\Smarty\SmartyPluginInterface;
use Thelia\Core\Template\Smarty\AbstractSmartyPlugin;
use Symfony\Component\Translation\TranslatorInterface;
class Translation implements SmartyPluginInterface
class Translation extends AbstractSmartyPlugin
{
protected $translator;
@@ -44,7 +44,15 @@ class Translation implements SmartyPluginInterface
*/
public function translate($params, &$smarty)
{
return $this->translator->trans($params['l'], isset($params['p']) ? $params['p'] : array());
// All parameters other than 'l' are supposed to be variables. Build an array of var => value pairs
// and pass it to the translator
$vars = array();
foreach($params as $name => $value) {
$vars["%$name"] = $value;
}
return $this->translator->trans($params['l'], $vars);
}
/**

View File

@@ -24,11 +24,11 @@
namespace Thelia\Core\Template\Smarty\Plugins;
use Thelia\Core\Template\Smarty\SmartyPluginDescriptor;
use Thelia\Core\Template\Smarty\SmartyPluginInterface;
use Thelia\Core\Template\Smarty\AbstractSmartyPlugin;
use Thelia\Tools\URL;
use Thelia\Core\HttpFoundation\Request;
class UrlGenerator implements SmartyPluginInterface
class UrlGenerator extends AbstractSmartyPlugin
{
protected $request;

View File

@@ -10,7 +10,7 @@ use \Smarty;
use Symfony\Component\HttpFoundation\Response;
use Thelia\Core\Template\ParserInterface;
use Thelia\Core\Template\Smarty\SmartyPluginInterface;
use Thelia\Core\Template\Smarty\AbstractSmartyPlugin;
use Thelia\Core\Template\Exception\ResourceNotFoundException;
use Thelia\Core\Template\ParserContext;
use Thelia\Model\ConfigQuery;
@@ -177,7 +177,7 @@ class SmartyParser extends Smarty implements ParserInterface
$this->status = $status;
}
public function addPlugins(SmartyPluginInterface $plugin)
public function addPlugins(AbstractSmartyPlugin $plugin)
{
$this->plugins[] = $plugin;
}

View File

@@ -42,7 +42,7 @@ class SmartyPluginDescriptor
protected $name;
/**
* @var SmartyPluginInterface plugin implmentation class
* @var AbstractSmartyPlugin plugin implmentation class
*/
protected $class;

View File

@@ -4,7 +4,7 @@
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
@@ -21,19 +21,10 @@
/* */
/*************************************************************************************/
namespace Thelia\Core\Template\Smarty;
/**
*
* this interface must be implements when you want to add plugin to smarty using config process
*
* Interface SmartyPluginInterface
* @package Thelia\Core\Template\Smarty
*/
interface SmartyPluginInterface
{
/**
* @return an array of SmartyPluginDescriptor
*/
public function getPluginDescriptors();
}
namespace Thelia\Exception;
class InvalidCartException extends \RuntimeException {
}

View File

@@ -7,4 +7,30 @@ use Thelia\Model\Base\Cart as BaseCart;
class Cart extends BaseCart
{
public function duplicate($token, Customer $customer = null)
{
$cartItems = $this->getCartItems();
$cart = new Cart();
$cart->setAddressDeliveryId($this->getAddressDeliveryId());
$cart->setAddressInvoiceId($this->getAddressInvoiceId());
$cart->setToken($token);
if ($customer){
$cart->setCustomer($customer);
}
// TODO : set current Currency
//$cart->setCurrency()
$cart->save();
foreach ($cartItems as $cartItem){
$item = new CartItem();
$item->setCart($cart);
$item->setProductId($cartItem->getProductId());
$item->setQuantity($cartItem->getQuantity());
$item->save();
}
return $cart;
}
}

View File

@@ -3,7 +3,7 @@
namespace Thelia\Model;
use Thelia\Model\Base\CartQuery as BaseCartQuery;
use Symfony\Component\HttpFoundation\Request;
/**
* Skeleton subclass for performing query and update operations on the 'cart' table.
@@ -18,4 +18,5 @@ use Thelia\Model\Base\CartQuery as BaseCartQuery;
class CartQuery extends BaseCartQuery
{
} // CartQuery

View File

@@ -116,7 +116,7 @@ class Customer extends BaseCustomer implements UserInterface
protected function generateRef()
{
return date("YmdHisu");
return uniqid(substr($this->getLastname(), 0, (strlen($this->getLastname()) >= 3) ? 3 : strlen($this->getLastname())), true);
}
public function setPassword($password)

View File

@@ -0,0 +1,239 @@
<?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\Tests\Action;
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
use Thelia\Core\HttpFoundation\Request;
use Thelia\Core\HttpFoundation\Session\Session;
use Thelia\Model\Cart;
use Thelia\Model\Customer;
class CartTest extends \PHPUnit_Framework_TestCase
{
protected $session;
protected $request;
protected $actionCart;
protected $uniqid;
public function setUp()
{
$this->session = new Session(new MockArraySessionStorage());
$this->request = new Request();
$this->request->setSession($this->session);
$this->uniqid = uniqid('', true);
$this->actionCart = $this->getMock(
"\Thelia\Action\Cart",
array("generateCookie")
);
$this->actionCart
->expects($this->any())
->method("generateCookie")
->will($this->returnValue($this->uniqid));
}
/**
* no cart present in session and cart_id no yet exists in cookies.
*
* In this case, a new cart instance must be create
*/
public function testGetCartWithoutCustomerAndWithoutExistingCart()
{
$actionCart = $this->actionCart;
$cart = $actionCart->getCart($this->request);
$this->assertInstanceOf("Thelia\Model\Cart", $cart, '$cart must be an instance of cart model Thelia\Model\Cart');
$this->assertNull($cart->getCustomerId());
$this->assertNull($cart->getAddressDeliveryId());
$this->assertNull($cart->getAddressInvoiceId());
$this->assertEquals($this->uniqid, $cart->getToken());
}
/**
* Customer is connected but his cart does not exists yet
*
* Cart must be created and associated to the current connected Customer
*/
public function testGetCartWithCustomerAndWithoutExistingCart()
{
$actionCart = $this->actionCart;
$request = $this->request;
//create a fake customer just for test. If not persists test fails !
$customer = new Customer();
$customer->setFirstname("john");
$customer->setLastname("doe");
$customer->setTitleId(1);
$customer->save();
$request->getSession()->setCustomerUser($customer);
$cart = $actionCart->getCart($request);
$this->assertInstanceOf("Thelia\Model\Cart", $cart, '$cart must be an instance of cart model Thelia\Model\Cart');
$this->assertNotNull($cart->getCustomerId());
$this->assertEquals($customer->getId(), $cart->getCustomerId());
$this->assertNull($cart->getAddressDeliveryId());
$this->assertNull($cart->getAddressInvoiceId());
$this->assertEquals($this->uniqid, $cart->getToken());
}
/**
* Cart exists and his id put in cookies.
*
* Must return the same cart instance
*/
public function testGetCartWithoutCustomerAndWithExistingCart()
{
$actionCart = $this->actionCart;
$request = $this->request;
$uniqid = uniqid("test1", true);
//create a fake cart in database;
$cart = new Cart();
$cart->setToken($uniqid);
$cart->save();
$request->cookies->set("thelia_cart", $uniqid);
$getCart = $actionCart->getCart($request);
$this->assertInstanceOf("Thelia\Model\Cart", $getCart, '$cart must be an instance of cart model Thelia\Model\Cart');
$this->assertNull($getCart->getCustomerId());
$this->assertNull($getCart->getAddressDeliveryId());
$this->assertNull($getCart->getAddressInvoiceId());
$this->assertEquals($cart->getToken(), $getCart->getToken());
}
/**
* a cart id exists in cookies but this id does not exists yet in databases
*
* a new cart must be created (different token)
*/
public function testGetCartWithExistingCartButNotGoodCookies()
{
$actionCart = $this->actionCart;
$request = $this->request;
$token = "WrongToken";
$request->cookies->set("thelia_cart", $token);
$cart = $actionCart->getCart($request);
$this->assertInstanceOf("Thelia\Model\Cart", $cart, '$cart must be an instance of cart model Thelia\Model\Cart');
$this->assertNull($cart->getCustomerId());
$this->assertNull($cart->getAddressDeliveryId());
$this->assertNull($cart->getAddressInvoiceId());
$this->assertNotEquals($token, $cart->getToken());
}
/**
* cart and customer already exists. Cart and customer are linked.
*
* cart in session must be return
*/
public function testGetCartWithExistingCartAndCustomer()
{
$actionCart = $this->actionCart;
$request = $this->request;
//create a fake customer just for test. If not persists test fails !
$customer = new Customer();
$customer->setFirstname("john");
$customer->setLastname("doe");
$customer->setTitleId(1);
$customer->save();
$uniqid = uniqid("test2", true);
//create a fake cart in database;
$cart = new Cart();
$cart->setToken($uniqid);
$cart->setCustomer($customer);
$cart->save();
$request->cookies->set("thelia_cart", $uniqid);
$request->getSession()->setCustomerUser($customer);
$getCart = $actionCart->getCart($request);
$this->assertInstanceOf("Thelia\Model\Cart", $getCart, '$cart must be an instance of cart model Thelia\Model\Cart');
$this->assertNotNull($getCart->getCustomerId());
$this->assertNull($getCart->getAddressDeliveryId());
$this->assertNull($getCart->getAddressInvoiceId());
$this->assertEquals($cart->getToken(), $getCart->getToken(), "token must be the same");
$this->assertEquals($customer->getId(), $getCart->getCustomerId());
}
/**
* Customer is connected but cart not associated to him
*
* A new cart must be created (duplicated) containing customer id
*/
public function testGetCartWithExistinsCartAndCustomerButNotSameCustomerId()
{
$actionCart = $this->actionCart;
$request = $this->request;
//create a fake customer just for test. If not persists test fails !
$customer = new Customer();
$customer->setFirstname("john");
$customer->setLastname("doe");
$customer->setTitleId(1);
$customer->save();
$uniqid = uniqid("test3", true);
//create a fake cart in database;
$cart = new Cart();
$cart->setToken($uniqid);
$cart->save();
$request->cookies->set("thelia_cart", $uniqid);
$request->getSession()->setCustomerUser($customer);
$getCart = $actionCart->getCart($request);
$this->assertInstanceOf("Thelia\Model\Cart", $getCart, '$cart must be an instance of cart model Thelia\Model\Cart');
$this->assertNotNull($getCart->getCustomerId());
$this->assertNull($getCart->getAddressDeliveryId());
$this->assertNull($getCart->getAddressInvoiceId());
$this->assertNotEquals($cart->getToken(), $getCart->getToken(), "token must be different");
$this->assertEquals($customer->getId(), $getCart->getCustomerId());
}
}

View File

@@ -1,12 +1,25 @@
<?php
/**
* Created by JetBrains PhpStorm.
* User: manu
* Date: 11/07/13
* Time: 10:34
* To change this template use File | Settings | File Templates.
*/
/*************************************************************************************/
/* */
/* 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\Tests\Command;

View File

@@ -0,0 +1,136 @@
<?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\Tests\Core\HttpFoundation\Session;
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
use Thelia\Core\HttpFoundation\Session\Session;
use Thelia\Model\Cart;
use Thelia\Model\Customer;
class SessionTest extends \PHPUnit_Framework_TestCase
{
protected $session;
public function setUp()
{
$this->session = new Session(new MockArraySessionStorage());
}
public function testGetCartWithoutExistingCart()
{
$session = $this->session;
$cart = $session->getCart();
$this->assertNull($cart);
}
public function testGetCartWithExistingCartWithoutCustomerConnected()
{
$session = $this->session;
$testCart = new Cart();
$testCart->setToken(uniqid("testSessionGetCart1", true));
$testCart->save();
$session->setCart($testCart->getId());
$cart = $session->getCart();
$this->assertNotNull($cart);
$this->assertInstanceOf("\Thelia\Model\Cart", $cart, '$cart must be an instance of Thelia\Model\Cart');
$this->assertEquals($testCart->getToken(), $cart->getToken());
}
public function testGetCartWithExistingCustomerButNoCart()
{
$session = $this->session;
//create a fake customer just for test. If not persists test fails !
$customer = new Customer();
$customer->setFirstname("john test session");
$customer->setLastname("doe");
$customer->setTitleId(1);
$customer->save();
$session->setCustomerUser($customer);
$cart = $session->getCart();
$this->assertNull($cart);
}
public function testGetCartWithExistingCartAndCustomerButWithoutReferenceToCustomerInCart()
{
$session = $this->session;
//create a fake customer just for test. If not persists test fails !
$customer = new Customer();
$customer->setFirstname("john test session");
$customer->setLastname("doe");
$customer->setTitleId(1);
$customer->save();
$session->setCustomerUser($customer);
$testCart = new Cart();
$testCart->setToken(uniqid("testSessionGetCart2", true));
$testCart->save();
$session->setCart($testCart->getId());
$cart = $session->getCart();
$this->assertNull($cart);
}
public function testGetCartWithExistingCartAndCustomerAndReferencesEachOther()
{
$session = $this->session;
//create a fake customer just for test. If not persists test fails !
$customer = new Customer();
$customer->setFirstname("john test session");
$customer->setLastname("doe");
$customer->setTitleId(1);
$customer->save();
$session->setCustomerUser($customer);
$testCart = new Cart();
$testCart->setToken(uniqid("testSessionGetCart3", true));
$testCart->setCustomerId($customer->getId());
$testCart->save();
$session->setCart($testCart->getId());
$cart = $session->getCart();
$this->assertNotNull($cart);
$this->assertInstanceOf("\Thelia\Model\Cart", $cart, '$cart must be an instance of Thelia\Model\Cart');
}
}