Merge Master

This commit is contained in:
touffies
2013-10-07 11:50:20 +02:00
69 changed files with 1560 additions and 11105 deletions

1
.gitignore vendored
View File

@@ -14,7 +14,6 @@ coverage
.buildpath
.project
.settings/
local/cache/*
local/media/documents/*
local/media/images/*
web/assets/*

View File

@@ -8,6 +8,7 @@ env:
- DB_USER=root
before_script:
- phpenv config-add travis.php.ini
- composer self-update
- composer install --prefer-dist --dev
- sh -c "mysql -u$DB_USER -e 'SET FOREIGN_KEY_CHECKS = 0; DROP DATABASE IF EXISTS thelia;SET FOREIGN_KEY_CHECKS = 1;'; fi"

View File

@@ -16,6 +16,16 @@ Requirements
------------
* php 5.4
* Required extensions :
* PDO_Mysql
* mcrypt
* intl
* gd
* curl
* safe_mode off
* memory_limit at least 150M, preferably 256.
* post_max_size 20M
* upload_max_filesize 2M
* apache 2
* mysql 5

View File

@@ -38,7 +38,8 @@
"imagine/imagine": "dev-master",
"symfony/icu": "1.0",
"swiftmailer/swiftmailer": "5.0.*",
"symfony/serializer": "2.3.*"
"symfony/serializer": "2.3.*",
"ensepar/html2pdf": "1.0.1"
},
"require-dev" : {
"phpunit/phpunit": "3.7.*",

140
composer.lock generated
View File

@@ -3,8 +3,112 @@
"This file locks the dependencies of your project to a known state",
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
],
"hash": "097481390dc87b3482d895b3b6a65479",
"hash": "852879ecc2e39e5cf283a3b1c5051a8e",
"packages": [
{
"name": "ensepar/html2pdf",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/OwlyCode/html2pdf.git",
"reference": "b53a27430cc35b29bbe2faaa55ed4a7d5c156cd3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/OwlyCode/html2pdf/zipball/b53a27430cc35b29bbe2faaa55ed4a7d5c156cd3",
"reference": "b53a27430cc35b29bbe2faaa55ed4a7d5c156cd3",
"shasum": ""
},
"require": {
"ensepar/tcpdf": "5.0.003",
"php": ">=5.2"
},
"type": "library",
"autoload": {
"psr-0": {
"HTML2PDF": "."
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL"
],
"authors": [
{
"name": "Spipu",
"homepage": "http://sourceforge.net/users/spipu",
"role": "Developer"
},
{
"name": "OwlyCode",
"homepage": "http://www.github.com/OwlyCode",
"role": "Developer"
}
],
"description": "Unofficial fork of 'html2pdf' with Composer support. (Fixed composer dependency problem)",
"homepage": "https://github.com/jwronsky/html2pdf",
"keywords": [
"html",
"html2pdf",
"pdf"
],
"time": "2013-09-13 12:23:43"
},
{
"name": "ensepar/tcpdf",
"version": "5.0.003",
"source": {
"type": "git",
"url": "https://github.com/OwlyCode/tcpdf.git",
"reference": "ae578409e9454fdf6c794cce6f063b0c95bfa518"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/OwlyCode/tcpdf/zipball/ae578409e9454fdf6c794cce6f063b0c95bfa518",
"reference": "ae578409e9454fdf6c794cce6f063b0c95bfa518",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"autoload": {
"classmap": [
"fonts",
"config/lang",
"config",
"2dbarcodes.php",
"barcodes.php",
"htmlcolors.php",
"qrcode.php",
"tcpdf.php",
"unicode_data.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPLv3"
],
"authors": [
{
"name": "Nicola Asuni",
"email": "info@tecnick.com",
"homepage": "http://nicolaasuni.tecnick.com"
},
{
"name": "Tristan Maindron",
"email": "tmaindron@gmail.com",
"homepage": "http://www.github.com/OwlyCode"
}
],
"description": "TCPDF is a PHP class for generating PDF documents.",
"homepage": "http://www.tcpdf.org/",
"keywords": [
"TCPDF",
"pdf"
],
"time": "2013-09-12 17:00:40"
},
{
"name": "imagine/imagine",
"version": "dev-master",
@@ -1763,6 +1867,40 @@
],
"time": "2013-09-11 13:01:19"
},
{
"name": "phenx/php-font-lib",
"version": "0.2.1",
"source": {
"type": "git",
"url": "https://github.com/PhenX/php-font-lib.git",
"reference": "42a1ca6d19f14076911a118705b771c3a5a8b179"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PhenX/php-font-lib/zipball/42a1ca6d19f14076911a118705b771c3a5a8b179",
"reference": "42a1ca6d19f14076911a118705b771c3a5a8b179",
"shasum": ""
},
"type": "library",
"autoload": {
"classmap": [
"classes/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL"
],
"authors": [
{
"name": "Fabien Ménager",
"email": "fabien.menager@gmail.com"
}
],
"description": "A library to read, parse, export and make subsets of different types of font files.",
"homepage": "https://github.com/PhenX/php-font-lib",
"time": "2013-02-22 23:30:49"
},
{
"name": "phpunit/php-code-coverage",
"version": "1.2.12",

View File

@@ -60,6 +60,13 @@ class Address extends BaseAction implements EventSubscriberInterface
$address->delete();
}
public function useDefault(AddressEvent $event)
{
$address = $event->getAddress();
$address->makeItDefault();
}
protected function createOrUpdate(AddressModel $addressModel, AddressCreateOrUpdateEvent $event)
{
$addressModel->setDispatcher($this->getDispatcher());
@@ -125,7 +132,8 @@ class Address extends BaseAction implements EventSubscriberInterface
return array(
TheliaEvents::ADDRESS_CREATE => array("create", 128),
TheliaEvents::ADDRESS_UPDATE => array("update", 128),
TheliaEvents::ADDRESS_DELETE => array("delete", 128)
TheliaEvents::ADDRESS_DELETE => array("delete", 128),
TheliaEvents::ADDRESS_DEFAULT => array('useDefault', 128),
);
}
}

View File

@@ -25,6 +25,7 @@ namespace Thelia\Action;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Thelia\Core\Event\ActionEvent;
use Thelia\Core\Event\Customer\CustomerAddressEvent;
use Thelia\Core\Event\Customer\CustomerCreateOrUpdateEvent;
use Thelia\Core\Event\Customer\CustomerEvent;
use Thelia\Core\Event\TheliaEvents;
@@ -148,11 +149,11 @@ class Customer extends BaseAction implements EventSubscriberInterface
public static function getSubscribedEvents()
{
return array(
TheliaEvents::CUSTOMER_CREATEACCOUNT => array("create", 128),
TheliaEvents::CUSTOMER_UPDATEACCOUNT => array("modify", 128),
TheliaEvents::CUSTOMER_LOGOUT => array("logout", 128),
TheliaEvents::CUSTOMER_LOGIN => array("login" , 128),
TheliaEvents::CUSTOMER_DELETEACCOUNT => array("delete", 128),
TheliaEvents::CUSTOMER_CREATEACCOUNT => array('create', 128),
TheliaEvents::CUSTOMER_UPDATEACCOUNT => array('modify', 128),
TheliaEvents::CUSTOMER_LOGOUT => array('logout', 128),
TheliaEvents::CUSTOMER_LOGIN => array('login', 128),
TheliaEvents::CUSTOMER_DELETEACCOUNT => array('delete', 128),
);
}
}

View File

@@ -0,0 +1,75 @@
<?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\Action;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Thelia\Core\Event\PdfEvent;
use Thelia\Core\Event\TheliaEvents;
/**
* Class Pdf
* @package Thelia\Action
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class Pdf extends BaseAction implements EventSubscriberInterface
{
public function generatePdf(PdfEvent $event)
{
$html2pdf = new \HTML2PDF($event->getOrientation(), $event->getFormat(), $event->getLang(), $event->getUnicode(), $event->getEncoding(), $event->getMarges());
$html2pdf->pdf->SetDisplayMode('real');
$html2pdf->writeHTML($event->getContent());
$event->setPdf($html2pdf->output(null, 'S'));
}
/**
* Returns an array of event names this subscriber wants to listen to.
*
* The array keys are event names and the value can be:
*
* * The method name to call (priority defaults to 0)
* * An array composed of the method name to call and the priority
* * An array of arrays composed of the method names to call and respective
* priorities, or 0 if unset
*
* For instance:
*
* * array('eventName' => 'methodName')
* * array('eventName' => array('methodName', $priority))
* * array('eventName' => array(array('methodName1', $priority), array('methodName2'))
*
* @return array The event names to listen to
*
* @api
*/
public static function getSubscribedEvents()
{
return array(
TheliaEvents::GENERATE_PDF => array("generatePdf", 128)
);
}
}

View File

@@ -28,6 +28,7 @@ use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Filesystem\Filesystem;
use Thelia\Command\ContainerAwareCommand;
use Thelia\Install\CheckPermission;
use Thelia\Install\Database;
/**
@@ -82,6 +83,9 @@ class Install extends ContainerAwareCommand
'',
'Welcome to Thelia install process',
'You need information about your database configuration (host, username, password, database name, etc)',
'',
'<info>Caution : You are installing Thelia in cli mode, we verify some information, but this information are only available for the cli php sapi</info>',
'<info>This informations can be different in your apache or cgi php.ini files</info>',
''
));
@@ -136,40 +140,35 @@ class Install extends ContainerAwareCommand
"Checking some permissions"
));
$confDir = THELIA_ROOT . "local/config";
$cacheDir = THELIA_ROOT . "cache";
$logDir = THELIA_ROOT . "log";
$conf = is_writable($confDir);
$cache = is_writable($cacheDir);
$log = is_writable($logDir);
$permissions = new CheckPermission(false, $this->getContainer()->get('thelia.translator'));
$isValid = $permissions->exec();
foreach($permissions->getValidationMessages() as $item => $data) {
if($data['status']) {
$output->writeln(array(
sprintf(
"<info>config directory(%s)...</info> %s",
$confDir,
$conf ? "<info>Ok</info>" : "<error>Fail</error>"
),
sprintf(
"<info>cache directory(%s)...</info> %s"
,$cacheDir,
$cache ? "<info>Ok</info>" : "<error>Fail</error>"
),
sprintf(
"<info>log directory(%s)...</info> %s",
$logDir,
$log ? "<info>Ok</info>" : "<error>Fail</error>"
),
sprintf("<info>%s ...</info> %s",
$data['text'],
"<info>Ok</info>")
)
);
} else {
$output->writeln(array(
sprintf("<error>%s </error>%s",
$data['text'],
sprintf("<error>%s</error>", $data["hint"])
)
));
}
if ($conf === false || $cache === false || $log === false) {
}
if(false === $isValid) {
$output->writeln(array(
"",
"<error>Please put correct permission and reload install process</error>"
"<error>Please put correct permissions and reload install process</error>"
));
exit;
}
}
/**

View File

@@ -111,6 +111,11 @@
<tag name="kernel.event_subscriber"/>
</service>
<service id="thelia.action.pdf" class="Thelia\Action\Pdf">
<argument type="service" id="service_container"/>
<tag name="kernel.event_subscriber"/>
</service>
</services>
</config>

View File

@@ -123,6 +123,32 @@
<!-- end Customer rule management -->
<!-- address management -->
<route id="admin.address.delete" path="/admin/address/delete" methods="post">
<default key="_controller">Thelia\Controller\Admin\AddressController::deleteAction</default>
</route>
<route id="admin.address.makeItDefault" path="/admin/address/use" methods="post">
<default key="_controller">Thelia\Controller\Admin\AddressController::useAddressAction</default>
</route>
<route id="admin.address.create" path="/admin/address/create" methods="post">
<default key="_controller">Thelia\Controller\Admin\AddressController::createAction</default>
</route>
<route id="admin.address.update.view" path="/admin/address/update/{address_id}">
<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}">
<default key="_controller">Thelia\Controller\Admin\AddressController::processUpdateAction</default>
<requirement key="address_id">\d+</requirement>
</route>
<!-- end address management -->
<!-- order management -->
<route id="admin.order.list" path="/admin/orders">
@@ -150,6 +176,16 @@
<default key="_controller">Thelia\Controller\Admin\OrderController::updateAddress</default>
</route>
<route id="admin.order.pdf.invoice" path="/admin/order/pdf/invoice/{order_id}">
<default key="_controller">Thelia\Controller\Admin\OrderController::generateInvoicePdf</default>
<requirement key="order_id">\d+</requirement>
</route>
<route id="admin.order.pdf.invoice" path="/admin/order/pdf/delivery/{order_id}">
<default key="_controller">Thelia\Controller\Admin\OrderController::generateDeliveryPdf</default>
<requirement key="order_id">\d+</requirement>
</route>
<!-- end order management -->
<!-- Categories management -->
@@ -370,7 +406,7 @@
</route>
<!-- content routes management -->
<route id="admin.folders.create" path="/admin/content/create">
<route id="admin.content.create" path="/admin/content/create">
<default key="_controller">Thelia\Controller\Admin\ContentController::createAction</default>
</route>

View File

@@ -0,0 +1,306 @@
<?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\Controller\Admin;
use Thelia\Core\Event\Address\AddressCreateOrUpdateEvent;
use Thelia\Core\Event\Address\AddressEvent;
use Thelia\Core\Event\Customer\CustomerCreateOrUpdateEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Form\AddressCreateForm;
use Thelia\Form\AddressUpdateForm;
use Thelia\Model\AddressQuery;
use Thelia\Model\CustomerQuery;
/**
* Class AddressController
* @package Thelia\Controller\Admin
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class AddressController extends AbstractCrudController
{
public function __construct()
{
parent::__construct(
'address',
null,
null,
'admin.customer.update.view',
'admin.address.create',
'admin.address.update',
'admin.address.delete',
TheliaEvents::ADDRESS_CREATE,
TheliaEvents::ADDRESS_UPDATE,
TheliaEvents::ADDRESS_DELETE,
null,
null
);
}
public function useAddressAction()
{
if (null !== $response = $this->checkAuth("admin.customer.update")) return $response;
$address_id = $this->getRequest()->request->get('address_id');
try {
$address = AddressQuery::create()->findPk($address_id);
if (null === $address) {
throw new \InvalidArgumentException(sprintf('%d address does not exists', $address_id));
}
$addressEvent = new AddressEvent($address);
$this->dispatch(TheliaEvents::ADDRESS_DEFAULT, $addressEvent);
$this->adminLogAppend(sprintf("address %d for customer %d removal", $address_id, $address->getCustomerId()));
} catch(\Exception $e) {
\Thelia\Log\Tlog::getInstance()->error(sprintf("error during address removal with message %s", $e->getMessage()));
}
$this->redirectToRoute('admin.customer.update.view', array(), array('customer_id' => $address->getCustomerId()));
}
/**
* Return the creation form for this object
*/
protected function getCreationForm()
{
return new AddressCreateForm($this->getRequest());
}
/**
* Return the update form for this object
*/
protected function getUpdateForm()
{
return new AddressUpdateForm($this->getRequest());
}
/**
* Hydrate the update form for this object, before passing it to the update template
*
* @param \Thelia\Model\Address $object
*/
protected function hydrateObjectForm($object)
{
$data = array(
"label" => $object->getLabel(),
"title" => $object->getTitleId(),
"firstname" => $object->getFirstname(),
"lastname" => $object->getLastname(),
"address1" => $object->getAddress1(),
"address2" => $object->getAddress2(),
"address3" => $object->getAddress3(),
"zipcode" => $object->getZipcode(),
"city" => $object->getCity(),
"country" => $object->getCountryId(),
"cellphone" => $object->getCellphone(),
"phone" => $object->getPhone(),
"company" => $object->getCompany()
);
return new AddressUpdateForm($this->getRequest(), "form", $data);
}
/**
* Creates the creation event with the provided form data
*
* @param unknown $formData
*/
protected function getCreationEvent($formData)
{
$event = $this->getCreateOrUpdateEvent($formData);
$customer = CustomerQuery::create()->findPk($this->getRequest()->get("customer_id"));
$event->setCustomer($customer);
return $event;
}
/**
* Creates the update event with the provided form data
*
* @param unknown $formData
*/
protected function getUpdateEvent($formData)
{
$event = $this->getCreateOrUpdateEvent($formData);
$event->setAddress($this->getExistingObject());
return $event;
}
protected function getCreateOrUpdateEvent($formData)
{
$event = new AddressCreateOrUpdateEvent(
$formData["label"],
$formData["title"],
$formData["firstname"],
$formData["lastname"],
$formData["address1"],
$formData["address2"],
$formData["address3"],
$formData["zipcode"],
$formData["city"],
$formData["country"],
$formData["cellphone"],
$formData["phone"],
$formData["company"],
$formData["is_default"]
);
return $event;
}
/**
* Creates the delete event with the provided form data
*/
protected function getDeleteEvent()
{
return new AddressEvent($this->getExistingObject());
}
/**
* Return true if the event contains the object, e.g. the action has updated the object in the event.
*
* @param unknown $event
*/
protected function eventContainsObject($event)
{
return null !== $event->getAddress();
}
/**
* Get the created object from an event.
*
* @param unknown $createEvent
*/
protected function getObjectFromEvent($event)
{
return null;
}
/**
* Load an existing object from the database
*/
protected function getExistingObject()
{
return AddressQuery::create()->findPk($this->getRequest()->get('address_id'));
}
/**
* Returns the object label form the object event (name, title, etc.)
*
* @param unknown $object
*/
protected function getObjectLabel($object)
{
return $object->getLabel();
}
/**
* Returns the object ID from the object
*
* @param unknown $object
*/
protected function getObjectId($object)
{
return $object->getId();
}
/**
* Render the main list template
*
* @param unknown $currentOrder, if any, null otherwise.
*/
protected function renderListTemplate($currentOrder)
{
// TODO: Implement renderListTemplate() method.
}
/**
* Render the edition template
*/
protected function renderEditionTemplate()
{
return $this->render('ajax/address-update-modal', array(
"address_id" => $this->getRequest()->get('address_id'),
"customer_id" => $this->getExistingObject()->getCustomerId()
));
}
/**
* Redirect to the edition template
*/
protected function redirectToEditionTemplate()
{
$address = $this->getExistingObject();
$this->redirectToRoute('admin.customer.update.view', array(), array('customer_id' => $address->getCustomerId()));
}
/**
* Redirect to the list template
*/
protected function redirectToListTemplate()
{
// TODO: Implement redirectToListTemplate() method.
}
/**
* Put in this method post object delete processing if required.
*
* @param \Thelia\Core\Event\AddressEvent $deleteEvent the delete event
* @return Response a response, or null to continue normal processing
*/
protected function performAdditionalDeleteAction($deleteEvent)
{
$address = $deleteEvent->getAddress();
$this->redirectToRoute('admin.customer.update.view', array(), array('customer_id' => $address->getCustomerId()));
}
/**
* Put in this method post object creation processing if required.
*
* @param AddressCreateOrUpdateEvent $createEvent the create event
* @return Response a response, or null to continue normal processing
*/
protected function performAdditionalCreateAction($createEvent)
{
$this->redirectToEditionTemplate();
}
protected function performAdditionalUpdateAction($event)
{
$this->redirectToEditionTemplate();
}
}

View File

@@ -51,7 +51,7 @@ class BaseAdminController extends BaseController
/**
* Helper to append a message to the admin log.
*
* @param unknown $message
* @param string $message
*/
public function adminLogAppend($message)
{
@@ -187,12 +187,12 @@ class BaseAdminController extends BaseController
/**
* @return a ParserInterface instance parser
*/
protected function getParser()
protected function getParser($template = null)
{
$parser = $this->container->get("thelia.parser");
// Define the template thant shoud be used
$parser->setTemplate(ConfigQuery::read('base_admin_template', 'admin/default'));
$parser->setTemplate($template ?: ConfigQuery::read('base_admin_template', 'admin/default'));
return $parser;
}
@@ -246,9 +246,9 @@ class BaseAdminController extends BaseController
* @param unknown $routeId the route ID, as found in Config/Resources/routing/admin.xml
* @param unknown $urlParameters the URL parametrs, as a var/value pair array
*/
public function redirectToRoute($routeId, $urlParameters = array())
public function redirectToRoute($routeId, $urlParameters = array(), $routeParameters = array())
{
$this->redirect(URL::getInstance()->absoluteUrl($this->getRoute($routeId), $urlParameters));
$this->redirect(URL::getInstance()->absoluteUrl($this->getRoute($routeId, $routeParameters), $urlParameters));
}
/**
@@ -379,9 +379,11 @@ class BaseAdminController extends BaseController
*
* @param $templateName the complete template name, with extension
* @param array $args the template arguments
* @param null $templateDir
*
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function renderRaw($templateName, $args = array())
protected function renderRaw($templateName, $args = array(), $templateDir = null)
{
// Add the template standard extension
@@ -417,7 +419,7 @@ class BaseAdminController extends BaseController
// Render the template.
try {
$data = $this->getParser()->render($templateName, $args);
$data = $this->getParser($templateDir)->render($templateName, $args);
return $data;
} catch (AuthenticationException $ex) {

View File

@@ -22,13 +22,17 @@
/*************************************************************************************/
namespace Thelia\Controller\Admin;
use Propel\Runtime\Exception\PropelException;
use Symfony\Component\Form\Form;
use Thelia\Core\Event\Address\AddressEvent;
use Thelia\Core\Event\Customer\CustomerAddressEvent;
use Thelia\Core\Event\Customer\CustomerCreateOrUpdateEvent;
use Thelia\Core\Event\Customer\CustomerEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Form\CustomerModification;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Model\AddressQuery;
use Thelia\Model\CustomerQuery;
use Thelia\Core\Translation\Translator;
@@ -53,6 +57,8 @@ class CustomerController extends BaseAdminController
));
}
/**
* update customer action
*

View File

@@ -23,10 +23,13 @@
namespace Thelia\Controller\Admin;
use Symfony\Component\HttpFoundation\Response;
use Thelia\Core\Event\Order\OrderAddressEvent;
use Thelia\Core\Event\Order\OrderEvent;
use Thelia\Core\Event\PdfEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Form\OrderUpdateAddress;
use Thelia\Model\ConfigQuery;
use Thelia\Model\Base\OrderAddressQuery;
use Thelia\Model\OrderQuery;
use Thelia\Model\OrderStatusQuery;
@@ -193,4 +196,52 @@ class OrderController extends BaseAdminController
$this->redirect(URL::getInstance()->absoluteUrl($this->getRoute("admin.order.update.view", $params)));
}
public function generateInvoicePdf($order_id)
{
return $this->generatePdf($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("admin.order.update")) return $response;
$html = $this->renderRaw(
$fileName,
array(
'order_id' => $order_id
),
ConfigQuery::read('pdf_template', 'pdf')
);
$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
))));
}
}

View File

@@ -0,0 +1,193 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Core\Event;
/**
* Class PdfEvent
* @package Thelia\Core\Event
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class PdfEvent extends ActionEvent
{
protected $content;
protected $pdf;
protected $orientation;
protected $format;
protected $lang;
protected $unicode;
protected $encoding;
protected $marges;
/**
* @param $content html content to transform into pdf
* @param string $orientation page orientation, same as TCPDF
* @param string $format The format used for pages, same as TCPDF
* @param string $lang Lang : fr, en, it...
* @param bool $unicode TRUE means that the input text is unicode (default = true)
* @param string $encoding charset encoding; default is UTF-8
* @param array $marges Default marges (left, top, right, bottom)
*/
public function __construct($content, $orientation = 'P', $format = 'A4', $lang='fr', $unicode=true, $encoding='UTF-8',array $marges = array(0, 0, 0, 0))
{
$this->content = $content;
$this->orientation = $orientation;
$this->format = $format;
$this->lang = $lang;
$this->unicode = $unicode;
$this->encoding = $encoding;
$this->marges = $marges;
}
/**
* @param mixed $content
*/
public function setContent($content)
{
$this->content = $content;
}
/**
* @return mixed
*/
public function getContent()
{
return $this->content;
}
public function setPdf($pdf)
{
$this->pdf = $pdf;
}
public function getPdf()
{
return $this->pdf;
}
public function hasPdf()
{
return null !== $this->pdf;
}
/**
* @param mixed $encoding
*/
public function setEncoding($encoding)
{
$this->encoding = $encoding;
}
/**
* @return mixed
*/
public function getEncoding()
{
return $this->encoding;
}
/**
* @param mixed $format
*/
public function setFormat($format)
{
$this->format = $format;
}
/**
* @return mixed
*/
public function getFormat()
{
return $this->format;
}
/**
* @param mixed $lang
*/
public function setLang($lang)
{
$this->lang = $lang;
}
/**
* @return mixed
*/
public function getLang()
{
return $this->lang;
}
/**
* @param mixed $marges
*/
public function setMarges($marges)
{
$this->marges = $marges;
}
/**
* @return mixed
*/
public function getMarges()
{
return $this->marges;
}
/**
* @param mixed $orientation
*/
public function setOrientation($orientation)
{
$this->orientation = $orientation;
}
/**
* @return mixed
*/
public function getOrientation()
{
return $this->orientation;
}
/**
* @param mixed $unicode
*/
public function setUnicode($unicode)
{
$this->unicode = $unicode;
}
/**
* @return mixed
*/
public function getUnicode()
{
return $this->unicode;
}
}

View File

@@ -76,6 +76,11 @@ final class TheliaEvents
*/
const CUSTOMER_DELETEACCOUNT = "action.deleteCustomer";
/**
* sent on customer address removal
*/
const CUSTOMER_ADDRESS_DELETE = "action.customer.deleteAddress";
/**
* sent when a customer need a new password
*/
@@ -134,6 +139,11 @@ final class TheliaEvents
*/
const ADDRESS_DELETE = "action.deleteAddress";
/**
* sent when an address is tag as default
*/
const ADDRESS_DEFAULT = "action.defaultAddress";
const BEFORE_CREATEADDRESS = "action.before_createAddress";
const AFTER_CREATEADDRESS = "action.after_createAddress";
@@ -597,4 +607,6 @@ final class TheliaEvents
*/
const GENERATE_REWRITTENURL = 'action.generate_rewritenurl';
const GENERATE_PDF = 'thelia.generatePdf';
}

View File

@@ -72,7 +72,7 @@ class AsseticHelper
break;
case 'sass' :
$fm->set('less', new Filter\Sass\SassFilter());
$fm->set('sass', new Filter\Sass\SassFilter());
break;
case 'cssembed' :
@@ -87,6 +87,10 @@ class AsseticHelper
$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;

View File

@@ -30,6 +30,7 @@ use Thelia\Core\Template\Smarty\AbstractSmartyPlugin;
use Thelia\Core\Security\SecurityContext;
use Thelia\Core\Template\ParserContext;
use Thelia\Core\Template\Smarty\SmartyPluginDescriptor;
use Thelia\Model\ConfigQuery;
use Thelia\Model\CategoryQuery;
use Thelia\Model\ContentQuery;
use Thelia\Model\CountryQuery;
@@ -234,6 +235,17 @@ class DataAccessFunctions extends AbstractSmartyPlugin
return $this->dataAccess("Lang", $params, $this->request->getSession()->getLang());
}
public function ConfigDataAccess($params, $smarty)
{
if(false === array_key_exists("key", $params)) {
return null;
}
$key = $params['key'];
return ConfigQuery::read($key);
}
/**
* @param $objectLabel
* @param $params
@@ -344,6 +356,7 @@ class DataAccessFunctions extends AbstractSmartyPlugin
new SmartyPluginDescriptor('function', 'lang', $this, 'langDataAccess'),
new SmartyPluginDescriptor('function', 'cart', $this, 'cartDataAccess'),
new SmartyPluginDescriptor('function', 'order', $this, 'orderDataAccess'),
new SmartyPluginDescriptor('function', 'config', $this, 'ConfigDataAccess'),
);
}

View File

@@ -45,6 +45,7 @@ class CheckPermission extends BaseInstall
const DIR_LOG = 'log';
const DIR_CACHE = 'cache';
const DIR_WEB = 'web';
const DIR_SESSION = 'local/session';
/** @var array Directory needed to be writable */
protected $directoriesToBeWritable = array(
@@ -52,11 +53,12 @@ class CheckPermission extends BaseInstall
self::DIR_LOG,
self::DIR_CACHE,
self::DIR_WEB,
self::DIR_SESSION,
);
/** @var array Minimum server configuration necessary */
protected $minServerConfigurationNecessary = array(
'memory_limit' => 134217728,
'memory_limit' => 157286400,
'post_max_size' => 20971520,
'upload_max_filesize' => 2097152
);
@@ -187,9 +189,9 @@ class CheckPermission extends BaseInstall
{
if ($this->translator !== null) {
if ($isValid) {
$sentence = 'Your directory <strong>%directory%</strong> is writable';
$sentence = 'Your directory %directory% is writable';
} else {
$sentence = 'Your directory <strong>%directory%</strong> is not writable';
$sentence = 'Your directory %directory% is not writable';
}
$translatedText = $this->translator->trans(
@@ -216,7 +218,7 @@ class CheckPermission extends BaseInstall
protected function getI18nDirectoryHint($directory)
{
if ($this->translator !== null) {
$sentence = '<span class="label label-primary">chmod 777 %directory%</span> on your server with admin rights could help';
$sentence = 'chmod 777 %directory% on your server with admin rights could help';
$translatedText = $this->translator->trans(
$sentence,
array(
@@ -246,9 +248,9 @@ class CheckPermission extends BaseInstall
protected function getI18nConfigText($key, $expectedValue, $currentValue, $isValid)
{
if ($isValid) {
$sentence = 'Your <span class="label label-primary">%key%</span> server configuration (currently %currentValue%) is well enough to run Thelia2 (%expectedValue% needed)';
$sentence = 'Your %key% server configuration (currently %currentValue%) is well enough to run Thelia2 (%expectedValue% needed)';
} else {
$sentence = 'Your <span class="label label-primary">%key%</span> server configuration (currently %currentValue%) is not sufficient enough in order to run Thelia2 (%expectedValue% needed)';
$sentence = 'Your %key% server configuration (currently %currentValue%) is not sufficient enough in order to run Thelia2 (%expectedValue% needed)';
}
$translatedText = $this->translator->trans(
@@ -271,7 +273,7 @@ class CheckPermission extends BaseInstall
*/
protected function getI18nConfigHint()
{
$sentence = 'Modifying this value on your server <span class="label label-primary">php.ini</span> file with admin rights could help';
$sentence = 'Modifying this value on your server php.ini file with admin rights could help';
$translatedText = $this->translator->trans(
$sentence,
array(),
@@ -294,9 +296,9 @@ class CheckPermission extends BaseInstall
{
if ($this->translator !== null) {
if ($isValid) {
$sentence = 'Your PHP version <span class="label label-primary">%currentValue%</span> is well enough to run Thelia2 (%expectedValue% needed)';
$sentence = 'Your PHP version %currentValue% is well enough to run Thelia2 (%expectedValue% needed)';
} else {
$sentence = 'Your PHP version <span class="label label-primary">%currentValue%</span> is not sufficient enough to run Thelia2 (%expectedValue% needed)';
$sentence = 'Your PHP version %currentValue% is not sufficient enough to run Thelia2 (%expectedValue% needed)';
}
$translatedText = $this->translator->trans(
@@ -343,6 +345,10 @@ class CheckPermission extends BaseInstall
{
$serverValueInBytes = $this->returnBytes(ini_get($key));
if($serverValueInBytes == -1) {
return true;
}
return ($serverValueInBytes >= $necessaryValueInBytes);
}

View File

@@ -40,21 +40,33 @@ class Database
/**
* Insert all sql needed in database
* Default insert /install/thelia.sql and /install/insert.sql
*
* @param $dbName
* @param string $dbName Database name
* @param array $extraSqlFiles SQL Files uri to insert
*/
public function insertSql($dbName = null)
public function insertSql($dbName = null, array $extraSqlFiles = null)
{
if ($dbName) {
$this->connection->query(sprintf("use %s", $dbName));
}
$sql = array();
if (null === $extraSqlFiles) {
$sql = array_merge(
$sql,
$this->prepareSql(file_get_contents(THELIA_ROOT . "/install/thelia.sql")),
$this->prepareSql(file_get_contents(THELIA_ROOT . "/install/insert.sql"))
$this->prepareSql(file_get_contents(THELIA_ROOT . '/install/thelia.sql')),
$this->prepareSql(file_get_contents(THELIA_ROOT . '/install/insert.sql'))
);
} else {
foreach ($extraSqlFiles as $fileToInsert) {
$sql = array_merge(
$sql,
$this->prepareSql(file_get_contents($fileToInsert))
);
}
}
for ($i = 0; $i < count($sql); $i ++) {
if (!empty($sql[$i])) {
@@ -75,7 +87,7 @@ class Database
$sql = trim($sql);
$query = array();
$tab = explode(";", $sql);
$tab = explode(";\n", $sql);
for ($i=0; $i<count($tab); $i++) {
$queryTemp = str_replace("-CODE-", ";',", $tab[$i]);

View File

@@ -27,7 +27,8 @@ INSERT INTO `config` (`name`, `value`, `secured`, `hidden`, `created_at`, `updat
('thelia_admin_remember_me_cookie_expiration', 2592000, 0, 0, NOW(), NOW()),
('thelia_customer_remember_me_cookie_name', 'tcrmcn', 0, 0, NOW(), NOW()),
('thelia_customer_remember_me_cookie_expiration', 31536000, 0, 0, NOW(), NOW()),
('session_config.handlers', 'Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NativeFileSessionHandler', 0, 0, NOW(), NOW())
('session_config.handlers', 'Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NativeFileSessionHandler', 0, 0, NOW(), NOW()),
('company_name','', 0, 0, NOW(), NOW())
;

View File

@@ -118,11 +118,11 @@
<a href="#" class="dropdown-toggle" data-toggle="dropdown">{intl l="Orders"} <span class="caret"></span></a>
<ul class="dropdown-menu config_menu" role="menu">
<ul class="dropdown-menu" role="menu">
<li role="menuitem">
<a data-target="{url path='admin/orders'}" href="{url path='admin/orders'}">
{intl l="All orders"}
<a class="clearfix" data-target="{url path='admin/orders'}" href="{url path='admin/orders'}">
<span class="pull-left">{intl l="All orders"}</span>
<span class="label label-default pull-right">{count type="order" customer="*" backend_context="1"}</span>
</a>
</li>
@@ -130,8 +130,8 @@
{loop name="order-status-list" type="order-status"}
{assign "orderStatusLabel" "order_$CODE"}
<li role="menuitem">
<a data-target="{url path='admin/orders/$LABEL'}" href="{url path="admin/orders" status=$ID}">
{$TITLE}
<a class="clearfix" data-target="{url path='admin/orders/$LABEL'}" href="{url path="admin/orders" status=$ID}">
<span class="pull-left">{$TITLE}</span>
<span class="label label-{#$orderStatusLabel#} pull-right">{count type="order" customer="*" backend_context="1" status=$ID}</span>
</a>
</li>

View File

@@ -0,0 +1,111 @@
{* Update an Address *}
{form name="thelia.address.update"}
{* Capture the dialog body, to pass it to the generic dialog *}
{capture "edit_address_dialog"}
{form_hidden_fields form=$form}
{form_field form=$form field='label'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l={$label}} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l={$label} }" placeholder="{intl l='Label'}">
</div>
{/form_field}
{form_field form=$form field='company'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l={$label}} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l={$label}}" placeholder="{intl l='Company'}">
</div>
{/form_field}
{form_field form=$form field='title'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l={$label}} : </label>
<select name="{$name}" id="{$label_attr.for}" class="form-control">
{loop type="title" name="title1"}
<option value="{$ID}" {if $value == $ID}selected{/if}>{$LONG}</option>
{/loop}
</select>
</div>
{/form_field}
{form_field form=$form field='firstname'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l={$label}} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l={$label}}" placeholder="{intl l='Firstname'}">
</div>
{/form_field}
{form_field form=$form field='lastname'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l={$label}} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l={$label}}" placeholder="{intl l='Lastname'}">
</div>
{/form_field}
{form_field form=$form field='address1'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l={$label}} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l={$label}}" placeholder="{intl l='Address'}">
</div>
<div class="form-group">
{form_field form=$form field='address2'}
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l={$label}}" placeholder="{intl l='Additional address'}">
{/form_field}
</div>
<div class="form-group">
{form_field form=$form field='address3'}
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l={$label}}" placeholder="{intl l='Additional address'}">
{/form_field}
</div>
{/form_field}
{form_field form=$form field='zipcode'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l={$label}} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l={$label}}" placeholder="{intl l='Zip code'}">
</div>
{/form_field}
{form_field form=$form field='city'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l={$label}} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l={$label}}" placeholder="{intl l='City'}">
</div>
{/form_field}
{form_field form=$form field='country'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l={$label}} : </label>
<select name="{$name}" id="{$label_attr.for}" class="form-control">
{loop type="country" name="country1"}
<option value="{$ID}" {if $value == $ID}selected{/if}>{$TITLE}</option>
{/loop}
</select>
</div>
{/form_field}
{/capture}
{include
file = "includes/generic-create-dialog.html"
dialog_id = "edit_address_dialog"
dialog_title = {intl l="Edit an address"}
dialog_body = {$smarty.capture.edit_address_dialog nofilter}
dialog_ok_label = {intl l="Edit this address"}
dialog_cancel_label = {intl l="Cancel"}
form_action = {url path="/admin/address/save/{$address_id}"}
form_enctype = {form_enctype form=$form}
form_error_message = $form_error_message
}
{/form}

View File

@@ -9,6 +9,14 @@
// Base class and wrapper
.navbar {
margin-bottom: 0;
.dropdown-menu {
> li {
> a > .label {
font-size: 15px;
}
}
}
}
// Inner for background effects

View File

@@ -295,6 +295,13 @@
width: auto;
}
.modal-backdrop .loading {
left: 50%;
top: 50%;
right: auto;
position: absolute;
}
.existing-image .col-sm-6{
position: relative;

View File

@@ -44,7 +44,7 @@
{/form_field}
{if $form_error}<div class="alert alert-danger">{$form_error_message}</div>{/if}
{loop name="address" type="address" customer="$customer_id" backend_context="1" default="true"}
<div class="col-md-6">
<p class="title title-without-tabs">{intl l="Customer informations"}</p>
@@ -74,7 +74,7 @@
</div>
{/form_field}
{loop name="address" type="address" customer="$customer_id" backend_context="1" default="true"}
<p class="title title-without-tabs">{intl l="Default address"}</p>
@@ -171,15 +171,15 @@
<td>
<div class="btn-group">
<a class="btn btn-default btn-xs" title="{intl l='Edit this address'}" href="#edit_address_dialog" data-toggle="modal">
<a class="btn btn-default btn-xs customer-update-address" title="{intl l='Edit this address'}" href="#" data-id="{$ID}">
<span class="glyphicon glyphicon-edit"></span>
</a>
<a class="btn btn-default btn-xs" title="{intl l='Use this address by default'}" href="#use_address_dialog" data-toggle="modal" rel="tooltip">
<a class="btn btn-default btn-xs customer-address-use" title="{intl l='Use this address by default'}" href="#use_address_dialog" data-id="{$ID}" data-toggle="modal" rel="tooltip">
<span class="glyphicon glyphicon-pushpin"></span>
</a>
<a class="btn btn-default btn-xs customer-delete" title="{intl l='Delete this customer and all his orders'}" href="#delete_address_dialog" data-id="{$ID}" data-toggle="modal">
<a class="btn btn-default btn-xs customer-address-delete" title="{intl l='Delete this customer and all his orders'}" href="#delete_address_dialog" data-id="{$ID}" data-toggle="modal">
<span class="glyphicon glyphicon-trash"></span>
</a>
@@ -218,7 +218,7 @@
</div>
</div>
<div id="address-update-modal"></div>
{* Add an Address *}
{form name="thelia.address.create"}
@@ -227,7 +227,10 @@
{capture "address_creation_dialog"}
{form_hidden_fields form=$form}
<input type="hidden" name="customer_id" value="{$customer_id}">
{form_field form=$form field='success_url'}
<input type="hidden" name="{$name}" value="{url path="/admin/customer/update/{$customer_id}"}" />
{/form_field}
{form_field form=$form field='label'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l="{$label}"} : </label>
@@ -246,7 +249,7 @@
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l="{$label}"} : </label>
<select name="{$name}" id="{$label_attr.for}" class="form-control">
<select name="{$name}" id="{$label_attr.for}" class="form-control" required>
{loop type="title" name="title1"}
<option value="{$ID}">{$LONG}</option>
{/loop}
@@ -257,21 +260,21 @@
{form_field form=$form field='firstname'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l="{$label}"} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l="{$label}"}" placeholder="{intl l='Firstname'}">
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l="{$label}"}" placeholder="{intl l='Firstname'}" required>
</div>
{/form_field}
{form_field form=$form field='lastname'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l="{$label}"} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l="{$label}"}" placeholder="{intl l='Lastname'}">
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l="{$label}"}" placeholder="{intl l='Lastname'}" required>
</div>
{/form_field}
{form_field form=$form field='address1'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l="{$label}"} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l="{$label}"}" placeholder="{intl l='Address'}">
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l="{$label}"}" placeholder="{intl l='Address'}" required>
</div>
<div class="form-group">
@@ -290,21 +293,21 @@
{form_field form=$form field='zipcode'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l="{$label}"} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l="{$label}"}" placeholder="{intl l='Zip code'}">
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l="{$label}"}" placeholder="{intl l='Zip code'}" required>
</div>
{/form_field}
{form_field form=$form field='city'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l="{$label}"} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l="{$label}"}" placeholder="{intl l='City'}">
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l="{$label}"}" placeholder="{intl l='City'}" required>
</div>
{/form_field}
{form_field form=$form field='country'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l="{$label}"} : </label>
<select name="{$name}" id="{$label_attr.for}" class="form-control">
<select name="{$name}" id="{$label_attr.for}" class="form-control" required>
{loop type="country" name="country1"}
<option value="{$ID}">{$TITLE}</option>
{/loop}
@@ -331,117 +334,7 @@
{/form}
{* Update an Address *}
{form name="thelia.address.update"}
{* Capture the dialog body, to pass it to the generic dialog *}
{capture "edit_address_dialog"}
{form_hidden_fields form=$form}
{form_field form=$form field='label'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l="{$label}"} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l="{$label}"}" placeholder="{intl l='Label'}">
</div>
{/form_field}
{form_field form=$form field='company'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l="{$label}"} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l="{$label}"}" placeholder="{intl l='Company'}">
</div>
{/form_field}
{form_field form=$form field='title'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l="{$label}"} : </label>
<select name="{$name}" id="{$label_attr.for}" class="form-control">
{loop type="title" name="title1"}
<option value="{$ID}">{$LONG}</option>
{/loop}
</select>
</div>
{/form_field}
{form_field form=$form field='firstname'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l="{$label}"} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l="{$label}"}" placeholder="{intl l='Firstname'}">
</div>
{/form_field}
{form_field form=$form field='lastname'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l="{$label}"} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l="{$label}"}" placeholder="{intl l='Lastname'}">
</div>
{/form_field}
{form_field form=$form field='address1'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l="{$label}"} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l="{$label}"}" placeholder="{intl l='Address'}">
</div>
<div class="form-group">
{form_field form=$form field='address2'}
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l="{$label}"}" placeholder="{intl l='Additional address'}">
{/form_field}
</div>
<div class="form-group">
{form_field form=$form field='address3'}
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l="{$label}"}" placeholder="{intl l='Additional address'}">
{/form_field}
</div>
{/form_field}
{form_field form=$form field='zipcode'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l="{$label}"} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l="{$label}"}" placeholder="{intl l='Zip code'}">
</div>
{/form_field}
{form_field form=$form field='city'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l="{$label}"} : </label>
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}" title="{intl l="{$label}"}" placeholder="{intl l='City'}">
</div>
{/form_field}
{form_field form=$form field='country'}
<div class="form-group {if $error}has-error{/if}">
<label for="{$label_attr.for}" class="control-label">{intl l="{$label}"} : </label>
<select name="{$name}" id="{$label_attr.for}" class="form-control">
{loop type="country" name="country1"}
<option value="{$ID}">{$TITLE}</option>
{/loop}
</select>
</div>
{/form_field}
{/capture}
{include
file = "includes/generic-create-dialog.html"
dialog_id = "edit_address_dialog"
dialog_title = {intl l="Edit an address"}
dialog_body = {$smarty.capture.edit_address_dialog nofilter}
dialog_ok_label = {intl l="Edit this address"}
dialog_cancel_label = {intl l="Cancel"}
form_action = {url path='/admin/address/update'}
form_enctype = {form_enctype form=$form}
form_error_message = $form_error_message
}
{/form}
{* Default confirmation dialog *}
@@ -475,7 +368,7 @@
dialog_message = {intl l="Do you really want to delete this address ?"}
form_action = {url path='/admin/address/delete'}
form_content = {$smarty.capture.delete_dialog nofilter}
form_content = {$smarty.capture.delete_address_dialog nofilter}
}
{/block}
@@ -483,4 +376,35 @@
{javascripts file='assets/js/main.js'}
<script src="{$asset_url}"></script>
{/javascripts}
<script>
(function($) {
$(document).ready(function(){
$("a.customer-address-delete").click(function(e){
$("#address_delete_id").val($(this).data("id"));
});
$("a.customer-address-use").click(function(e){
$("#address_use_id").val($(this).data("id"));
});
$("a.customer-update-address").click(function(e){
var baseUrl = "{url path="/admin/address/update/"}";
$('body').append('<div class="modal-backdrop fade in" id="loading-event"><div class="loading"></div></div>');
$.ajax({
method: 'get',
url: baseUrl+$(this).data('id')
}).done(function(data){
$("#loading-event").remove();
$("#address-update-modal").html(data);
$("#edit_address_dialog").modal("show");
});
});
$(document).on("hidden.bs.modal", "#edit_address_dialog", function(ev){
$("#edit_address_dialog").remove();
});
});
})(jQuery);
</script>
{/block}

View File

@@ -193,7 +193,7 @@
<caption class="clearfix">
{intl l='Invoice informations'}
<div class="pull-right">
<a class="btn btn-default btn-primary" title="{intl l='Download invoice as PDF'}" href="#">
<a class="btn btn-default btn-primary" title="{intl l='Download invoice as PDF'}" href="{url path="/admin/order/pdf/invoice/$ID"}">
<span class="glyphicon glyphicon-cloud-download"></span> {intl l='PDF | Invoice'}
</a>
<a class="btn btn-default btn-primary js-update-order-address" data-address-id="{$INVOICE_ADDRESS}" title="{intl l='Edit invoice address'}" href="#edit_order_address_dialog" data-toggle="modal">
@@ -268,7 +268,7 @@
<caption class="clearfix">
{intl l='Delivery address'}
<div class="pull-right">
<a class="btn btn-default btn-primary" title="{intl l='Download purchase order as PDF'}" href="#">
<a class="btn btn-default btn-primary" title="{intl l='Download purchase order as PDF'}" href="{url path="/admin/order/pdf/delivery/$ID"}">
<span class="glyphicon glyphicon-cloud-download"></span> {intl l='PDF | Purchase order'}
</a>
<a class="btn btn-default btn-primary js-update-order-address" data-address-id="{$DELIVERY_ADDRESS}" title="{intl l='Edit delivery address'}" href="#edit_order_address_dialog" data-toggle="modal">

View File

@@ -1,3 +0,0 @@
<h1>PAGE NOT FOUND</h1>
<a href="{navigate to="index"}">Back Home</a>

View File

@@ -1,99 +0,0 @@
{check_auth context="front" roles="CUSTOMER" login_tpl="login"}
{include file="includes/header.html"}
{$page_title="{intl l='My Account'}"}
{form name="thelia.address.create"}
{if $form_error}<div class="alert alert-block alert-error">{$form_error_message}</div>{/if}
{* We use {navigate to="index"} as form action to avoid mixing post and get data *}
<form action="{url path="/address/create" }" method="post" {form_enctype form=$form}>
{form_field form=$form field='success_url'}
<input type="hidden" name="{$name}" value="{viewurl view="address_list"}" />
{/form_field}
{form_hidden_fields form=$form}
{form_field form=$form field="label"}
{if $error}{$message}{/if}
<label> <span>{intl l="{$label}"} : </span></label>
<input type="text" name="{$name}" value="{$value}" {$attr}>
<br />
{/form_field}
{form_field form=$form field="title"}
{if $error}{$message}{/if}
<label> <span>{intl l="{$label}"} : </span></label>
<select name="{$name}">
{loop type="title" name="title1"}
<option value="{$ID}">{$LONG}</option>
{/loop}
</select>
<br />
{/form_field}
{form_field form=$form field="firstname"}
{if $error}{$message}{/if}
<label> <span>{intl l="{$label}"} : </span></label>
<input type="text" name="{$name}" value="{$value}" {$attr}>
<br />
{/form_field}
{form_field form=$form field="lastname"}
{if $error}{$message}{/if}
<label> <span>{intl l="{$label}"} : </span></label>
<input type="text" name="{$name}" value="{$value}" {$attr}>
<br />
{/form_field}
{form_field form=$form field="address1"}
{if $error}{$message}{/if}
<label> <span>{intl l="{$label}"} : </span></label>
<input type="text" name="{$name}" value="{$value}" {$attr}>
<br />
{/form_field}
{form_field form=$form field="zipcode"}
{if $error}{$message}{/if}
<label> <span>{intl l="{$label}"} : </span></label>
<input type="text" name="{$name}" value="{$value}" {$attr}>
<br />
{/form_field}
{form_field form=$form field="city"}
{if $error}{$message}{/if}
<label> <span>{intl l="{$label}"} : </span></label>
<input type="text" name="{$name}" value="{$value}" {$attr}>
<br />
{/form_field}
{form_field form=$form field="country"}
{if $error}{$message}{/if}
<label> <span>{intl l="{$label}"} : </span></label>
<select name="{$name}">
{loop type="country" name="country1"}
<option value="{$ID}">{$TITLE}</option>
{/loop}
</select>
<br />
{/form_field}
{form_field form=$form field="phone"}
{if $error}{$message}{/if}
<label> <span>{intl l="{$label}"} : </span></label>
<input type="text" name="{$name}" value="{$value}" {$attr}>
<br />
{/form_field}
<input type="submit" value="submit">
</form>
{/form}
{include file="includes/footer.html"}

View File

@@ -1,100 +0,0 @@
{check_auth context="front" roles="CUSTOMER" login_tpl="login"}
{include file="includes/header.html"}
{$page_title="{intl l='My Account'}"}
{form name="thelia.address.update"}
{if $form_error}<div class="alert alert-block alert-error">{$form_error_message}</div>{/if}
{* We use {navigate to="index"} as form action to avoid mixing post and get data *}
<form action="{url path="/address/update" }" method="post" {form_enctype form=$form}>
{form_field form=$form field='success_url'}
<input type="hidden" name="{$name}" value="{viewurl view="address_list"}" />
{/form_field}
<input type="hidden" name="address_id" value="5" />
{form_hidden_fields form=$form}
{form_field form=$form field="label"}
{if $error}{$message}{/if}
<label> <span>{intl l="{$label}"} : </span></label>
<input type="text" name="{$name}" value="{$value}" {$attr}>
<br />
{/form_field}
{form_field form=$form field="title"}
{if $error}{$message}{/if}
<label> <span>{intl l="{$label}"} : </span></label>
<select name="{$name}">
{loop type="title" name="title1"}
<option value="{$ID}">{$LONG}</option>
{/loop}
</select>
<br />
{/form_field}
{form_field form=$form field="firstname"}
{if $error}{$message}{/if}
<label> <span>{intl l="{$label}"} : </span></label>
<input type="text" name="{$name}" value="{$value}" {$attr}>
<br />
{/form_field}
{form_field form=$form field="lastname"}
{if $error}{$message}{/if}
<label> <span>{intl l="{$label}"} : </span></label>
<input type="text" name="{$name}" value="{$value}" {$attr}>
<br />
{/form_field}
{form_field form=$form field="address1"}
{if $error}{$message}{/if}
<label> <span>{intl l="{$label}"} : </span></label>
<input type="text" name="{$name}" value="{$value}" {$attr}>
<br />
{/form_field}
{form_field form=$form field="zipcode"}
{if $error}{$message}{/if}
<label> <span>{intl l="{$label}"} : </span></label>
<input type="text" name="{$name}" value="{$value}" {$attr}>
<br />
{/form_field}
{form_field form=$form field="city"}
{if $error}{$message}{/if}
<label> <span>{intl l="{$label}"} : </span></label>
<input type="text" name="{$name}" value="{$value}" {$attr}>
<br />
{/form_field}
{form_field form=$form field="country"}
{if $error}{$message}{/if}
<label> <span>{intl l="{$label}"} : </span></label>
<select name="{$name}">
{loop type="country" name="country1"}
<option value="{$ID}">{$TITLE}</option>
{/loop}
</select>
<br />
{/form_field}
{form_field form=$form field="phone"}
{if $error}{$message}{/if}
<label> <span>{intl l="{$label}"} : </span></label>
<input type="text" name="{$name}" value="{$value}" {$attr}>
<br />
{/form_field}
<input type="submit" value="submit">
</form>
{/form}
{include file="includes/footer.html"}

View File

@@ -1,11 +0,0 @@
{check_auth context="front" roles="CUSTOMER" login_tpl="login"}
{include file="includes/header.html"}
{$page_title="{intl l='My Account'}"}
<ul>
{loop type="address" name="customer_list" customer="current"}
<li>{$LABEL} - {$FIRSTNAME} {$LASTNAME} - <a href="{url path="/address/edit/{$ID}"}">edit</a></li>
{/loop}
</ul>
{include file="includes/footer.html"}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -1,9 +0,0 @@
body {
font-size: 12px;
font-family: Arial, helvetica, sans serif;
background-image: url("../img/test-background.jpg");
}
div {
margin: 10px 0;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

File diff suppressed because one or more lines are too long

View File

@@ -1,50 +0,0 @@
{include file="includes/header.html"}
<h1>{intl l='cart'}</h1>
<ul>
{loop name="cart" type="cart"}
<li>Item {$LOOP_COUNT}/{$LOOP_TOTAL} : {$ITEM_ID} {$TITLE} - quantity : {$QUANTITY}</li>
{/loop}
</ul>
{form name="thelia.cart.add" }
{* We use {navigate to="index"} as form action to avoid mixing post and get data *}
<form action="{url path="/cart/add" }" method="post" {form_enctype form=$form}>
{*
The form error status and the form error messages are defined in Customer action,
and passed back to the form plugin through the ParserContext.
*}
{if $form_error}<div class="alert alert-error">{$form_error_message}</div>{/if}
{form_hidden_fields form=$form}
{form_field form=$form field="product"}
{form_error form=$form field="product"}
{$message}
{/form_error}
<label for="{$label_attr.for}">{intl l="{$label}"}: </label><input id="{$label_attr.for}" type="text" name="{$name}" value="{$value}" {$attr} ><br />
{/form_field}
{form_field form=$form field='product_sale_elements_id'}
{form_error form=$form field="product_sale_elements_id"}
{$message}
{/form_error}
<label>{intl l="product_sale_elements_id"}: </label><input type="text" name="{$name}" value="{$value}" {$attr}> <br />
{/form_field}
{form_field form=$form field='quantity'}
{form_error form=$form field="quantity"}
{$message}
{/form_error}
<label>{intl l="quantity"}: </label><input type="text" name="{$name}" value="{$value}" {$attr}> <br />
{/form_field}
<button type="submit">{intl l='Login'}</button>
</form>
{/form}
{include file='includes/footer.html'}

View File

@@ -1,145 +0,0 @@
<h1>Category page</h1>
<div style="border: solid 8px; margin: 0px; padding: 0px; width: 45%; float: left">
<h2>CATALOG</h2>
{loop name="category0" type="category" parent="0" order="manual"}
<div style="border: solid 4px blue; padding: 20px; margin: 10px;">
<h2>CATEGORY : {$TITLE} ({$LOOP_COUNT} / {$LOOP_TOTAL})</h2>
{ifloop rel="prod_ass_cont"}
<h5>Associated Content</h5>
<ul>
{loop name="prod_ass_cont" type="associated_content" category="$ID" order="associated_content"}
<li>{$TITLE}</li>
{/loop}
</ul>
{/ifloop}
{elseloop rel="prod_ass_cont"}
<h5>No associated content</h5>
{/elseloop}
{loop name="product" type="product" category="$ID"}
<div style="border: dashed 2px red; padding: 20px; margin: 10px;">
<h3><a href="{$URL}">PRODUCT {$ID} : {$REF} ({$LOOP_COUNT} / {$LOOP_TOTA}L)</a></h3>
<h4>{$TITLE}</h4>
<p>{$DESCRIPTION}</p>
<p>Starting by {$BEST_PRICE} € HT (TAX : {$BEST_PRICE_TAX} ; {$BEST_TAXED_PRICE} € TTC)</p>
{ifloop rel="ft"}
<h5>Features</h5>
<ul>
{assign var=current_product value=$ID}
{loop name="ft" type="feature" order="manual" product="$ID"}
<li>
<strong>{$TITLE}</strong> :
{loop name="ft_v" type="feature_value" product="{$current_product}" feature="{$ID}"}
{$TITLE} / {$PERSONAL_VALUE}
{/loop}
</li>
{/loop}
</ul>
{/ifloop}
{elseloop rel="ft"}
<h5>No feature</h5>
{/elseloop}
</div>
{/loop}
{loop name="catgory1" type="category" parent="$ID"}
<div style="border: double 4px lightseagreen; padding: 20px; margin: 10px;">
<h3>SUBCATEGORY : {$TITLE} ({$LOOP_COUNT} / {$LOOP_TOTAL})</h3>
{ifloop rel="prod_ass_cont"}
<h5>Associated Content</h5>
<ul>
{loop name="prod_ass_cont" type="associated_content" category="$ID" order="associated_content"}
<li>{$TITLE}</li>
{/loop}
</ul>
{/ifloop}
{elseloop rel="prod_ass_cont"}
<h5>No associated content</h5>
{/elseloop}
{loop name="product" type="product" category="$ID"}
<div style="border: solid 1px green; padding: 20px; margin: 10px;">
<h3><a href="{$URL}">PRODUCT {$ID} : {$REF} ({$LOOP_COUNT} / {$LOOP_TOTAL})</a></h3>
<h4>{$TITLE}</h4>
<p>{$DESCRIPTION}</p>
{ifloop rel="ft"}
<h5>Features</h5>
<ul>
{assign var=current_product value=$ID}
{loop name="ft" type="feature" order="manual" product="$ID"}
<li>
<strong>{$TITLE}</strong> :
{loop name="ft_v" type="feature_value" product="{$current_product}" feature="$ID"}
{$TITLE} / {$PERSONAL_VALUE}
{/loop}
</li>
{/loop}
</ul>
{/ifloop}
{elseloop rel="ft"}
<h5>No feature</h5>
{/elseloop}
</div>
{/loop}
</div>
{/loop}
</div>
{/loop}
</div>
<div style="border: solid 8px; margin: 0px; padding: 0px; width: 45%; float: left">
<h2>ALL FEATURES AND THEIR AVAILABILITY</h2>
<ul>
{loop name="ft" type="feature" order="manual"}
<li>
{$TITLE}
<ul>
{loop name="ftav" type="feature_availability" order="manual" feature="$ID"}
<li>{$TITLE}</li>
{/loop}
</ul>
</li>
{/loop}
</ul>
<hr />
<h2>ALL ATTRIBUTES AND THEIR AVAILABILITY</h2>
<ul>
{loop name="attr" type="attribute" order="manual"}
<li>
{$TITLE}
<ul>
{loop name="attrav" type="attribute_availability" order="manual" attribute="$ID"}
<li>{$TITLE}</li>
{/loop}
</ul>
</li>
{/loop}
</ul>
<hr />
<h2>CURRENCIES</h2>
<ul>
{loop name="cur" type="currency"}
<li>
{$NAME} ({$SYMBOL})
</li>
{/loop}
</ul>
</div>

View File

@@ -1,165 +0,0 @@
{include file="includes/header.html"}
{form name="thelia.customer.creation"}
{* We use {navigate to="index"} as form action to avoid mixing post and get data *}
<form action="{url path="/customer/create" }" method="post" {form_enctype form=$form}>
{*
The two fields below are not par of the form, they are here to defines
the action to process, and the view to render once the form is submited
*}
{*
This field is common to all BaseForm instances (thus, this one), and defines
the URL the customer is redirected to once the form has been successfully
processed
*}
{form_field form=$form field='success_url'}
<input type="hidden" name="{$name}" value="{navigate to="return_to"}" /> {* the url the user is redirected to on login success *}
{/form_field}
{form_field form=$form field='auto_login'}
<input type="hidden" name="{$name}" value="1" /> {* the customer will be loogged-in automatically *}
{/form_field}
{*
The form error status and the form error messages are defined in Customer action,
and passed back to the form plugin through the ParserContext.
*}
{if $form_error}<div class="alert alert-error">{$form_error_message}</div>{/if}
{form_hidden_fields form=$form}
{form_field form=$form field="title"}
{form_error form=$form field="title"}
{$message}
{/form_error}
<label> <span>{intl l="{$label}"} : </span></label>
<select name="{$name}">
<option value="1">M.</option>
<option value="2">Mme.</option>
</select>
<br />
{/form_field}
{form_field form=$form field="firstname"}
{form_error form=$form field="firstname"}
{$message}
{/form_error}
<label> <span>{intl l="{$label}"} : </span></label><input type="text" name="{$name}" value="{$value}" {$attr} > <br />
{/form_field}
{form_field form=$form field="lastname"}
{form_error form=$form field="lastname"}
{$message}
{/form_error}
<label> <span>{intl l="{$label}"} : </span></label><input type="text" name="{$name}" value="{$value}" {$attr} > <br />
{/form_field}
{form_field form=$form field="address1"}
{form_error form=$form field="address1"}
{$message}
{/form_error}
<label> <span>{intl l="{$label}"} : </span></label><input type="text" name="{$name}" value="{$value}" {$attr} > <br />
{/form_field}
{form_field form=$form field="address2"}
{form_error form=$form field="address2"}
{$message}
{/form_error}
<label> <span>{intl l="{$label}"} : </span></label><input type="text" name="{$name}" value="{$value}" {$attr} > <br />
{/form_field}
{form_field form=$form field="address3"}
{form_error form=$form field="address3"}
{$message}
{/form_error}
<label> <span>{intl l="{$label}"} : </span></label><input type="text" name="{$name}" value="{$value}" {$attr} > <br />
{/form_field}
{form_field form=$form field="zipcode"}
{form_error form=$form field="zipcode"}
{$message}
{/form_error}
<label> <span>{intl l="{$label}"} : </span></label><input type="text" name="{$name}" value="{$value}" {$attr} > <br />
{/form_field}
{form_field form=$form field="city"}
{form_error form=$form field="city"}
{$message}
{/form_error}
<label> <span>{intl l="{$label}"} : </span></label><input type="text" name="{$name}" value="{$value}" {$attr} > <br />
{/form_field}
{form_field form=$form field="country"}
{form_error form=$form field="country"}
{$message}
{/form_error}
<label> <span>{intl l="{$label}"} : </span></label>
<select name="{$name}">
<option value="1">France</option>
<option value="2">Belgium</option>
</select>
<br />
{/form_field}
{form_field form=$form field="phone"}
{form_error form=$form field="phone"}
{$message}
{/form_error}
<label> <span>{intl l="{$label}"} : </span></label><input type="text" name="{$name}" value="{$value}" {$attr}> <br />
{/form_field}
{form_field form=$form field="cellphone"}
{form_error form=$form field="cellphone"}
{$message}
{/form_error}
<label> <span>{intl l="{$label}"} : </span></label><input type="text" name="{$name}" value="{$value}" {$attr}> <br />
{/form_field}
{form_field form=$form field="email"}
{form_error form=$form field="email"}
{$message}
{/form_error}
<label><span>{intl l="{$label}"}</span></label><input type="email" name="{$name}" value="{$value}" {$attr} ><br />
{/form_field}
{form_field form=$form field="email_confirm"}
{form_error form=$form field="email_confirm"}
{$message}
{/form_error}
<label><span>{intl l="{$label}"}</span></label><input type="email" name="{$name}" {$attr} ><br />
{/form_field}
{form_field form=$form field="password"}
{form_error form=$form field="password"}
{$message}
{/form_error}
<label><span>{intl l="{$label}"}</span></label><input type="password" name="{$name}" {$attr} ><br />
{/form_field}
{form_field form=$form field="password_confirm"}
{form_error form=$form field="password_confirm"}
{$message}
{/form_error}
<label><span>{intl l="{$label}"}</span></label><input type="password" name="{$name}" {$attr} ><br />
{/form_field}
<input type="submit" value="valider">
</form>
{/form}
{include file="includes/footer.html"}

View File

@@ -1,125 +0,0 @@
<h1>CUSTOMER</h1>
<h2>Information</h2>
{loop name="customer" type="customer"}
<table border="1" cellspacing="0" cellpadding="5">
<tr>
<td>ID</td>
<td>{$ID}</td>
</tr>
<tr>
<td>Réference</td>
<td>{$REF}</td>
</tr>
<tr>
<td>Title</td>
<td>
{loop name="title" type="title" id="$TITLE"}
{$LONG} ({$SHORT})
{/loop}
</td>
</tr>
<tr>
<td>Firstname</td>
<td>{$FIRSTNAME}</td>
</tr>
<tr>
<td>Lastname</td>
<td>{$LASTNAME}</td>
</tr>
<tr>
<td>Email</td>
<td>{$EMAIL}</td>
</tr>
<tr>
<td>Is reseller</td>
<td>{$RESELLER}</td>
</tr>
<tr>
<td>Sponsor</td>
<td>{$SPONSOR}</td>
</tr>
<tr>
<td>Discount</td>
<td>{$DISCOUNT} %</td>
</tr>
</table>
{/loop}
<h2>Addresses</h2>
{loop name="addresses" type="address"}
<table border="1" cellspacing="0" cellpadding="5">
<tr>
<td>ID</td>
<td>{$ID}</td>
</tr>
<tr>
<td>Name</td>
<td>{$NAME}</td>
</tr>
<tr>
<td>Title</td>
<td>
<ul>
{assign var=current_title value=$TITLE}
{loop name="title" type="title"}
<li {if $current_title==$ID}style="background-color: yellow"{/if}>
{$LONG} ({$SHORT})
</li>
{/loop}
</ul>
</td>
</tr>
<tr>
<td>Company</td>
<td>{$COMPANY}</td>
</tr>
<tr>
<td>Firstname</td>
<td>{$FIRSTNAME}</td>
</tr>
<tr>
<td>Lastname</td>
<td>{$LASTNAME}</td>
</tr>
<tr>
<td>Address</td>
<td>{$ADDRESS1}<br/>{$ADDRESS2}<br/>{$ADDRESS3}</td>
</tr>
<tr>
<td>Zipcode</td>
<td>{$ZIPCODE}</td>
</tr>
<tr>
<td>City</td>
<td>{$CITY}</td>
</tr>
<tr>
<td>Country</td>
<td>
<select>
{assign var=current_country value=$COUNTRY}
{loop name="country" type="country"}
<option {if $current_country==$ID}selected="selected"{/if}>
{$TITLE} ({$ID} - {$ISOCODE} - {$ISOALPHA2} - {$ISOALPHA3})
</option>
{/loop}
</select>
</td>
</tr>
<tr>
<td>Phone</td>
<td>{$PHONE}</td>
</tr>
<tr>
<td>Cellphone</td>
<td>{$CELLPHONE}</td>
</tr>
</table>
{/loop}

View File

@@ -1,8 +0,0 @@
<h1>Category page</h1>
{loop type="category" name="categoryloop" id="500"}
TOTO
{/loop}
{pageloop rel="categoryloop"}
{/pageloop}

View File

@@ -1,15 +0,0 @@
{include file="includes/header.html"}
<ul>
{loop type="delivery" name="delivery.list"}
<li>
<ul>
<li>id : {$ID}</li>
<li>prix : {$PRICE}</li>
<li>Choisir : <a href="{url path="/delivery/choose/{$ID}"}">Choisir</a></li>
</ul>
</li>
{/loop}
</ul>
{include file="includes/footer.html"}

View File

@@ -1,16 +0,0 @@
{loop name="folder0" type="folder" parent="0" order="alpha_reverse"}
<div style="border: solid 4px blue; padding: 20px; margin: 10px;">
<h2>FOLDER : {$TITLE}</h2>
{loop name="folder1" type="folder" parent="$ID"}
<div style="border: double 4px lightseagreen; padding: 20px; margin: 10px;">
<h3>SUBFOLDER : {$TITLE} ({$LOOP_COUNT} / {$LOOP_TOTAL})</h3>
{loop name="content" type="content" folder="$ID"}
<div style="border: solid 1px green; padding: 20px; margin: 10px;">
<h3>CONTENT : {$TITLE}</h3>
<p>{$DESCRIPTION}</p>
</div>
{/loop}
</div>
{/loop}
</div>
{/loop}

View File

@@ -1 +0,0 @@
<?php

View File

@@ -1,104 +0,0 @@
{include file="includes/header.html"}
<div>
<h2>Category Images</h2>
<ul>
{loop type="category" name="jsvdfk"}
<li><p>Category id {$ID}: {$TITLE}</p>
<ul>
<li>
{loop type="image" name="image_test" category="$ID" width="200" height="100" resize_mode="borders"}
<p>Processed file URL: {$IMAGE_URL}</p>
<p>Original file URL: {$ORIGINAL_IMAGE_URL}</p>
<img src="{$IMAGE_URL}" />
{/loop}
{loop type="image" name="image_test" category="$ID"}
<p>Full size file URL: {$IMAGE_URL}</p>
<img src="{$IMAGE_URL}" />
{/loop}
{loop type="image" name="image_test" source="category" source_id="$ID"}
<p>source="category" source_id="x" argument style: Processed file URL: {$IMAGE_URL}</p>
{/loop}
</li>
</ul>
</li>
{/loop}
</ul>
</div>
<div>
<h2>Product Images</h2>
<ul>
{loop type="product" name="jsvdfk"}
<li><p>Product id {$ID}: {$TITLE}</p>
<ul>
<li>
{loop type="image" name="image_test" product="$ID" width="200" height="100" resize_mode="borders" effects="gamma:0.7" background_color="#cc8000"}
<p>Processed file URL: {$IMAGE_URL}</p>
<p>Original file URL: {$ORIGINAL_IMAGE_URL}</p>
<p>Images:</p>
<img src="{$IMAGE_URL}" />
{/loop}
{loop type="image" name="image_test" product="$ID" width="200" height="100" resize_mode="crop"}
<img src="{$IMAGE_URL}" />
{/loop}
{loop type="image" name="image_test" product="$ID" width="100" height="200" resize_mode="borders" background_color="#cc8000"}
<img src="{$IMAGE_URL}" />
{/loop}
{loop type="image" name="image_test" product="$ID" width="100" rotation="-20" background_color="#facabe"}
<img src="{$IMAGE_URL}" />
{/loop}
{loop type="image" name="image_test" product="$ID" width="200" height="100" resize_mode="borders" background_color="#facabe" effects="negative"}
<img src="{$IMAGE_URL}" />
{/loop}
</p>
</li>
</ul></li>
{/loop}
</ul>
</div>
<div>
<h2>Folder Images</h2>
<ul>
{loop type="folder" name="jsvdfk"}
<li><p>Folder id {$ID}: {$TITLE}</p>
<ul>
<li>
{loop type="image" name="image_test" folder="$ID" width="200" height="100" resize_mode="borders"}
<p>Processed file URL: {$IMAGE_URL}</p>
<p>Original file URL: {$ORIGINAL_IMAGE_URL}</p>
<img src="{$IMAGE_URL}" />
{/loop}
</li>
</ul>
</li>
{/loop}
</ul>
</div>
<div>
<h2>Content Images</h2>
<ul>
{loop type="content" name="jsvdfk"}
<li><p>Content id {$ID}: {$TITLE}</p>
<ul>
<li>
{loop type="image" name="image_test" content="$ID" width="200" height="100" resize_mode="borders"}
<p>Processed file URL: {$IMAGE_URL}</p>
<p>Original file URL: {$ORIGINAL_IMAGE_URL}</p>
<img src="{$IMAGE_URL}" />
{/loop}
</li>
</ul>
</li>
{/loop}
</ul>
</div>
{include file="includes/footer.html"}

View File

@@ -1,12 +0,0 @@
{loop name="included0" type="category" parent="0"}
<h2>Out before - CATEGORY : {$TITLE} ({$LOOP_COUNT} / {$LOOP_TOTAL})</h2>
{loop name="category1" type="category" parent="$ID"}
<h3>Inner - SUBCATEGORY : {$TITLE} ({$LOOP_COUNT} / {$LOOP_TOTAL})</h3>
{/loop}
{loop name="category2" type="category" parent="$ID"}
<h3>Inner 2 - SUBCATEGORY : {$TITLE} ({$LOOP_COUNT} / {$LOOP_TOTAL})</h3>
{/loop}
<h2>Out after - CATEGORY : {$TITLE} ({$LOOP_COUNT} / {$LOOP_TOTAL})</h2>
<hr />
{/loop}

View File

@@ -1,19 +0,0 @@
{* Include required JS files *}
{javascripts file='../assets/js/*'}
<script src="{$asset_url}"></script>
{/javascripts}
<script>
$(function() {
$('#jquery_block').html("Jquery is now loaded.").hover(function() {
$(this).css('font-weight', 'bold');
}, function() {
$(this).css('font-weight', 'normal');
});
});
</script>
{debugbar_renderjs}
{debugbar_renderresult}
</body>
</html>

View File

@@ -1,26 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>{$page_title|default:{intl l="Thelia II"}}</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
{stylesheets file='../assets/css/*' filters='less,cssembed'}
<link rel="stylesheet" href="{$asset_url}">
{/stylesheets}
{debugbar_rendercss}
</head>
<body>
<div>
{loop type="auth" name="customer_info_block" roles="CUSTOMER" context="front"}
<p>Your are logged in as {customer attr="firstname"} {customer attr="lastname"} ! <a href="{url path='/customer/logout'}">Logout</a></p>
{/loop}
{loop type="auth" name="admin_info_block" roles="ADMIN" context="admin"}
<p>You are logged as administrator {admin attr="firstname"} {admin attr="lastname"}</p>
{/loop}
{elseloop rel="customer_info_block"}
You are not logged in. <a href="{viewurl view='login'}">Login now</a> or <a href="{viewurl view='connexion'}">create your account</a>
{/elseloop}
</div>
<hr />

View File

@@ -1,153 +0,0 @@
{include file="includes/header.html"}
<div>
Here you are : {navigate to="current"}
{loop type="auth" name="auth_test" context="front" roles="CUSTOMER"}
<p>Customer is authentified :-)</p>
{/loop}
{elseloop rel="auth_test"}
<p>Customer is not authentified :-(</p>
{/elseloop}
An image from asset directory :
{images file='assets/img/logo-thelia-34px.png'}<img src="{$asset_url}" alt="{intl l='Thelia, solution e-commerce libre'}" />{/images}
</div>
<div>
{intl l='An internationalized string'}
</div>
<div>
jQuery data: <span id="jquery_block"></span>
</div>
<div>
<p>Category loop example</p>
<ul>
{loop type="category" name="catloop1"}
<li>{$LOOP_COUNT}/{$LOOP_TOTAL} : {$ID} {$TITLE}, children: {$NB_CHILD}
{ifloop rel="inner1"}
<ul>
{loop type="category" name="inner1" parent="{$ID}"}
<li>Sub cat {$ID} (parent is {$PARENT}): {$TITLE}</li>
{/loop}
</ul>
{/ifloop}
</li>
{/loop}
</ul>
</div>
<div>
<p>Conditional example #1</p>
{ifloop rel="catloop2"}
Hey ! Loop catloop2 is not empty:
<ul>
{loop type="category" name="catloop2" parent="12"}
<li>{$LOOP_COUNT}/{$LOOP_TOTAL} : {$ID} {$TITLE}</li>
{/loop}
</ul>
{/ifloop}
{elseloop rel="catloop2"}
<p>Loop catloop2 is empty</p>
{/elseloop}
</div>
<div>
<p>Conditional example #2</p>
{ifloop rel="catloop3"}
Loop catloop3 is not empty:
<ul>
{loop type="category" name="catloop3" parent="0"}
<li>{$LOOP_COUNT}/{$LOOP_TOTAL} : {$ID} {$TITLE}</li>
{/loop}
</ul>
{/ifloop}
{elseloop rel="catloop3"}
<p>Loop catloop3 is empty</p>
{/elseloop}
{elseloop rel="catloop2"}
<p>... but catloop2 is still empty :-)</p>
{/elseloop}
</div>
<div>
<p>Traditional for loop</p>
{for $index=5 to 12 step 1}
Compteur = {$index}<br />
{/for}
</div>
<div>
<p>Some pagination</p>
<p>PAGE 1</p>
<ul>
{loop type="category" name="catloopwithpagination1" limit="2" page="1"}
<li>{$LOOP_COUNT}/{$LOOP_TOTAL} : {$ID} {$TITLE}</li>
{/loop}
</ul>
<p>PAGE 2</p>
<ul>
{loop type="category" name="catloopwithpagination2" limit="2" page="2"}
<li>{$LOOP_COUNT}/{$LOOP_TOTAL} : {$ID} {$TITLE}</li>
{/loop}
</ul>
<p>PAGE 1000</p>
<ul>
{loop type="category" name="catloopwithpagination1000" limit="2" page="1000"}
<li>{$LOOP_COUNT}/{$LOOP_TOTAL} : {$ID} {$TITLE}</li>
{/loop}
{elseloop rel="catloopwithpagination1000"}
NO RESULTS
{/elseloop}
</ul>
</div>
<div>
<p>Some pagination with page choice</p>
{assign var=current_page value=2}
<p>PAGE {$current_page} :</p>
<ul>
{loop type="category" name="catloopwithpaginationchoice" limit="2" page="{$current_page}"}
<li>{$LOOP_COUNT}/{$LOOP_TOTAL} : {$ID} {$TITLE}</li>
{/loop}
</ul>
<p>page choice</p>
{pageloop rel="catloopwithpaginationchoice"}
{if ${PAGE} != {$current_page}}
{if {$PAGE} > {$current_page}-10 AND {$PAGE} < {$current_page}+10}
{$PAGE}
{/if}
{if {$PAGE} == {$current_page}-10 OR {$PAGE} == {$current_page}+10}
...
{/if}
{if ({$PAGE} < {$current_page}-10 OR {$PAGE} > {$current_page}+10) AND ({$PAGE}%10 == 0 OR ${PAGE} == {$LAST} OR ${PAGE} == 1)}
{$PAGE}
{/if}
{else}
{ {$PAGE} }
{/if}
{if {$PAGE} != {$LAST}}
-
{/if}
{/pageloop}
</div>
{include file="includes/footer.html"}

View File

@@ -1,49 +0,0 @@
{include file="includes/header.html"}
<h1>{intl l='Please login'}</h1>
{form name="thelia.customer.login" }
<form action="{url path='/customer/login'}" method="post" {form_enctype form=$form}>
{*
The field below are not par of the Login form, it defines view to render if the form cannot be validated
*}
<input type="hidden" name="view" value="login" /> {* the view to return to if the form cannot be validated *}
{*
This field is common to all BaseForm instances (thus, this one), and defines
the URL the customer is redirected to once the form has been successfully
processed
*}
{form_field form=$form field='success_url'}
<input type="hidden" name="{$name}" value="{navigate to="return_to"}" /> {* the url the user is redirected to on login success *}
{/form_field}
{*
The form error status and the form error messages are defined in Customer action,
and passed back to the form plugin through the ParserContext.
*}
{if $0form_error}<div class="alert alert-error">{$form_error_message}</div>{/if}
{form_hidden_fields form=$form}
{form_field form=$form field="email"}
{if $error}{$message}{/if}
<label>{intl l="Your e-mail address"}: </label><input type="email" name="{$name}" {$attr} value="{$value}"><br />
{/form_field}
{form_field form=$form field='password'}
<label>{intl l="Your password"}: </label><input type="password" name="{$name}" {$attr} value="{$value}"> <br />
{/form_field}
{form_field form=$form field='remember_me'}
<label class="checkbox"> <input type="checkbox" name="{$name}" value="{$value}" {$attr} {if $options.checked}checked="checked"{/if}/> {intl l='Remember me'}</label>
{/form_field}
<button type="submit">{intl l='Login'}</button>
</form>
{/form}
{include file='includes/footer.html'}

View File

@@ -1,6 +0,0 @@
{check_auth context="front" roles="CUSTOMER" login_tpl="login"}
{$page_title="{intl l='My Account'}"}
{include file="includes/header.html"}
{include file="includes/footer.html"}

View File

@@ -1,94 +0,0 @@
{assign var=category_current_page value={$smarty.get.category_page|default:1}}
<h1>Pagination</h1>
<h2>Categories</h2>
<div style="border: solid 1px; padding: 20px;">
{loop name="cat" type="category" page="{$category_current_page}" limit="2"}
<h2>{$LOOP_COUNT} - {$TITLE}</h2>
<h3>Products :</h3>
<div style="border: solid 1px; padding: 20px;">
{assign var=this_product_getter value="product_`$ID`_page"}
{assign var=product_current_page value={$smarty.get.$this_product_getter|default:1}}
<ul>
{loop name="prod" type="product" category="$ID" page="{$product_current_page}" limit="2"}
<li>
{$ID}:{$REF}
</li>
{/loop}
</ul>
</div>
<p>{$TITLE} page choice</p>
{pageloop rel="prod"}
{if $PAGE != $product_current_page}
<a href="index_dev.php?view=pagination&category_page={$category_current_page}&{$this_product_getter}={$PAGE}">{$PAGE}</a>
{else}
{$PAGE}
{/if}
{if $PAGE != $LAST}
-
{/if}
{/pageloop}
{/loop}
</div>
<p>categories page choice</p>
{pageloop rel="cat"}
{if $PAGE != $category_current_page}
<a href="index_dev.php?view=pagination&category_page={$PAGE}">{$PAGE}</a>
{else}
{$PAGE}
{/if}
{if $PAGE != $LAST}
-
{/if}
{/pageloop}
<hr>
Pagination before loop
<hr>
{assign var=product_current_page value={$smarty.get.$this_product_getter|default:1}}
{capture name="prod2"}
{loop name="prod2" type="product" page="{$product_current_page}" limit="2"}
<li>
{$ID}:{$REF}
</li>
{/loop}
{/capture}
{pageloop rel="prod2"}
{if ${PAGE} != {$product_current_page}}
<a href="index_dev.php?view=pagination&category_page={$category_current_page}&{$this_product_getter}={$PAGE}">{$PAGE}</a>
{else}
{$PAGE}
{/if}
{if $PAGE != $LAST}
-
{/if}
{/pageloop}
{$smarty.capture.prod2}
{pageloop rel="prod2"}
{if ${PAGE} != {$product_current_page}}
<a href="index_dev.php?view=pagination&category_page={$category_current_page}&{$this_product_getter}={$PAGE}">{$PAGE}</a>
{else}
{$PAGE}
{/if}
{if $PAGE != $LAST}
-
{/if}
{/pageloop}

View File

@@ -1,94 +0,0 @@
{*include file="includes/header.html"*}
Here you are : {navigate to="current"}<br />
From : {navigate to="return_to"}<br />
Index : {navigate to="index"}<br />
<h1>Product page</h1>
{ifloop rel="product"}
{loop type="product" name="product" current="true"}
<div style="border: dashed 2px red; padding: 20px; margin: 10px;">
<h2>PRODUCT ({$ID}) : {$REF}</h2>
<h3>{$TITLE}</h3>
<p>{$DESCRIPTION}</p>
<p>Starting by {$BEST_PRICE} {currency attr="symbol"} HT (TAX : {$BEST_PRICE_TAX} ; {$BEST_TAXED_PRICE} {currency attr="symbol"} TTC)</p>
{ifloop rel="acc"}
<h4>Accessories</h4>
<ul>
{loop name="acc" type="accessory" product="$ID" order="accessory"}
<li><a href="{$URL}">{$REF}</a></li>
{/loop}
</ul>
{/ifloop}
{elseloop rel="acc"}
<h4>No accessory</h4>
{/elseloop}
{ifloop rel="prod_ass_cont"}
<h4>Associated Content</h4>
<ul>
{loop name="prod_ass_cont" type="associated_content" product="$ID" order="associated_content"}
<li>{$TITLE}</li>
{/loop}
</ul>
{/ifloop}
{elseloop rel="prod_ass_cont"}
<h4>No associated content</h4>
{/elseloop}
{ifloop rel="ft"}
<h4>Features</h4>
<ul>
{assign var=current_product value=$ID}
{loop name="ft" type="feature" order="manual" product="$ID"}
<li>
<strong>{$TITLE}</strong> :
{loop name="ft_v" type="feature_value" product="{$current_product}" feature="$ID"}
{$TITLE} / {$PERSONAL_VALUE}
{/loop}
</li>
{/loop}
</ul>
{/ifloop}
{elseloop rel="ft"}
<h4>No feature</h4>
{/elseloop}
<h4>Product sale elements</h4>
{assign var=current_product value=$ID}
{loop name="pse" type="product_sale_elements" product="$ID" order="promo,min_price"}
<div style="border: solid 2px darkorange; padding: 5px; margin: 5px;">
{loop name="combi" type="attribute_combination" product_sale_elements="$ID"}
{$ATTRIBUTE_TITLE} = {$ATTRIBUTE_AVAILABILITY_TITLE}<br />
{/loop}
<br />{$WEIGHT} g
<br /><strong>{if $IS_PROMO == 1} {$PROMO_PRICE} {currency attr="symbol"} HT // TAX : {$PROMO_PRICE_TAX} ; {$TAXED_PROMO_PRICE} {currency attr="symbol"} TTC (instead of {$PRICE} HT // TAX : {$PRICE_TAX} ; {$TAXED_PRICE} {currency attr="symbol"} TTC){else} {$PRICE} {currency attr="symbol"} HT // TAX : {$PRICE_TAX} ; {$TAXED_PRICE} {currency attr="symbol"} TTC{/if}</strong>
<br /><br />
Add
<select>
{for $will=1 to $QUANTITY}
<option>{$will}</option>
{/for}
</select>
to my cart
</ul>
</div>
{/loop}
</div>
{/loop}
{/ifloop}
{elseloop rel="product"}
<h2>Produit introuvable !</h2>
{/elseloop}
{*include file="includes/footer.html"*}

View File

@@ -1,11 +0,0 @@
<ul>
{loop name="car" type="category"}
<li>
<ul>
{loop name="product" type="product" category="$ID"}
<li>{$REF}</li>
{/loop}
</ul>
</li>
{/loop}
</ul>

193
templates/pdf/delivery.html Normal file
View File

@@ -0,0 +1,193 @@
<!--
THELIA - Modèle de bon de livraison
Pour plus d'information sur les possibilités de mise en page, merci de consulter
la documentation de html2pdf: http://html2pdf.fr/
-->
<style type="text/css">
<!--
table {
border-collapse: collapse;
width: 100%;
}
td,th {
padding: 1.5mm;
border: 0.2mm solid #333;
}
th {
background-color: #D83C46;
color: #fff;
text-align: center;
font-weight: normal;
}
td.total {
background-color: #ccc;
font-weight: bold;
}
-->
</style>
<page backtop="10mm" backleft="10mm" backright="10mm" backbottom="10mm">
<page_header>
</page_header>
<page_footer>
<table>
<col style="width: 80%; padding: 3mm; border: none; text-align: center;" />
<col style="width: 20%; padding: 3mm; border: none; text-align: right;" />
<tbody>
<tr>
<td><!-- Insérer ici les mentions légales --></td>
<td>{intl l="page"} [[page_cu]]/[[page_nb]]</td>
</tr>
</tbody>
</table>
</page_footer>
{loop name="order.invoice" type="order" id=$order_id customer="*"}
{loop name="currency.order" type="currency" id=$CURRENCY}
{assign "orderCurrency" $SYMBOL}
{/loop}
<!-- En-tete du document -->
<table style="padding-bottom: 5mm;">
<col style="width:50%; padding: 0; border: none;" />
<col style="width:50%; padding: 0; border: none;" />
<tr>
<!-- A gauche: informations sur le BL -->
<td valign="bottom">
<div style="text-align: center; padding-bottom: 5mm;">
<h1 style="font-size: 5mm;">
{config key="company_name"}
<!-- Vous pouvez remplacer #VARIABLE(nomsite) par le nom de votre entreprise -->
</h1>
<!--
<p> Vous pouvez insérer ici l'adresse de votre entreprise</p>
-->
<h2 style="font-size: 5mm;">{intl l='Delivery module'}<br />{$DELIVERY_REF}</h2>
</div>
<table style="width: 80%">
<col style="width:50%;text-align: center;" />
<col style="width:50%;text-align: center;" />
<tr>
<th>{intl l="invoice ref"}</th>
<th>{intl l="invoice date"}</th>
</tr>
<tr>
<td>{$REF}</td>
<td>{format_date date=$INVOICE_DATE}</td>
</tr>
</table>
<table style="width: 80%; margin-top: 3mm;">
<col style="width:50%;text-align: center;" />
<col style="width:50%;text-align: center;" />
<tr>
<th>{intl l="invoice"} </th>
<th>{intl l="customer number"}</th>
</tr>
<tr>
<td>{$INVOICE_REF}</td>
<td>{loop type="customer" name="customer.invoice" id=$CUSTOMER current="0"}{$REF}{/loop}</td>
</tr>
</table>
</td>
<!-- A droite: adresses de livraison et de facturation -->
<td valign="bottom">
<table style="padding-bottom: 5mm;">
<tr>
<th style="width: 100%; text-align: left;">{intl l="delivery address"}</th>
</tr>
<tr>
<td>
{loop type="order_address" name="delivery_address" id=$DELIVERY_ADDRESS}
{loop type="title" name="order-invoice-address-title" id=$TITLE}{$LONG}{/loop}{$FIRSTNAME} {$LASTNAME}<br />
{$ADDRESS1} {$ADDRESS2} {$ADDRESS3}<br />
{$ZIPCODE} {$COUNTRY}<br/>
{loop type="country" name="country_delivery" id=$COUNTRY}{$TITLE}{/loop}
{/loop}
</td>
</tr>
</table>
<table>
<tr>
<th style="width: 100%; text-align: left;">{intl l="invoice address"}</th>
</tr>
<tr>
<td>
{loop type="order_address" name="delivery_address" id=$INVOICE_ADDRESS}
{loop type="title" name="order-invoice-address-title" id=$TITLE}{$LONG}{/loop}{$FIRSTNAME} {$LASTNAME}<br />
{$ADDRESS1} {$ADDRESS2} {$ADDRESS3}<br />
{$ZIPCODE} {$COUNTRY}<br/>
{loop type="country" name="country_delivery" id=$COUNTRY}{$TITLE}{/loop}
{/loop}
</td>
</tr>
</table>
</td>
</tr>
</table>
<!-- Liste des articles -->
<table>
<col style="width: 20%;" />
<col style="width: 65%;" />
<col style="width: 15%; text-align: right" />
<thead>
<tr>
<th style="text-align: center;">{intl l="Ref"}</th>
<th style="text-align: center;">{intl l="product"}</th>
<th style="text-align: center;">{intl l="Quantity"}</th>
</tr>
</thead>
<tbody>
{loop type="order_product" name="order-products" order=$ID}
<tr>
<td>{$REF}</td>
<td>{$TITLE}</td>
<td>{$QUANTITY}</td>
</tr>
{/loop}
</tbody>
</table>
<!-- Mode de livraison -->
<table style="width: 100%; margin-top: 5mm;">
<col style="width: 20%;" />
<col style="width: 80%;" />
<tbody>
<tr>
<th>{intl l="delivery module"}</th>
<td>{loop name="delivery-module" type="module" id=$DELIVERY_MODULE}{$TITLE}{/loop}</td>
</tr>
</tbody>
</table>
{/loop}
</page>

233
templates/pdf/invoice.html Normal file
View File

@@ -0,0 +1,233 @@
<!--
THELIA - Modèle de facture
Pour plus d'information sur les possibilités de mise en page, merci de consulter
la documentation de html2pdf: http://html2pdf.fr/
-->
<style type="text/css">
<!--
table {
border-collapse: collapse;
width: 100%;
}
td,th {
padding: 1.5mm;
border: 0.2mm solid #333;
}
th {
background-color: #D83C46;
color: #fff;
text-align: center;
font-weight: normal;
}
td.total {
background-color: #ccc;
font-weight: bold;
}
-->
</style>
<page backtop="10mm" backleft="10mm" backright="10mm" backbottom="10mm">
<page_header>
</page_header>
<page_footer>
<table>
<col style="width: 80%; padding: 3mm; border: none; text-align: center;" />
<col style="width: 20%; padding: 3mm; border: none; text-align: right;" />
<tbody>
<tr>
<td><!-- Insérer ici les mentions légales --></td>
<td>{intl l="Page"} [[page_cu]]/[[page_nb]]</td>
</tr>
</tbody>
</table>
</page_footer>
{loop name="order.invoice" type="order" id=$order_id customer="*"}
{loop name="currency.order" type="currency" id=$CURRENCY}
{assign "orderCurrency" $SYMBOL}
{/loop}
<table style="padding-bottom: 5mm;">
<tr>
<td style="width:50%; padding: 0; border: none;" valign="bottom">
<div style="text-align: center; padding-bottom: 10mm;">
<h1>{config key="company_name"}</h1>
<p><!-- Insérer ici l'adresse de votre entreprise --></p>
<h2>{intl l="invoice"} {$INVOICE_REF}</h2>
</div>
<table style="width: 100%">
<tr>
<th>{intl l="invoice ref"}</th>
<th>{intl l="customer number"}</th>
<th>{intl l="invoice date"}</th>
</tr>
<tr>
<td>{$REF}</td>
<td>{loop type="customer" name="customer.invoice" id=$CUSTOMER current="0"}{$REF}{/loop}</td>
<td>{format_date date=$INVOICE_DATE}</td>
</tr>
</table>
</td>
<td style="width:50%; padding: 0; border: none;" valign="bottom">
<table style="padding-bottom: 5mm;">
<tr>
<th style="width: 100%; text-align: left;">{intl l="delivery address"}</th>
</tr>
<tr>
<td>
{loop type="order_address" name="delivery_address" id=$DELIVERY_ADDRESS}
{loop type="title" name="order-invoice-address-title" id=$TITLE}{$LONG}{/loop}{$FIRSTNAME} {$LASTNAME}<br />
{$ADDRESS1} {$ADDRESS2} {$ADDRESS3}<br />
{$ZIPCODE} {$COUNTRY}<br/>
{loop type="country" name="country_delivery" id=$COUNTRY}{$TITLE}{/loop}
{/loop}
</td>
</tr>
</table>
<table>
<tr>
<th style="width: 100%; text-align: left;">{intl l="invoice address"}</th>
</tr>
<tr>
<td>
{loop type="order_address" name="delivery_address" id=$INVOICE_ADDRESS}
{loop type="title" name="order-invoice-address-title" id=$TITLE}{$LONG}{/loop}{$FIRSTNAME} {$LASTNAME}<br />
{$ADDRESS1} {$ADDRESS2} {$ADDRESS3}<br />
{$ZIPCODE} {$COUNTRY}<br/>
{loop type="country" name="country_delivery" id=$COUNTRY}{$TITLE}{/loop}
{/loop}
</td>
</tr>
</table>
</td>
</tr>
</table>
<table>
<col style="width: 38%;" />
<col style="width: 15%;" />
<col style="width: 15%; text-align: right" />
<col style="width: 12%; text-align: right" />
<col style="width: 5%; text-align: right" />
<col style="width: 15%; text-align: right" />
<thead>
<tr>
<th style="text-align: center;">{intl l="Product"}</th>
<th style="text-align: center;">{intl l="Unit. price"}</th>
<th style="text-align: center;">{intl l="Tax"}</th>
<th style="text-align: center;">{intl l="Unit taxed price"}</th>
<th style="text-align: center;">{intl l="Quantity"}</th>
<th style="text-align: center;">{intl l="Taxed total"}</th>
</tr>
</thead>
<tbody>
{loop type="order_product" name="order-products" order=$ID}
{if $WAS_IN_PROMO == 1}
{assign "realPrice" $PROMO_PRICE}
{assign "realTax" $PROMO_PRICE_TAX}
{assign "realTaxedPrice" $TAXED_PROMO_PRICE}
{else}
{assign "realPrice" $PRICE}
{assign "realTax" $PRICE_TAX}
{assign "realTaxedPrice" $TAXED_PRICE}
{/if}
<tr>
<td>
{$TITLE}
{ifloop rel="combinations"}
{loop type="order_product_attribute_combination" name="combinations" order_product=$ID}
{$ATTRIBUTE_TITLE} - {$ATTRIBUTE_AVAILABILITY_TITLE}<br>
{/loop}
{/ifloop}
</td>
<td>{$orderCurrency} {$realPrice}</td>
<td>{$orderCurrency} {$realTax}</td>
<td>{$orderCurrency} {$realTaxedPrice}</td>
<td>{$QUANTITY}</td>
<td>{$orderCurrency} {$realTaxedPrice * $QUANTITY}</td>
</tr>
{/loop}
</tbody>
</table>
<!-- Pied du tableau -->
<table>
<col style="width: 65%;" />
<col style="width: 35%;" />
<tr>
<td style="padding: 0; padding-top: 5mm; border: none;">
<table style="width: 90%; padding-bottom: 5mm;">
<col style="width: 35%; text-align: right;" />
<col style="width: 65%;" />
<tbody>
<tr>
<th>{intl l="Payment module"}</th>
<td>{loop name="payment-module" type="module" id=$PAYMENT_MODULE}{$TITLE}{/loop}</td>
</tr>
<tr>
<th>{intl l="delivery module"}</th>
<td>{loop name="delivery-module" type="module" id=$DELIVERY_MODULE}{$TITLE}{/loop}</td>
</tr>
</tbody>
</table>
</td>
<td valign="top" style="padding: 0;padding-top: 5mm; border: none;">
<table style="padding-bottom: 5mm;">
<col style="width: 58%; text-align: right;" />
<col style="width: 42%; text-align: right;" />
<tbody>
<tr>
<td>{intl l="Total without tax"}</td>
<td>{$orderCurrency} {$TOTAL_AMOUNT}</td>
</tr>
<tr>
<td>{intl l="Total with tax"}</td>
<td>{$orderCurrency} {$TOTAL_TAXED_AMOUNT - $POSTAGE}</td>
</tr>
<tr>
<td>{intl l="Postage"}</td>
<td>{$orderCurrency} {$POSTAGE}</td>
</tr>
<tr>
<td class="total">{intl l="Total"}</td>
<td class="total">{$orderCurrency} {$TOTAL_TAXED_AMOUNT}</td>
</tr>
</tbody>
</table>
</td>
</tr>
</table>
{/loop}
</page>

1
travis.php.ini Normal file
View File

@@ -0,0 +1 @@
post_max_size = 20M

0
local/cache/.gitkeep → web/cache/.gitkeep vendored Executable file → Normal file
View File

View File

@@ -42,11 +42,11 @@ $request = Request::createFromGlobals();
$thelia = new Thelia("dev", true);
if ( false === in_array($request->getClientIp(), $trustedIp)) {
// Redirect 401 Unauthorized
$response = new Response('Unauthorized', 401);
$response = Response::create('Forbidden', 403)->send();
$thelia->terminate($request, $response);
} else {
$response = $thelia->handle($request)->prepare($request)->send();
$thelia->terminate($request, $response);
}
$response = $thelia->handle($request)->prepare($request)->send();
$thelia->terminate($request, $response);