Merge branch 'master' of github.com:thelia/thelia

This commit is contained in:
Etienne Roudeix
2013-11-12 16:01:08 +01:00
70 changed files with 1906 additions and 2322 deletions

View File

@@ -83,9 +83,10 @@ class Customer extends BaseAction implements EventSubscriberInterface
public function delete(CustomerEvent $event)
{
$customer = $event->getCustomer();
if (null !== $customer = $event->getCustomer()) {
$customer->delete();
$customer->delete();
}
}
private function createOrUpdateCustomer(CustomerModel $customer, CustomerCreateOrUpdateEvent $event)

View File

@@ -109,19 +109,17 @@
<!-- Customer rule management -->
<route id="admin.customers" path="/admin/customers">
<default key="_controller">Thelia\Controller\Admin\CustomerController::indexAction</default>
<default key="_controller">Thelia\Controller\Admin\CustomerController::defaultAction</default>
</route>
<route id="admin.customer.update.view" path="/admin/customer/update/{customer_id}" methods="get">
<default key="_controller">Thelia\Controller\Admin\CustomerController::viewAction</default>
<requirement key="customer_id">\d+</requirement>
</route>
<route id="admin.customer.update.process" path="/admin/customer/update/{customer_id}" methods="post">
<route id="admin.customer.update.view" path="/admin/customer/update">
<default key="_controller">Thelia\Controller\Admin\CustomerController::updateAction</default>
<requirement key="customer_id">\d+</requirement>
</route>
<route id="admin.customer.update.process" path="/admin/customer/save">
<default key="_controller">Thelia\Controller\Admin\CustomerController::processUpdateAction</default>
</route>
<route id="admin.customer.delete" path="/admin/customer/delete">
<default key="_controller">Thelia\Controller\Admin\CustomerController::deleteAction</default>
</route>
@@ -146,14 +144,12 @@
<default key="_controller">Thelia\Controller\Admin\AddressController::createAction</default>
</route>
<route id="admin.address.update.view" path="/admin/address/update/{address_id}">
<route id="admin.address.update.view" path="/admin/address/update">
<default key="_controller">Thelia\Controller\Admin\AddressController::updateAction</default>
<requirement key="address_id">\d+</requirement>
</route>
<route id="admin.address.save" path="/admin/address/save/{address_id}">
<route id="admin.address.save" path="/admin/address/save">
<default key="_controller">Thelia\Controller\Admin\AddressController::processUpdateAction</default>
<requirement key="address_id">\d+</requirement>
</route>
<!-- end address management -->

View File

@@ -58,6 +58,11 @@
<default key="_controller">Thelia\Controller\Front\DefaultController::noAction</default>
<default key="_view">account-password</default>
</route>
<route id="customer.order.pdf.delivery" path="/account/order/pdf/delivery/{order_id}">
<default key="_controller">Thelia\Controller\Front\OrderController::generateDeliveryPdf</default>
<requirement key="order_id">\d+</requirement>
</route>
<!-- end customer routes -->
<!-- customer address routes -->
@@ -152,10 +157,6 @@
</route>
<!-- end order management process -->
<route id="mail.test" path="/mail/test">
<default key="_controller">Thelia\Controller\Front\Mail::test</default>
</route>
<!-- contact management -->
<route id="contact.send" path="/contact" methods="post">
<default key="_controller">Thelia\Controller\Front\ContactController::sendAction</default>

View File

@@ -4,23 +4,21 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://thelia.net/schema/dic/config http://thelia.net/schema/dic/config/thelia-1.0.xsd">
<services>
<!-- URL maganement -->
<!-- The assets manager -->
<service id="assetic.asset.manager" class="Thelia\Core\Template\Assets\AsseticAssetManager" >
<argument>%kernel.debug%</argument>
</service>
<!-- Smarty parser plugins -->
<service id="smarty.plugin.assetic" class="Thelia\Core\Template\Smarty\Plugins\Assetic" >
<service id="smarty.plugin.assets" class="Thelia\Core\Template\Smarty\Plugins\Assets" >
<tag name="thelia.parser.register_plugin"/>
<argument>%kernel.environment%</argument>
<argument type="service" id="assetic.asset.manager" />
</service>
<service id="smarty.plugin.theliasyntax" class="Thelia\Core\Template\Smarty\Plugins\TheliaSyntax" >

View File

@@ -42,7 +42,7 @@ class AddressController extends AbstractCrudController
public function __construct()
{
parent::__construct(
'address',
'registration_date',
null,
null,
@@ -50,10 +50,7 @@ class AddressController extends AbstractCrudController
TheliaEvents::ADDRESS_CREATE,
TheliaEvents::ADDRESS_UPDATE,
TheliaEvents::ADDRESS_DELETE,
null,
null
TheliaEvents::ADDRESS_DELETE
);
}
@@ -79,7 +76,7 @@ class AddressController extends AbstractCrudController
\Thelia\Log\Tlog::getInstance()->error(sprintf("error during address setting as default with message %s", $e->getMessage()));
}
$this->redirectToRoute('admin.customer.update.view', array(), array('customer_id' => $address->getCustomerId()));
$this->redirectToEditionTemplate();
}
/**
@@ -99,13 +96,14 @@ class AddressController extends AbstractCrudController
}
/**
* Hydrate the update form for this object, before passing it to the update template
* Fills in the form data array
*
* @param \Thelia\Model\Address $object
* @param unknown $object
* @return multitype:NULL
*/
protected function hydrateObjectForm($object)
protected function createFormDataArray($object)
{
$data = array(
return array(
"label" => $object->getLabel(),
"title" => $object->getTitleId(),
"firstname" => $object->getFirstname(),
@@ -120,8 +118,16 @@ class AddressController extends AbstractCrudController
"phone" => $object->getPhone(),
"company" => $object->getCompany()
);
}
return new AddressUpdateForm($this->getRequest(), "form", $data);
/**
* Hydrate the update form for this object, before passing it to the update template
*
* @param \Thelia\Model\Address $object
*/
protected function hydrateObjectForm($object)
{
return new AddressUpdateForm($this->getRequest(), "form", $this->createFormDataArray($object));
}
/**
@@ -240,7 +246,8 @@ class AddressController extends AbstractCrudController
*/
protected function renderListTemplate($currentOrder)
{
// TODO: Implement renderListTemplate() method.
// We render here the customer edit template.
return $this->renderEditionTemplate();
}
/**
@@ -248,9 +255,10 @@ class AddressController extends AbstractCrudController
*/
protected function renderEditionTemplate()
{
return $this->render('ajax/address-update-modal', array(
"address_id" => $this->getRequest()->get('address_id'),
"customer_id" => $this->getExistingObject()->getCustomerId()
return $this->render('customer-edit', array(
"address_id" => $this->getRequest()->get('address_id'),
"page" => $this->getRequest()->get('page'),
"customer_id" => $this->getCustomerId()
));
}
@@ -259,8 +267,11 @@ class AddressController extends AbstractCrudController
*/
protected function redirectToEditionTemplate()
{
$address = $this->getExistingObject();
$this->redirectToRoute('admin.customer.update.view', array(), array('customer_id' => $address->getCustomerId()));
// We display here the custromer edition template
$this->redirectToRoute('admin.customer.update.view', array(
"page" => $this->getRequest()->get('page'),
"customer_id" => $this->getCustomerId()
));
}
/**
@@ -279,8 +290,7 @@ class AddressController extends AbstractCrudController
*/
protected function performAdditionalDeleteAction($deleteEvent)
{
$address = $deleteEvent->getAddress();
$this->redirectToRoute('admin.customer.update.view', array(), array('customer_id' => $address->getCustomerId()));
$this->redirectToEditionTemplate();
}
/**
@@ -298,4 +308,11 @@ class AddressController extends AbstractCrudController
{
$this->redirectToEditionTemplate();
}
protected function getCustomerId() {
if (null !== $address = $this->getExistingObject())
return $address->getCustomerId();
else
return $this->getRequest()->get('customer_id', 0);
}
}

View File

@@ -35,171 +35,99 @@ use Thelia\Form\Exception\FormValidationException;
use Thelia\Model\CustomerQuery;
use Thelia\Core\Translation\Translator;
use Thelia\Tools\Password;
use Thelia\Model\AddressQuery;
use Thelia\Model\Address;
/**
* Class CustomerController
* @package Thelia\Controller\Admin
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class CustomerController extends BaseAdminController
class CustomerController extends AbstractCrudController
{
public function indexAction()
public function __construct()
{
if (null !== $response = $this->checkAuth(AdminResources::CUSTOMER, array(), AccessManager::VIEW)) return $response;
return $this->render("customers", array("display_customer" => 20));
parent::__construct(
'customer',
'lastname',
'customer_order',
AdminResources::CUSTOMER,
TheliaEvents::CUSTOMER_CREATEACCOUNT,
TheliaEvents::CUSTOMER_UPDATEACCOUNT,
TheliaEvents::CUSTOMER_DELETEACCOUNT
);
}
public function viewAction($customer_id)
protected function getCreationForm()
{
if (null !== $response = $this->checkAuth(AdminResources::CUSTOMER, array(), AccessManager::VIEW)) return $response;
return $this->render("customer-edit", array(
"customer_id" => $customer_id
));
return new CustomerCreateForm($this->getRequest());
}
/**
* update customer action
*
* @param $customer_id
* @return mixed|\Thelia\Core\HttpFoundation\Response
*/
public function updateAction($customer_id)
protected function getUpdateForm()
{
if (null !== $response = $this->checkAuth(AdminResources::CUSTOMER, array(), AccessManager::UPDATE)) return $response;
$message = false;
$customerUpdateForm = new CustomerUpdateForm($this->getRequest());
try {
$customer = CustomerQuery::create()->findPk($customer_id);
if (null === $customer) {
throw new \InvalidArgumentException(sprintf("%d customer id does not exist", $customer_id));
}
$form = $this->validateForm($customerUpdateForm);
$event = $this->createEventInstance($form->getData());
$event->setCustomer($customer);
$this->dispatch(TheliaEvents::CUSTOMER_UPDATEACCOUNT, $event);
$customerUpdated = $event->getCustomer();
$this->adminLogAppend(AdminResources::CUSTOMER, AccessManager::UPDATE, sprintf("Customer with Ref %s (ID %d) modified", $customerUpdated->getRef() , $customerUpdated->getId()));
if ($this->getRequest()->get("save_mode") == "close") {
$this->redirectToRoute("admin.customers");
} else {
$this->redirectSuccess($customerUpdateForm);
}
} catch (FormValidationException $e) {
$message = sprintf("Please check your input: %s", $e->getMessage());
} catch (PropelException $e) {
$message = $e->getMessage();
} catch (\Exception $e) {
$message = sprintf("Sorry, an error occured: %s", $e->getMessage()." ".$e->getFile());
}
if ($message !== false) {
\Thelia\Log\Tlog::getInstance()->error(sprintf("Error during customer update process : %s.", $message));
$customerUpdateForm->setErrorMessage($message);
$this->getParserContext()
->addForm($customerUpdateForm)
->setGeneralError($message)
;
}
return $this->render("customer-edit", array(
"customer_id" => $customer_id
));
return new CustomerUpdateForm($this->getRequest());
}
public function createAction()
protected function getCreationEvent($formData)
{
if (null !== $response = $this->checkAuth(AdminResources::CUSTOMER, array(), AccessManager::CREATE)) return $response;
$message = null;
$customerCreateForm = new CustomerCreateForm($this->getRequest());
try {
$form = $this->validateForm($customerCreateForm);
$data = $form->getData();
$data["password"] = Password::generateRandom();
$event = $this->createEventInstance($form->getData());
$this->dispatch(TheliaEvents::CUSTOMER_CREATEACCOUNT, $event);
$successUrl = $customerCreateForm->getSuccessUrl();
$successUrl = str_replace('_ID_', $event->getCustomer()->getId(), $successUrl);
$this->redirect($successUrl);
}catch (FormValidationException $e) {
$message = sprintf("Please check your input: %s", $e->getMessage());
} catch (PropelException $e) {
$message = $e->getMessage();
} catch (\Exception $e) {
$message = sprintf("Sorry, an error occured: %s", $e->getMessage()." ".$e->getFile());
}
if ($message !== false) {
\Thelia\Log\Tlog::getInstance()->error(sprintf("Error during customer creation process : %s.", $message));
$customerCreateForm->setErrorMessage($message);
$this->getParserContext()
->addForm($customerCreateForm)
->setGeneralError($message)
;
}
return $this->render("customers", array("display_customer" => 20));
return $this->createEventInstance($formData);
}
public function deleteAction()
protected function getUpdateEvent($formData)
{
if (null !== $response = $this->checkAuth(AdminResources::CUSTOMER, array(), AccessManager::DELETE)) return $response;
$event = $this->createEventInstance($formData);
$message = null;
$event->setCustomer($this->getExistingObject());
try {
$customer_id = $this->getRequest()->get("customer_id");
$customer = CustomerQuery::create()->findPk($customer_id);
return $event;
}
if (null === $customer) {
throw new \InvalidArgumentException(Translator::getInstance("The customer you want to delete does not exist"));
}
protected function getDeleteEvent()
{
return new CustomerEvent($this->getExistingObject());
}
$event = new CustomerEvent($customer);
protected function eventContainsObject($event)
{
return $event->hasCustomer();
}
$this->dispatch(TheliaEvents::CUSTOMER_DELETEACCOUNT, $event);
} catch (\Exception $e) {
$message = $e->getMessage();
}
protected function hydrateObjectForm($object)
{
// Get default adress of the customer
$address = $object->getDefaultAddress();
$params = array(
"customer_page" => $this->getRequest()->get("customer_page", 1)
// Prepare the data that will hydrate the form
$data = array(
'id' => $object->getId(),
'firstname' => $object->getFirstname(),
'lastname' => $object->getLastname(),
'email' => $object->getEmail(),
'title' => $object->getTitleId(),
);
if ($message) {
$params["delete_error_message"] = $message;
if ($address !== null) {
$data['company'] = $address->getCompany();
$data['address1'] = $address->getAddress1();
$data['address2'] = $address->getAddress2();
$data['address3'] = $address->getAddress3();
$data['phone'] = $address->getPhone();
$data['cellphone'] = $address->getCellphone();
$data['zipcode'] = $address->getZipcode();
$data['city'] = $address->getCity();
$data['country'] = $address->getCountryId();
}
$this->redirectToRoute("admin.customers", $params);
// A loop is used in the template
return new CustomerUpdateForm($this->getRequest(), 'form', $data);
}
protected function getObjectFromEvent($event)
{
return $event->hasCustomer() ? $event->getCustomer() : null;
}
/**
@@ -209,26 +137,75 @@ class CustomerController extends BaseAdminController
private function createEventInstance($data)
{
$customerCreateEvent = new CustomerCreateOrUpdateEvent(
$data["title"],
$data["firstname"],
$data["lastname"],
$data["address1"],
$data["address2"],
$data["address3"],
$data["phone"],
$data["cellphone"],
$data["zipcode"],
$data["city"],
$data["country"],
isset($data["email"])?$data["email"]:null,
isset($data["password"]) ? $data["password"]:null,
$this->getRequest()->getSession()->getLang()->getId(),
isset($data["reseller"])?$data["reseller"]:null,
isset($data["sponsor"])?$data["sponsor"]:null,
isset($data["discount"])?$data["discount"]:null,
isset($data["company"])?$data["company"]:null
$data["title"],
$data["firstname"],
$data["lastname"],
$data["address1"],
$data["address2"],
$data["address3"],
$data["phone"],
$data["cellphone"],
$data["zipcode"],
$data["city"],
$data["country"],
isset($data["email"])?$data["email"]:null,
isset($data["password"]) && ! empty($data["password"]) ? $data["password"]:null,
$this->getRequest()->getSession()->getLang()->getId(),
isset($data["reseller"])?$data["reseller"]:null,
isset($data["sponsor"])?$data["sponsor"]:null,
isset($data["discount"])?$data["discount"]:null,
isset($data["company"])?$data["company"]:null
);
return $customerCreateEvent;
}
}
protected function getExistingObject()
{
return CustomerQuery::create()->findPk($this->getRequest()->get('customer_id', 0));
}
protected function getObjectLabel($object)
{
return $object->getRef() . "(".$object->getLastname()." ".$object->getFirstname().")";
}
protected function getObjectId($object)
{
return $object->getId();
}
protected function getEditionArguments()
{
return array(
'customer_id' => $this->getRequest()->get('customer_id', 0),
'page' => $this->getRequest()->get('page', 1)
);
}
protected function renderListTemplate($currentOrder)
{
return $this->render('customers', array(
'customer_order' => $currentOrder,
'display_customer' => 20,
'page' => $this->getRequest()->get('page', 1)
));
}
protected function redirectToListTemplate()
{
$this->redirectToRoute('admin.customers', array(
'page' => $this->getRequest()->get('page', 1))
);
}
protected function renderEditionTemplate()
{
return $this->render('customer-edit', $this->getEditionArguments());
}
protected function redirectToEditionTemplate()
{
$this->redirectToRoute("admin.customer.update.view", $this->getEditionArguments());
}
}

View File

@@ -202,48 +202,28 @@ class OrderController extends BaseAdminController
public function generateInvoicePdf($order_id)
{
return $this->generatePdf($order_id, ConfigQuery::read('pdf_invoice_file', 'invoice'));
if (null !== $response = $this->checkAuth(AdminResources::ORDER, array(), AccessManager::UPDATE)) return $response;
return $this->generateBackOfficeOrderPdf($order_id, ConfigQuery::read('pdf_invoice_file', 'invoice'));
}
public function generateDeliveryPdf($order_id)
{
return $this->generatePdf($order_id, ConfigQuery::read('pdf_delivery_file', 'delivery'));
}
protected function generatePdf($order_id, $fileName)
{
if (null !== $response = $this->checkAuth(AdminResources::ORDER, array(), AccessManager::UPDATE)) return $response;
$html = $this->renderRaw(
$fileName,
array(
return $this->generateBackOfficeOrderPdf($order_id, ConfigQuery::read('pdf_delivery_file', 'delivery'));
}
private function generateBackOfficeOrderPdf($order_id, $fileName)
{
if(null === $response = $this->generateOrderPdf($order_id, $fileName)){
$this->redirect(URL::getInstance()->absoluteUrl($this->getRoute("admin.order.update.view", array(
'order_id' => $order_id
),
TemplateHelper::getInstance()->getActivePdfTemplate()->getPath()
);
$order = OrderQuery::create()->findPk($order_id);
try {
$pdfEvent = new PdfEvent($html);
$this->dispatch(TheliaEvents::GENERATE_PDF, $pdfEvent);
if ($pdfEvent->hasPdf()) {
return Response::create($pdfEvent->getPdf(), 200,
array(
'Content-type' => "application/pdf",
'Content-Disposition' => sprintf('Attachment;filename=%s.pdf', $order->getRef()),
));
}
} catch (\Exception $e) {
\Thelia\Log\Tlog::getInstance()->error(sprintf('error during generating invoice pdf for order id : %d with message "%s"', $order_id, $e->getMessage()));
))));
}
$this->redirect(URL::getInstance()->absoluteUrl($this->getRoute("admin.order.update.view", array(
'order_id' => $order_id
))));
return $response;
}
}

View File

@@ -22,6 +22,8 @@
/*************************************************************************************/
namespace Thelia\Controller;
use Thelia\Core\Event\PdfEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\HttpFoundation\Response;
use Symfony\Component\DependencyInjection\ContainerAware;
@@ -31,7 +33,9 @@ use Symfony\Component\Routing\Exception\MissingMandatoryParametersException;
use Symfony\Component\Routing\Exception\RouteNotFoundException;
use Symfony\Component\Routing\Router;
use Thelia\Core\Security\SecurityContext;
use Thelia\Core\Template\TemplateHelper;
use Thelia\Core\Translation\Translator;
use Thelia\Model\OrderQuery;
use Thelia\Tools\URL;
use Thelia\Tools\Redirect;
use Thelia\Core\Template\ParserContext;
@@ -52,7 +56,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class BaseController extends ContainerAware
abstract class BaseController extends ContainerAware
{
/**
@@ -73,6 +77,21 @@ class BaseController extends ContainerAware
return new Response($json_data, $status, array('content-type' => 'application/json'));
}
/**
* @param $pdf
* @param $fileName
* @param $status
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function pdfResponse($pdf, $fileName, $status = 200)
{
return Response::create($pdf, $status,
array(
'Content-type' => "application/pdf",
'Content-Disposition' => sprintf('Attachment;filename=%s.pdf', $fileName),
));
}
/**
* Dispatch a Thelia event
*
@@ -207,6 +226,35 @@ class BaseController extends ContainerAware
}
}
protected function generateOrderPdf($order_id, $fileName)
{
$html = $this->renderRaw(
$fileName,
array(
'order_id' => $order_id
),
TemplateHelper::getInstance()->getActivePdfTemplate()->getPath()
);
$order = OrderQuery::create()->findPk($order_id);
try {
$pdfEvent = new PdfEvent($html);
$this->dispatch(TheliaEvents::GENERATE_PDF, $pdfEvent);
if ($pdfEvent->hasPdf()) {
return $this->pdfResponse($pdfEvent->getPdf(), $order->getRef());
}
} catch (\Exception $e) {
\Thelia\Log\Tlog::getInstance()->error(sprintf('error during generating invoice pdf for order id : %d with message "%s"', $order_id, $e->getMessage()));
}
}
/**
*
* redirect request to the specified url
@@ -311,20 +359,28 @@ class BaseController extends ContainerAware
}
/**
*
* return an instance of SmartyParser
*
* Caution : maybe there is still not default template defined.
*
* @return ParserInterface instance parser
* @return a ParserInterface instance parser
*/
protected function getParser()
{
return $this->container->get("thelia.parser");
}
abstract protected function getParser($template = null);
protected function render($inline)
{
return $this->getParser()->fetch(sprintf("string:%s", $inline));
}
/**
* Render the given template, and returns the result as an Http Response.
*
* @param $templateName the complete template name, with extension
* @param array $args the template arguments
* @param int $status http code status
* @return \Thelia\Core\HttpFoundation\Response
*/
abstract protected function render($templateName, $args = array(), $status = 200);
/**
* Render the given template, and returns the result as a string.
*
* @param $templateName the complete template name, with extension
* @param array $args the template arguments
* @param null $templateDir
*
* @return string
*/
abstract protected function renderRaw($templateName, $args = array(), $templateDir = null);
}

View File

@@ -24,9 +24,13 @@ namespace Thelia\Controller\Front;
use Symfony\Component\Routing\Router;
use Thelia\Controller\BaseController;
use Thelia\Core\HttpFoundation\Response;
use Thelia\Core\Security\Exception\AuthenticationException;
use Thelia\Core\Template\TemplateHelper;
use Thelia\Model\AddressQuery;
use Thelia\Model\ConfigQuery;
use Thelia\Model\ModuleQuery;
use Thelia\Tools\Redirect;
use Thelia\Tools\URL;
class BaseFrontController extends BaseController
@@ -88,12 +92,59 @@ class BaseFrontController extends BaseController
/**
* @return ParserInterface instance parser
*/
protected function getParser()
protected function getParser($template = null)
{
$parser = $this->container->get("thelia.parser");
$parser->setTemplate(ConfigQuery::getActiveTemplate());
// Define the template that should be used
$parser->setTemplate($template ?: TemplateHelper::getInstance()->getActiveFrontTemplate()->getPath());
return $parser;
}
/**
* Render the given template, and returns the result as an Http Response.
*
* @param $templateName the complete template name, with extension
* @param array $args the template arguments
* @param int $status http code status
* @return \Thelia\Core\HttpFoundation\Response
*/
protected function render($templateName, $args = array(), $status = 200)
{
return Response::create($this->renderRaw($templateName, $args), $status);
}
/**
* Render the given template, and returns the result as a string.
*
* @param $templateName the complete template name, with extension
* @param array $args the template arguments
* @param null $templateDir
*
* @return string
*/
protected function renderRaw($templateName, $args = array(), $templateDir = null)
{
// Add the template standard extension
$templateName .= '.html';
$session = $this->getSession();
// Prepare common template variables
$args = array_merge($args, array(
'locale' => $session->getLang()->getLocale(),
'lang_code' => $session->getLang()->getCode(),
'lang_id' => $session->getLang()->getId(),
'current_url' => $this->getRequest()->getUri()
));
// Render the template.
$data = $this->getParser($templateDir)->render($templateName, $args);
return $data;
}
}

View File

@@ -23,6 +23,9 @@
namespace Thelia\Controller\Front;
use Propel\Runtime\Exception\PropelException;
use Thelia\Core\Event\PdfEvent;
use Thelia\Core\HttpFoundation\Response;
use Thelia\Core\Template\TemplateHelper;
use Thelia\Exception\TheliaProcessException;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Core\Event\Order\OrderEvent;
@@ -34,6 +37,7 @@ use Thelia\Log\Tlog;
use Thelia\Model\AddressQuery;
use Thelia\Model\AreaDeliveryModuleQuery;
use Thelia\Model\Base\OrderQuery;
use Thelia\Model\ConfigQuery;
use Thelia\Model\ModuleQuery;
use Thelia\Model\Order;
use Thelia\Tools\URL;
@@ -67,7 +71,6 @@ class OrderController extends BaseFrontController
$deliveryModule = ModuleQuery::create()->findPk($deliveryModuleId);
/* check that the delivery address belongs to the current customer */
$deliveryAddress = AddressQuery::create()->findPk($deliveryAddressId);
if ($deliveryAddress->getCustomerId() !== $this->getSecurityContext()->getCustomerUser()->getId()) {
throw new \Exception("Delivery address does not belong to the current customer");
}
@@ -242,4 +245,20 @@ class OrderController extends BaseFrontController
return $order;
}
public function generateInvoicePdf($order_id)
{
/* check customer */
$this->checkAuth();
return $this->generateOrderPdf($order_id, ConfigQuery::read('pdf_invoice_file', 'invoice'));
}
public function generateDeliveryPdf($order_id)
{
/* check customer */
$this->checkAuth();
return $this->generateOrderPdf($order_id, ConfigQuery::read('pdf_delivery_file', 'delivery'));
}
}

View File

@@ -1,19 +0,0 @@
<?php
namespace Thelia\Controller;
use Symfony\Component\HttpFoundation\Request;
/**
*
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
interface NullControllerInterface
{
/**
* Nothing to do
*/
public function noAction(Request $request);
}

View File

@@ -31,7 +31,7 @@ use Thelia\Model\Customer;
* @package Thelia\Core\Event
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class CustomerCreateOrUpdateEvent extends ActionEvent
class CustomerCreateOrUpdateEvent extends CustomerEvent
{
//base parameters for creating new customer
protected $title;
@@ -53,11 +53,6 @@ class CustomerCreateOrUpdateEvent extends ActionEvent
protected $discount;
protected $company;
/**
* @var \Thelia\Model\Customer
*/
protected $customer;
/**
* @param int $title the title customer id
* @param string $firstname
@@ -242,21 +237,4 @@ class CustomerCreateOrUpdateEvent extends ActionEvent
{
return $this->sponsor;
}
/**
* @param Customer $customer
*/
public function setCustomer(Customer $customer)
{
$this->customer = $customer;
}
/**
* @return Customer
*/
public function getCustomer()
{
return $this->customer;
}
}

View File

@@ -28,13 +28,23 @@ use Thelia\Core\Event\ActionEvent;
class CustomerEvent extends ActionEvent
{
public $customer;
public $customer = null;
public function __construct(Customer $customer)
public function __construct(Customer $customer = null)
{
$this->customer = $customer;
}
/**
* @param Customer $customer
*/
public function setCustomer(Customer $customer)
{
$this->customer = $customer;
return $this;
}
/**
* @return \Thelia\Model\Customer
*/
@@ -43,4 +53,12 @@ class CustomerEvent extends ActionEvent
return $this->customer;
}
/**
* @return bool
*/
public function hasCustomer()
{
return $this->customer != null;
}
}

View File

@@ -26,17 +26,7 @@ namespace Thelia\Core\Event\Customer;
use Thelia\Core\Event\ActionEvent;
use Thelia\Model\Customer;
class CustomerLoginEvent extends ActionEvent
class CustomerLoginEvent extends CustomerEvent
{
protected $customer;
public function __construct(Customer $customer)
{
$this->customer = $customer;
}
public function getCustomer()
{
return $this->customer;
}
// Nothing specific :)
}

View File

@@ -21,28 +21,33 @@
/* */
/*************************************************************************************/
namespace Thelia\Controller\Front;
namespace Thelia\Core\Template\Assets;
/**
* Class Mail
* @package Thelia\Controller\Front
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class Mail extends BaseFrontController
{
interface AssetManagerInterface {
/**
* This is a demo how to send a mail using swiftmailer + smarty
* Prepare an asset directory.
*
* @param string $source_assets_directory the full path to the source asstes directory
* @param string $web_assets_directory_base the base directory of the web based asset directory
* @throws \RuntimeException if something goes wrong.
*/
public function test()
{
$message = \Swift_Message::newInstance('Wonderful Subject')
->setFrom(array('john@doe.com' => 'John Doe'))
->setTo(array('mraynaud@openstudio.fr' => 'name'))
->setBody($this->render('Here is the message itself'))
;
public function prepareAssets($source_assets_directory, $web_assets_directory_base);
$this->getMailer()->send($message);
exit;
}
}
/**
* Generates assets from $asset_path in $output_path, using $filters.
*
* @param string $asset_path the full path to the asset file (or file collection, e.g. *.less)
*
* @param string $web_assets_directory_base the full disk path to the base assets output directory in the web space
* @param string $output_url the URL to the base assets output directory in the web space
*
* @param string $asset_type the asset type: css, js, ... The generated files will have this extension. Pass an empty string to use the asset source extension.
* @param array $filters a list of filters, as defined below (see switch($filter_name) ...)
*
* @param boolean $debug the debug mode, true or false
*
* @throws \InvalidArgumentException if an invalid filter name is found
* @return string The URL to the generated asset file.
*/
public function processAsset($asset_path, $web_assets_directory_base, $output_url, $asset_type, $filters, $debug);
}

View File

@@ -0,0 +1,350 @@
<?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\Assets;
use Assetic\AssetManager;
use Assetic\FilterManager;
use Assetic\Filter;
use Assetic\Factory\AssetFactory;
use Assetic\AssetWriter;
use Thelia\Model\ConfigQuery;
use Thelia\Log\Tlog;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Filesystem\Exception\IOException;
/**
* This class is a simple helper for generating assets using Assetic.
*
* @author Franck Allimant <franck@cqfdev.fr>
*/
class AsseticAssetManager implements AssetManagerInterface
{
protected $debugMode;
protected $source_file_extensions = array('less', 'js', 'coffee', 'html', 'tpl', 'htm', 'xml');
public function __construct($debugMode)
{
$this->debugMode = $debugMode;
}
/**
* Create a stamp form the modification time of the content of the given directory and all of its subdirectories
*
* @param string $directory ther directory name
* @return string the stamp of this directory
*/
protected function getStamp($directory)
{
$stamp = '';
$iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($directory, \RecursiveDirectoryIterator::SKIP_DOTS),
\RecursiveIteratorIterator::LEAVES_ONLY);
foreach ($iterator as $file) {
$stamp .= $file->getMTime();
}
return md5($stamp);
}
/**
* Check if a file is a source asset file
*
* @param \DirectoryIterator $fileInfo
*/
protected function isSourceFile(\SplFileInfo $fileInfo) {
return in_array($fileInfo->getExtension(), $this->source_file_extensions);
}
/**
* Recursively copy assets from the source directory to the destination
* directory in the web space, ommiting source files.
*
* @param string $from_directory the source
* @param string $to_directory the destination
* @throws \RuntimeException if a problem occurs.
*/
protected function copyAssets(Filesystem $fs, $from_directory, $to_directory)
{
Tlog::getInstance()->addDebug("Copying assets from ", $from_directory, " to ", $to_directory);
$iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($from_directory, \RecursiveDirectoryIterator::SKIP_DOTS),
\RecursiveIteratorIterator::SELF_FIRST);
foreach ($iterator as $item) {
if ($item->isDir()) {
$dest_dir = $to_directory . DS . $iterator->getSubPathName();
if (! is_dir($dest_dir)) {
if ($fs->exists($dest_dir)) {
$fs->remove($dest_dir);
}
$fs->mkdir($dest_dir, 0777);
}
}
// We don't copy source files
else if (! $this->isSourceFile($item)) {
$dest_file = $to_directory . DS . $iterator->getSubPathName();
if ($fs->exists($dest_file)) {
$fs->remove($dest_file);
}
$fs->copy($item, $dest_file);
}
}
}
/**
* Compite the assets path relative to the base template directory
*
* @param string $source_assets_directory the source directory
* @param string $web_assets_directory_base base directory of the web assets
* @return the full path of the destination directory
*/
protected function getRelativeDirectoryPath($source_assets_directory, $web_assets_directory_base)
{
$source_assets_directory = realpath($source_assets_directory);
// Remove base path from asset source path to get a path relative to the template base
// and use it to create the destination path.
return str_replace(
realpath(THELIA_ROOT),
'',
$source_assets_directory
);
}
/**
* Compute the destination directory path, from the source directory and the
* base directory of the web assets
*
* @param string $source_assets_directory the source directory
* @param string $web_assets_directory_base base directory of the web assets
* @return the full path of the destination directory
*/
protected function getDestinationDirectory($source_assets_directory, $web_assets_directory_base)
{
// Compute the absolute path of the output directory
return $web_assets_directory_base . $this->getRelativeDirectoryPath($source_assets_directory, $web_assets_directory_base);
}
/**
* Prepare an asset directory by checking that no changes occured in
* the source directory. If any change is detected, the whole asset directory
* is copied in the web space.
*
* @param string $source_assets_directory the full path to the source asstes directory
* @param string $web_assets_directory_base the base directory of the web based asset directory
* @throws \RuntimeException if something goes wrong.
*/
public function prepareAssets($source_assets_directory, $web_assets_directory_base) {
// Compute the absolute path of the output directory
$to_directory = $this->getDestinationDirectory($source_assets_directory, $web_assets_directory_base);
// Get a path to the stamp file
$stamp_file_path = $to_directory . DS . '.source-stamp';
// Get the last stamp of source assets directory
$prev_stamp = @file_get_contents($stamp_file_path);
// Get the current stamp of the source directory
$curr_stamp = $this->getStamp($source_assets_directory);
if ($prev_stamp !== $curr_stamp) {
$fs = new Filesystem();
// FIXME: locking or not locking ?
/*
$lock_file = "$web_assets_directory_base/assets-".md5($source_assets_directory)."-generation-lock.txt";
if (! $fp = fopen($lock_file, "w")) {
throw new IOException(sprintf('Failed to open lock file %s', $lock_file));
}
if (flock($fp, LOCK_EX|LOCK_NB)) { // do an exclusive lock
*/
$tmp_dir = "$to_directory.tmp";
$fs->remove($tmp_dir);
// Copy the whole source dir in a temp directory
$this->copyAssets($fs, $source_assets_directory, $tmp_dir);
// Remove existing directory
if ($fs->exists($to_directory)) $fs->remove($to_directory);
// Put in place the new directory
$fs->rename($tmp_dir, $to_directory);
/*
// Release the lock
flock($fp, LOCK_UN);
// Remove the lock file
@fclose($fp);
$fs->remove($lock_file);
*/
if (false === @file_put_contents($stamp_file_path, $curr_stamp)) {
throw new \RuntimeException(
"Failed to create asset stamp file $stamp_file_path. Please check that your web server has the proper access rights to do that.");
}
/* }
else {
@fclose($fp);
}
*/
}
}
/**
* Decode the filters names, and initialize the Assetic FilterManager
*
* @param FilterManager $filterManager the Assetic filter manager
* @param string $filters a comma separated list of filter names
* @throws \InvalidArgumentException if a wrong filter is passed
* @return an array of filter names
*/
protected function decodeAsseticFilters(FilterManager $filterManager, $filters) {
if (!empty($filters)) {
$filter_list = explode(',', $filters);
foreach ($filter_list as $filter_name) {
$filter_name = trim($filter_name);
switch ($filter_name) {
case 'less':
$filterManager->set('less', new Filter\LessphpFilter());
break;
case 'sass':
$filterManager->set('sass', new Filter\Sass\SassFilter());
break;
case 'cssembed':
$filterManager->set('cssembed', new Filter\PhpCssEmbedFilter());
break;
case 'cssrewrite':
$filterManager->set('cssrewrite', new Filter\CssRewriteFilter());
break;
case 'cssimport':
$filterManager->set('cssimport', new Filter\CssImportFilter());
break;
case 'compass':
$filterManager->set('compass', new Filter\CompassFilter());
break;
default:
throw new \InvalidArgumentException("Unsupported Assetic filter: '$filter_name'");
break;
}
}
}
else {
$filter_list = array();
}
return $filter_list;
}
/**
* Generates assets from $asset_path in $output_path, using $filters.
*
* @param string $asset_path the full path to the asset file (or file collection, e.g. *.less)
*
* @param string $web_assets_directory_base the full disk path to the base assets output directory in the web space
* @param string $output_url the URL to the base assets output directory in the web space
*
* @param string $asset_type the asset type: css, js, ... The generated files will have this extension. Pass an empty string to use the asset source extension.
* @param array $filters a list of filters, as defined below (see switch($filter_name) ...)
*
* @param boolean $debug true / false
* @throws \InvalidArgumentException if an invalid filter name is found
* @return string The URL to the generated asset file.
*/
public function processAsset($asset_path, $web_assets_directory_base, $output_url, $asset_type, $filters, $debug)
{
$asset_name = basename($asset_path);
$input_directory = realpath(dirname($asset_path));
$am = new AssetManager();
$fm = new FilterManager();
// Get the filter list
$filter_list = $this->decodeAsseticFilters($fm, $filters);
// Factory setup
$factory = new AssetFactory($input_directory);
$factory->setAssetManager($am);
$factory->setFilterManager($fm);
$factory->setDefaultOutput('*' . (!empty($asset_type) ? '.' : '') . $asset_type);
$factory->setDebug($debug);
$asset = $factory->createAsset($asset_name, $filter_list);
$input_directory = realpath(dirname($asset_path));
$output_directory = $this->getDestinationDirectory($input_directory, $web_assets_directory_base);
// Get the URL part from the relative path
$output_relative_path = $this->getRelativeDirectoryPath($input_directory, $web_assets_directory_base);
$output_relative_web_path = rtrim(str_replace('\\', '/', $output_relative_path), '/') . '/';
$asset_target_filename = $asset->getTargetPath();
// This is the final name of the generated asset
$asset_destination_path = $output_directory . DS . $asset_target_filename;
Tlog::getInstance()->addDebug("Asset destination name: ", $asset_destination_path);
// We generate an asset only if it does not exists, or if the asset processing is forced in development mode
if (! file_exists($asset_destination_path) || ($this->debugMode && ConfigQuery::read('process_assets', true)) ) {
$writer = new AssetWriter($output_directory);
Tlog::getInstance()->addDebug("Writing asset to $output_directory");
$writer->writeAsset($asset);
}
return rtrim($output_url, '/') . '/' . $output_relative_web_path . $asset_target_filename;
}
}

View File

@@ -1,160 +0,0 @@
<?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\Assets;
use Assetic\AssetManager;
use Assetic\FilterManager;
use Assetic\Filter;
use Assetic\Factory\AssetFactory;
use Assetic\Factory\Worker\CacheBustingWorker;
use Assetic\AssetWriter;
use Thelia\Model\ConfigQuery;
/**
* This class is a simple helper for generating assets using Assetic.
*
* @author Franck Allimant <franck@cqfdev.fr>
*/
class AsseticHelper
{
/**
* Generates assets from $asset_path in $output_path, using $filters.
*
* @param string $asset_path the full path to the asset file (or file collection)
* @param string $output_path the full disk path to the output directory (shoud be visible to web server)
* @param string $output_url the URL to the generated asset directory
* @param string $asset_type the asset type: css, js, ... The generated files will have this extension. Pass an empty string to use the asset source extension.
* @param array $filters a list of filters, as defined below (see switch($filter_name) ...)
* @param boolean $debug true / false
* @param boolean $dev_mode true / false. If true, assets are not cached and always compiled.
* @throws \InvalidArgumentException if an invalid filter name is found
* @return string The URL to the generated asset file.
*/
public function asseticize($asset_path, $output_path, $output_url, $asset_type, $filters, $debug, $dev_mode = false)
{
$asset_name = basename($asset_path);
$asset_dir = dirname($asset_path);
$am = new AssetManager();
$fm = new FilterManager();
if (! empty($filters)) {
$filter_list = explode(',', $filters);
foreach ($filter_list as $filter_name) {
$filter_name = trim($filter_name);
switch ($filter_name) {
case 'less' :
$fm->set('less', new Filter\LessphpFilter());
break;
case 'sass' :
$fm->set('sass', new Filter\Sass\SassFilter());
break;
case 'cssembed' :
$fm->set('cssembed', new Filter\PhpCssEmbedFilter());
break;
case 'cssrewrite':
$fm->set('cssrewrite', new Filter\CssRewriteFilter());
break;
case 'cssimport':
$fm->set('cssimport', new Filter\CssImportFilter());
break;
case 'compass':
$fm->set('compass', new Filter\CompassFilter());
break;
default :
throw new \InvalidArgumentException("Unsupported Assetic filter: '$filter_name'");
break;
}
}
} else {
$filter_list = array();
}
// Factory setup
$factory = new AssetFactory($asset_dir);
$factory->setAssetManager($am);
$factory->setFilterManager($fm);
$factory->setDefaultOutput('*'.(! empty($asset_type) ? '.' : '').$asset_type);
$factory->setDebug($debug);
$factory->addWorker(new CacheBustingWorker('-'));
// We do not pass the filter list here, juste to get the asset file name
$asset = $factory->createAsset($asset_name);
$asset_target_path = $asset->getTargetPath();
$target_file = sprintf("%s/%s", $output_path, $asset_target_path);
// As it seems that assetic cannot handle a real file cache, let's do the job ourselves.
// It works only if the CacheBustingWorker is used, as a new file name is generated for each version.
//
// the previous version of the file is deleted, by getting the first part of the ouput file name
// (the one before '-'), and delete aby file beginning with the same string. Example:
// old name: 3bc974a-dfacc1f.css
// new name: 3bc974a-ad3ef47.css
//
// before generating 3bc974a-ad3ef47.css, delete 3bc974a-* files.
//
if ($dev_mode == true || ! file_exists($target_file)) {
if (ConfigQuery::read('process_assets', true)) {
// Delete previous version of the file
list($commonPart, $dummy) = explode('-', $asset_target_path);
foreach (glob("$output_path/$commonPart-*") as $filename) {
@unlink($filename);
}
// Apply filters now
foreach ($filter_list as $filter) {
if ('?' != $filter[0]) {
$asset->ensureFilter($fm->get($filter));
} elseif (!$debug) {
$asset->ensureFilter($fm->get(substr($filter, 1)));
}
}
$writer = new AssetWriter($output_path);
$writer->writeAsset($asset);
}
}
return rtrim($output_url, '/').'/'.$asset_target_path;
}
}

View File

@@ -36,6 +36,9 @@ use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Model\CustomerQuery;
use Thelia\Type\TypeCollection;
use Thelia\Type;
use Thelia\Model\OrderQuery;
use Thelia\Model\Map\OrderAddressTableMap;
use Thelia\Model\Map\OrderTableMap;
/**
*
@@ -65,7 +68,22 @@ class Customer extends BaseLoop implements SearchLoopInterface, PropelSearchLoop
)
),
Argument::createBooleanTypeArgument('reseller'),
Argument::createIntTypeArgument('sponsor')
Argument::createIntTypeArgument('sponsor'),
new Argument(
'order',
new TypeCollection(
new Type\EnumListType(array(
'id', 'id_reverse',
'reference', 'reference_reverse',
'firstname', 'firstname_reverse',
'lastname', 'lastname_reverse',
'last_order', 'last_order_reverse',
'order_amount', 'order_amount_reverse',
'registration_date', 'registration_date_reverse'
))
),
'lastname'
)
);
}
@@ -151,6 +169,49 @@ class Customer extends BaseLoop implements SearchLoopInterface, PropelSearchLoop
$search->filterBySponsor($sponsor, Criteria::EQUAL);
}
$orders = $this->getOrder();
foreach ($orders as $order) {
switch ($order) {
case 'id':
$search->orderById(Criteria::ASC);
break;
case 'id_reverse':
$search->orderById(Criteria::DESC);
break;
case 'reference':
$search->orderByRef(Criteria::ASC);
break;
case 'reference_reverse':
$search->orderByRef(Criteria::DESC);
break;
case 'lastname':
$search->orderByLastname(Criteria::ASC);
break;
case 'lastname_reverse':
$search->orderByLastname(Criteria::DESC);
break;
case 'firstname':
$search->orderByFirstname(Criteria::ASC);
break;
case 'firstname_reverse':
$search->orderByFirstname(Criteria::DESC);
break;
case 'registration_date':
$search->orderByCreatedAt(Criteria::ASC);
break;
case 'registration_date_reverse':
$search->orderByCreatedAt(Criteria::DESC);
break;
}
}
return $search;
}
@@ -158,16 +219,24 @@ class Customer extends BaseLoop implements SearchLoopInterface, PropelSearchLoop
public function parseResults(LoopResult $loopResult)
{
foreach ($loopResult->getResultDataCollection() as $customer) {
$loopResultRow = new LoopResultRow($customer);
$loopResultRow->set("ID", $customer->getId());
$loopResultRow->set("REF", $customer->getRef());
$loopResultRow->set("TITLE", $customer->getTitleId());
$loopResultRow->set("FIRSTNAME", $customer->getFirstname());
$loopResultRow->set("LASTNAME", $customer->getLastname());
$loopResultRow->set("EMAIL", $customer->getEmail());
$loopResultRow->set("RESELLER", $customer->getReseller());
$loopResultRow->set("SPONSOR", $customer->getSponsor());
$loopResultRow->set("DISCOUNT", $customer->getDiscount());
$loopResultRow
->set("ID" , $customer->getId())
->set("REF" , $customer->getRef())
->set("TITLE" , $customer->getTitleId())
->set("FIRSTNAME" , $customer->getFirstname())
->set("LASTNAME" , $customer->getLastname())
->set("EMAIL" , $customer->getEmail())
->set("RESELLER" , $customer->getReseller())
->set("SPONSOR" , $customer->getSponsor())
->set("DISCOUNT" , $customer->getDiscount())
->set("LAST_ORDER_DATE" , $lastOrder != null ? $lastOrder->getCreatedAt() : '')
->set("LAST_ORDER_AMOUNT" , $lastOrder != null ? $lastOrder->getCreatedAt() : '')
->set("LAST_ORDER_CURRENCY" , $lastOrder != null ? $lastOrder->getCreatedAt() : '')
;
$loopResult->addRow($loopResultRow);
}

View File

@@ -33,6 +33,8 @@ use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Model\LangQuery;
use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
use Thelia\Type\TypeCollection;
use Thelia\Type;
/**
* Language loop, to get a list of available languages
@@ -56,7 +58,14 @@ class Lang extends BaseLoop implements PropelSearchLoopInterface
return new ArgumentCollection(
Argument::createIntTypeArgument('id', null),
Argument::createIntListTypeArgument('exclude'),
Argument::createBooleanTypeArgument('default_only', false)
Argument::createBooleanTypeArgument('default_only', false),
new Argument(
'order',
new TypeCollection(
new Type\EnumListType(array('id', 'id_reverse', 'alpha', 'alpha_reverse', 'position', 'position_reverse'))
),
'position'
)
);
}
@@ -79,6 +88,30 @@ class Lang extends BaseLoop implements PropelSearchLoopInterface
}
$search->orderByPosition(Criteria::ASC);
$orders = $this->getOrder();
foreach ($orders as $order) {
switch ($order) {
case "id":
$search->orderById(Criteria::ASC);
break;
case "id_reverse":
$search->orderById(Criteria::DESC);
break;
case "alpha":
$search->orderByTitle(Criteria::ASC);
break;
case "alpha_reverse":
$search->orderByTitle(Criteria::DESC);
break;
case "position":
$search->orderByPosition(Criteria::ASC);
break;
case "position_reverse":
$search->orderByPosition(Criteria::DESC);
break;
}
}
return $search;

View File

@@ -25,32 +25,44 @@ namespace Thelia\Core\Template\Smarty\Assets;
use Thelia\Core\Template\Assets\AsseticHelper;
use Thelia\Tools\URL;
use Thelia\Core\Template\Assets\AssetManagerInterface;
class SmartyAssetsManager
{
const ASSET_TYPE_AUTO = '';
private $assetic_manager;
private $assetsManager;
private $web_root;
private $path_relative_to_web_root;
private $developmentMode;
/**
* Creates a new SmartyAssetsManager instance
*
* @param string $web_root the disk path to the web root
* @param string $path_relative_to_web_root the path (relative to web root) where the assets will be generated
* @param boolean $developmentMode true / false. If true, assets are not cached, and always generated.
* @param AssetManagerInterface $assetsManager an asset manager instance
* @param string $web_root the disk path to the web root (with final /)
* @param string $path_relative_to_web_root the path (relative to web root) where the assets will be generated
*/
public function __construct($web_root, $path_relative_to_web_root, $developmentMode)
public function __construct(AssetManagerInterface $assetsManager, $web_root, $path_relative_to_web_root)
{
$this->web_root = $web_root;
$this->path_relative_to_web_root = $path_relative_to_web_root;
$this->developmentMode = $developmentMode;
$this->assetsManager = $assetsManager;
}
$this->assetic_manager = new AsseticHelper();
public function prepareAssets($assets_directory, \Smarty_Internal_Template $template) {
$tpl_dir = dirname($template->source->filepath);
$asset_dir_absolute_path = realpath($tpl_dir . DS . $assets_directory);
if ($asset_dir_absolute_path === false) throw new \Exception("Failed to get real path of '".$tpl_dir . DS . $assets_directory."'");
$this->assetsManager->prepareAssets(
$asset_dir_absolute_path,
$this->web_root . $this->path_relative_to_web_root
);
}
public function computeAssetUrl($assetType, $params, \Smarty_Internal_Template $template)
@@ -66,19 +78,18 @@ class SmartyAssetsManager
$tpl_dir = dirname($tpl_path);
// Create absolute dir path
$asset_dir = realpath($tpl_dir.'/'.dirname($file));
$asset_dir = realpath($tpl_dir) . DS . dirname($file);
$asset_file = basename($file);
if ($asset_dir === false) throw new \Exception("Failed to get real path of '".$tpl_dir.'/'.dirname($file)."'");
$url = $this->assetic_manager->asseticize(
$asset_dir.'/'.$asset_file,
$this->web_root."/".$this->path_relative_to_web_root,
$url = $this->assetsManager->processAsset(
$asset_dir . DS . $asset_file,
$this->web_root . $this->path_relative_to_web_root,
URL::getInstance()->absoluteUrl($this->path_relative_to_web_root, null, URL::PATH_TO_FILE /* path only */),
$assetType,
$filters,
$debug,
$this->developmentMode
$debug
);
return $url;

View File

@@ -27,18 +27,29 @@ use Thelia\Core\Template\Smarty\SmartyPluginDescriptor;
use Thelia\Core\Template\Smarty\AbstractSmartyPlugin;
use Thelia\Core\Template\Smarty\Assets\SmartyAssetsManager;
use Thelia\Model\ConfigQuery;
use Thelia\Core\Template\Assets\AssetManagerInterface;
class Assetic extends AbstractSmartyPlugin
class Assets extends AbstractSmartyPlugin
{
public $assetManager;
public function __construct($developmentMode)
public function __construct(AssetManagerInterface $assetsManager)
{
$web_root = THELIA_WEB_DIR;
$asset_dir_from_web_root = ConfigQuery::read('asset_dir_from_web_root', 'assets');
$asset_dir_from_web_root = ConfigQuery::read('asset_dir_from_web_root', 'assets/');
$this->assetManager = new SmartyAssetsManager($assetsManager, THELIA_WEB_DIR, $asset_dir_from_web_root);
}
$this->assetManager = new SmartyAssetsManager($web_root, $asset_dir_from_web_root, $developmentMode == 'dev');
public function declareAssets($params, \Smarty_Internal_Template $template)
{
if (false !== $asset_dir = $this->getParam($params, 'directory', false)) {
$this->assetManager->prepareAssets($asset_dir, $template);
return '';
}
throw new \InvalidArgumentException('declare_assets: parameter "directory" is required');
}
public function blockJavascripts($params, $content, \Smarty_Internal_Template $template, &$repeat)
@@ -79,10 +90,11 @@ class Assetic extends AbstractSmartyPlugin
public function getPluginDescriptors()
{
return array(
new SmartyPluginDescriptor('block' , 'stylesheets', $this, 'blockStylesheets'),
new SmartyPluginDescriptor('block' , 'javascripts', $this, 'blockJavascripts'),
new SmartyPluginDescriptor('block' , 'images' , $this, 'blockImages'),
new SmartyPluginDescriptor('function', 'image' , $this, 'functionImage')
new SmartyPluginDescriptor('block' , 'stylesheets' , $this, 'blockStylesheets'),
new SmartyPluginDescriptor('block' , 'javascripts' , $this, 'blockJavascripts'),
new SmartyPluginDescriptor('block' , 'images' , $this, 'blockImages'),
new SmartyPluginDescriptor('function', 'image' , $this, 'functionImage'),
new SmartyPluginDescriptor('function', 'declare_assets' , $this, 'declareAssets')
);
}
}

View File

@@ -82,6 +82,21 @@ class CustomerUpdateForm extends BaseForm
"for" => "lastname"
)
))
->add("email", "email", array(
"constraints" => array(
new Constraints\NotBlank()
),
"label" => Translator::getInstance()->trans("Email address"),
"label_attr" => array(
"for" => "email"
)
))
->add("password", "text", array(
"label" => Translator::getInstance()->trans("Password"),
"label_attr" => array(
"for" => "email"
)
))
->add("address1", "text", array(
"constraints" => array(
new Constraints\NotBlank()
@@ -89,7 +104,7 @@ class CustomerUpdateForm extends BaseForm
"label_attr" => array(
"for" => "address"
),
"label" => Translator::getInstance()->trans("Street Address")
"label" => Translator::getInstance()->trans("Street Address ")
))
->add("address2", "text", array(
"label" => Translator::getInstance()->trans("Address Line 2"),