@@ -4,7 +4,6 @@ php:
|
||||
- 5.4
|
||||
- 5.5
|
||||
- 5.6
|
||||
- hhvm
|
||||
|
||||
env:
|
||||
- DB_USER=root
|
||||
@@ -23,5 +22,4 @@ before_script:
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- php: hhvm
|
||||
- php: 5.6
|
||||
|
||||
15
CHANGELOG.md
@@ -11,6 +11,21 @@
|
||||
- Fix bugs on customer change password form and module "order by title"
|
||||
- Add the ability to place a firewall on forms. To use this in a module, extend Thelia\Form\FirewallForm instead of BaseForm
|
||||
- Add Exports and Imports management
|
||||
- Default front office template:
|
||||
- Display enhancement
|
||||
- Optimization of the uses of Thelia loops to gain performances and consistency
|
||||
- Optimization for SEO : meta description fallback, ti>>>>>>> Updated Changelog
|
||||
tle on category page, ...
|
||||
- new PSE layout in product page, attributes are separated
|
||||
- Support of 'check-available-stock' config variable
|
||||
- Terms and conditions agreement is now in the order process
|
||||
- Default pdf template:
|
||||
- Added list of amount by tax rule
|
||||
- Display enhancement
|
||||
- Added legal information about the store
|
||||
- Demo:
|
||||
- Support for brand
|
||||
- Added folders and contents data.
|
||||
|
||||
#2.0.2
|
||||
- Coupon UI has been redesigned.
|
||||
|
||||
@@ -92,7 +92,7 @@ class Product extends BaseAction implements EventSubscriberInterface
|
||||
|
||||
$product
|
||||
->setDispatcher($event->getDispatcher())
|
||||
|
||||
->setRef($event->getRef())
|
||||
->setLocale($event->getLocale())
|
||||
->setTitle($event->getTitle())
|
||||
->setDescription($event->getDescription())
|
||||
@@ -269,9 +269,9 @@ class Product extends BaseAction implements EventSubscriberInterface
|
||||
$product = $event->getProduct();
|
||||
|
||||
// Delete all product feature relations
|
||||
if(null !== $featureProducts = FeatureProductQuery::create()->findByProductId($product->getId())){
|
||||
if (null !== $featureProducts = FeatureProductQuery::create()->findByProductId($product->getId())) {
|
||||
/** @var \Thelia\Model\FeatureProduct $featureProduct */
|
||||
foreach($featureProducts as $featureProduct){
|
||||
foreach ($featureProducts as $featureProduct) {
|
||||
$eventDelete = new FeatureProductDeleteEvent($product->getId(), $featureProduct->getFeatureId());
|
||||
|
||||
$event->getDispatcher()->dispatch(TheliaEvents::PRODUCT_FEATURE_DELETE_VALUE, $eventDelete);
|
||||
|
||||
@@ -121,8 +121,7 @@ class CartContainsCategories extends ConditionAbstract
|
||||
{
|
||||
return $this->translator->trans(
|
||||
'Cart contains categories condition',
|
||||
[],
|
||||
'condition'
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -133,8 +132,7 @@ class CartContainsCategories extends ConditionAbstract
|
||||
{
|
||||
$toolTip = $this->translator->trans(
|
||||
'The coupon applies if the cart contains at least one product of the selected categories',
|
||||
[],
|
||||
'condition'
|
||||
[]
|
||||
);
|
||||
|
||||
return $toolTip;
|
||||
@@ -167,7 +165,7 @@ class CartContainsCategories extends ConditionAbstract
|
||||
'At least one of cart products categories is %op% <strong>%categories_list%</strong>', [
|
||||
'%categories_list%' => $catStrList,
|
||||
'%op%' => $i18nOperator
|
||||
], 'condition'
|
||||
]
|
||||
);
|
||||
|
||||
return $toolTip;
|
||||
|
||||
@@ -113,8 +113,7 @@ class CartContainsProducts extends ConditionAbstract
|
||||
{
|
||||
return $this->translator->trans(
|
||||
'Cart contains specific products',
|
||||
[],
|
||||
'condition'
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -125,8 +124,7 @@ class CartContainsProducts extends ConditionAbstract
|
||||
{
|
||||
$toolTip = $this->translator->trans(
|
||||
'The coupon applies if the cart contains at least one product of the specified product list',
|
||||
[],
|
||||
'condition'
|
||||
[]
|
||||
);
|
||||
|
||||
return $toolTip;
|
||||
@@ -159,7 +157,7 @@ class CartContainsProducts extends ConditionAbstract
|
||||
'Cart contains at least a product %op% <strong>%products_list%</strong>', [
|
||||
'%products_list%' => $prodStrList,
|
||||
'%op%' => $i18nOperator
|
||||
], 'condition'
|
||||
]
|
||||
);
|
||||
|
||||
return $toolTip;
|
||||
|
||||
@@ -104,8 +104,7 @@ class ForSomeCustomers extends ConditionAbstract
|
||||
{
|
||||
return $this->translator->trans(
|
||||
'For one ore more customers',
|
||||
[],
|
||||
'condition'
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -116,8 +115,7 @@ class ForSomeCustomers extends ConditionAbstract
|
||||
{
|
||||
$toolTip = $this->translator->trans(
|
||||
'The coupon applies to some customers only',
|
||||
[],
|
||||
'condition'
|
||||
[]
|
||||
);
|
||||
|
||||
return $toolTip;
|
||||
@@ -150,7 +148,7 @@ class ForSomeCustomers extends ConditionAbstract
|
||||
'Customer is %op% <strong>%customer_list%</strong>', [
|
||||
'%customer_list%' => $custStrList,
|
||||
'%op%' => $i18nOperator
|
||||
], 'condition'
|
||||
]
|
||||
);
|
||||
|
||||
return $toolTip;
|
||||
|
||||
@@ -50,8 +50,7 @@ class MatchBillingCountries extends AbstractMatchCountries
|
||||
{
|
||||
return $this->translator->trans(
|
||||
'Billing country',
|
||||
[],
|
||||
'condition'
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -61,9 +60,8 @@ class MatchBillingCountries extends AbstractMatchCountries
|
||||
public function getToolTip()
|
||||
{
|
||||
$toolTip = $this->translator->trans(
|
||||
'The coupon applies to the selected delivery countries',
|
||||
[],
|
||||
'condition'
|
||||
'The coupon applies to the selected billing countries',
|
||||
[]
|
||||
);
|
||||
|
||||
return $toolTip;
|
||||
@@ -75,14 +73,14 @@ class MatchBillingCountries extends AbstractMatchCountries
|
||||
'Only if order billing country is %op% <strong>%countries_list%</strong>', [
|
||||
'%countries_list%' => $cntryStrList,
|
||||
'%op%' => $i18nOperator
|
||||
], 'condition'
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
protected function getFormLabel()
|
||||
{
|
||||
return $this->translator->trans(
|
||||
'Billing coutry is', [], 'condition'
|
||||
'Billing country is', []
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,8 +50,7 @@ class MatchDeliveryCountries extends AbstractMatchCountries
|
||||
{
|
||||
return $this->translator->trans(
|
||||
'Delivery country',
|
||||
[],
|
||||
'condition'
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -62,8 +61,7 @@ class MatchDeliveryCountries extends AbstractMatchCountries
|
||||
{
|
||||
$toolTip = $this->translator->trans(
|
||||
'The coupon applies to the selected delivery countries',
|
||||
[],
|
||||
'condition'
|
||||
[]
|
||||
);
|
||||
|
||||
return $toolTip;
|
||||
@@ -75,14 +73,14 @@ class MatchDeliveryCountries extends AbstractMatchCountries
|
||||
'Only if order shipping country is %op% <strong>%countries_list%</strong>', [
|
||||
'%countries_list%' => $cntryStrList,
|
||||
'%op%' => $i18nOperator
|
||||
], 'condition'
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
protected function getFormLabel()
|
||||
{
|
||||
return $this->translator->trans(
|
||||
'Delivery coutry is', [], 'condition'
|
||||
'Delivery country is', []
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,8 +68,7 @@ class MatchForEveryone extends ConditionAbstract
|
||||
{
|
||||
return $this->translator->trans(
|
||||
'Unconditional usage',
|
||||
[],
|
||||
'condition'
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -80,8 +79,7 @@ class MatchForEveryone extends ConditionAbstract
|
||||
{
|
||||
$toolTip = $this->translator->trans(
|
||||
'This condition is always true',
|
||||
[],
|
||||
'condition'
|
||||
[]
|
||||
);
|
||||
|
||||
return $toolTip;
|
||||
@@ -94,8 +92,7 @@ class MatchForEveryone extends ConditionAbstract
|
||||
{
|
||||
$toolTip = $this->translator->trans(
|
||||
'Unconditionnal usage',
|
||||
[],
|
||||
'condition'
|
||||
[]
|
||||
);
|
||||
|
||||
return $toolTip;
|
||||
|
||||
@@ -120,8 +120,7 @@ class MatchForTotalAmount extends ConditionAbstract
|
||||
{
|
||||
return $this->translator->trans(
|
||||
'Cart total amount',
|
||||
[],
|
||||
'condition'
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -132,8 +131,7 @@ class MatchForTotalAmount extends ConditionAbstract
|
||||
{
|
||||
$toolTip = $this->translator->trans(
|
||||
'Check the total Cart amount in the given currency',
|
||||
[],
|
||||
'condition'
|
||||
[]
|
||||
);
|
||||
|
||||
return $toolTip;
|
||||
@@ -155,8 +153,7 @@ class MatchForTotalAmount extends ConditionAbstract
|
||||
'%operator%' => $i18nOperator,
|
||||
'%amount%' => $this->values[self::CART_TOTAL],
|
||||
'%currency%' => $this->values[self::CART_CURRENCY]
|
||||
),
|
||||
'condition'
|
||||
)
|
||||
);
|
||||
|
||||
return $toolTip;
|
||||
@@ -199,7 +196,7 @@ class MatchForTotalAmount extends ConditionAbstract
|
||||
{
|
||||
$labelPrice = $this->facade
|
||||
->getTranslator()
|
||||
->trans('Cart total amount is', [], 'condition');
|
||||
->trans('Cart total amount is', []);
|
||||
|
||||
$html = $this->drawBackOfficeBaseInputsText($labelPrice, self::CART_TOTAL);
|
||||
|
||||
|
||||
@@ -103,8 +103,7 @@ class MatchForXArticles extends ConditionAbstract
|
||||
{
|
||||
return $this->translator->trans(
|
||||
'Cart item count',
|
||||
[],
|
||||
'condition'
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -115,8 +114,7 @@ class MatchForXArticles extends ConditionAbstract
|
||||
{
|
||||
$toolTip = $this->translator->trans(
|
||||
'The cart item count should match the condition',
|
||||
[],
|
||||
'condition'
|
||||
[]
|
||||
);
|
||||
|
||||
return $toolTip;
|
||||
@@ -136,8 +134,7 @@ class MatchForXArticles extends ConditionAbstract
|
||||
array(
|
||||
'%operator%' => $i18nOperator,
|
||||
'%quantity%' => $this->values[self::CART_QUANTITY]
|
||||
),
|
||||
'condition'
|
||||
)
|
||||
);
|
||||
|
||||
return $toolTip;
|
||||
@@ -164,7 +161,7 @@ class MatchForXArticles extends ConditionAbstract
|
||||
{
|
||||
$labelQuantity = $this->facade
|
||||
->getTranslator()
|
||||
->trans('Cart item count is', [], 'condition');
|
||||
->trans('Cart item count is');
|
||||
|
||||
$html = $this->drawBackOfficeBaseInputsText($labelQuantity, self::CART_QUANTITY);
|
||||
|
||||
|
||||
@@ -103,8 +103,7 @@ class StartDate extends ConditionAbstract
|
||||
{
|
||||
return $this->translator->trans(
|
||||
'Start date',
|
||||
[],
|
||||
'condition'
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -115,8 +114,7 @@ class StartDate extends ConditionAbstract
|
||||
{
|
||||
$toolTip = $this->translator->trans(
|
||||
'The coupon is valid after a given date',
|
||||
[],
|
||||
'condition'
|
||||
[]
|
||||
);
|
||||
|
||||
return $toolTip;
|
||||
|
||||
@@ -55,57 +55,49 @@ abstract class Operators
|
||||
case self::INFERIOR:
|
||||
$ret = $translator->trans(
|
||||
'Less than',
|
||||
[],
|
||||
'condition'
|
||||
[]
|
||||
);
|
||||
break;
|
||||
case self::INFERIOR_OR_EQUAL:
|
||||
$ret = $translator->trans(
|
||||
'Less than or equals',
|
||||
[],
|
||||
'condition'
|
||||
[]
|
||||
);
|
||||
break;
|
||||
case self::EQUAL:
|
||||
$ret = $translator->trans(
|
||||
'Equal to',
|
||||
[],
|
||||
'condition'
|
||||
[]
|
||||
);
|
||||
break;
|
||||
case self::SUPERIOR_OR_EQUAL:
|
||||
$ret = $translator->trans(
|
||||
'Greater than or equals',
|
||||
[],
|
||||
'condition'
|
||||
[]
|
||||
);
|
||||
break;
|
||||
case self::SUPERIOR:
|
||||
$ret = $translator->trans(
|
||||
'Greater than',
|
||||
[],
|
||||
'condition'
|
||||
[]
|
||||
);
|
||||
break;
|
||||
case self::DIFFERENT:
|
||||
$ret = $translator->trans(
|
||||
'Not equal to',
|
||||
[],
|
||||
'condition'
|
||||
[]
|
||||
);
|
||||
break;
|
||||
case self::IN:
|
||||
$ret = $translator->trans(
|
||||
'In',
|
||||
[],
|
||||
'condition'
|
||||
[]
|
||||
);
|
||||
break;
|
||||
case self::OUT:
|
||||
$ret = $translator->trans(
|
||||
'Not in',
|
||||
[],
|
||||
'condition'
|
||||
[]
|
||||
);
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -43,7 +43,7 @@ return array(
|
||||
'Available shipping zones' => 'Available shipping zones',
|
||||
'Bad tax list JSON' => 'Bad tax list JSON',
|
||||
'Billing country' => 'Billing country',
|
||||
'Billing coutry is' => 'Le pays de facturation est',
|
||||
'Billing country is' => 'Billing country is',
|
||||
'Brand' => 'Brand',
|
||||
'Brand / Supplier' => 'Brand / Supplier',
|
||||
'Brand name' => 'Brand name',
|
||||
@@ -87,7 +87,7 @@ return array(
|
||||
'Default product sale element' => 'Default product sale element',
|
||||
'Deleting %obj% for %id% with parent id %parentId%' => 'Deleting %obj% for %id% with parent id %parentId%',
|
||||
'Delivery country' => 'Delivery country',
|
||||
'Delivery coutry is' => 'Le pays de livraison est',
|
||||
'Delivery country is' => 'Delivery country is',
|
||||
'Delivery module ID not found' => 'Delivery module ID not found',
|
||||
'Detailed description' => 'Detailed description',
|
||||
'Disabled' => 'Disabled',
|
||||
@@ -169,6 +169,7 @@ return array(
|
||||
'Missing \'rel\' parameter in page loop' => 'Missing \'rel\' parameter in page loop',
|
||||
'Missing \'type\' parameter in loop arguments' => 'Missing \'type\' parameter in loop arguments',
|
||||
'Missing \'type\' parameter in {count} loop arguments' => 'Missing \'type\' parameter in {count} loop arguments',
|
||||
'Missing or invalid data: %s' => 'Missing or invalid data: %s',
|
||||
'Module ID not found' => 'Module ID not found',
|
||||
'Name' => 'Name',
|
||||
'Name *' => 'Name *',
|
||||
@@ -302,12 +303,12 @@ return array(
|
||||
'The coupon applies if the cart contains at least one product of the selected categories' => 'The coupon applies if the cart contains at least one product of the selected categories',
|
||||
'The coupon applies if the cart contains at least one product of the specified product list' => 'The coupon applies if the cart contains at least one product of the specified product list',
|
||||
'The coupon applies to some customers only' => 'The coupon applies to some customers only',
|
||||
'The coupon applies to the selected billing countries' => 'The coupon applies to the selected billing countries',
|
||||
'The coupon applies to the selected delivery countries' => 'Ce code promo s\'applique seulement aux pays de facturation sélectionnés',
|
||||
'The coupon is valid after a given date' => 'Le code promo est valide seulement à partir d\'une certaine date',
|
||||
'The detailed description.' => 'The detailed description.',
|
||||
'The image which replaces an undefined country flag (%file) was not found. Please check unknown-flag-path configuration variable, and check that the image exists.' => 'The image which replaces an undefined country flag (%file) was not found. Please check unknown-flag-path configuration variable, and check that the image exists.',
|
||||
'The loop name \'%name\' is already defined in %className class' => 'The loop name \'%name\' is already defined in %className class',
|
||||
'The product sale elements reference %ref doesn\'t exist' => 'The product sale elements reference %ref doesn\'t exist',
|
||||
'This brand is online' => 'This brand is online',
|
||||
'This category is online.' => 'This category is online.',
|
||||
'This condition is always true' => 'This condition is always true',
|
||||
@@ -355,6 +356,7 @@ return array(
|
||||
'Value *' => 'Value *',
|
||||
'Warnings' => 'Warnings',
|
||||
'Weight' => 'Weight',
|
||||
'Wrong form method, %s expected.' => 'Wrong form method, %s expected.',
|
||||
'Yes, I have a password :' => 'Yes, I have a password :',
|
||||
'You are already registered!' => 'You are already registered!',
|
||||
'You don\'t need to use commas or other punctuations.' => 'You don\'t need to use commas or other punctuations.',
|
||||
@@ -366,8 +368,10 @@ return array(
|
||||
'date format' => 'date format',
|
||||
'decimal separator' => 'Séparateur décimal',
|
||||
'delivery module %s is not a Thelia\Module\DeliveryModuleInterface' => 'delivery module %s is not a Thelia\Module\DeliveryModuleInterface',
|
||||
'hour(s)' => 'hour(s)',
|
||||
'language locale' => 'language locale',
|
||||
'mailing system modification' => 'mailing system modification',
|
||||
'minute(s)' => 'minute(s)',
|
||||
'password confirmation is not the same as password field' => 'password confirmation is not the same as password field',
|
||||
'password must be composed of at least 4 characters' => 'password must be composed of at least 4 characters',
|
||||
'payment module %s is not a Thelia\Module\PaymentModuleInterface' => 'payment module %s is not a Thelia\Module\PaymentModuleInterface',
|
||||
@@ -376,6 +380,4 @@ return array(
|
||||
'this product id does not exists : %d' => 'this product id does not exists : %d',
|
||||
'thousands separator' => 'Séparateur de milliers',
|
||||
'time format' => 'time format',
|
||||
'hour(s)' => 'hour(s)',
|
||||
'minute(s)' => 'minute(s)',
|
||||
);
|
||||
|
||||
@@ -21,7 +21,7 @@ return array(
|
||||
'A variable with name "%name" already exists.' => 'Une variable avec le nom "%name" existe déjà.',
|
||||
'Activate logs only for these IP Addresses' => 'Activer les logs uniquement pour ces adresses IP',
|
||||
'Activate logs only for these files' => 'Activer les logs uniquement pour ces fichiers',
|
||||
'Add to all product templates' => 'Ajouter à tous les templates produit',
|
||||
'Add to all product templates' => 'Ajouter à tous les gabarits produit',
|
||||
'Additional address' => 'Adresse complémentaire',
|
||||
'Address ID not found' => 'ID de l\'adresse non trouvé',
|
||||
'Address Line 2' => 'Adresse suite',
|
||||
@@ -42,8 +42,8 @@ return array(
|
||||
'Available quantity *' => 'Quantité disponible *',
|
||||
'Available shipping zones' => 'Zones de livraison disponibles',
|
||||
'Bad tax list JSON' => 'Mauvais JSON de la liste des taxes',
|
||||
'Billing country' => 'Pays de livraison',
|
||||
'Billing coutry is' => 'Pays de facturation',
|
||||
'Billing country' => 'Pays de facturation',
|
||||
'Billing country is' => 'Le pays de facturation est',
|
||||
'Brand' => 'Marque',
|
||||
'Brand / Supplier' => 'Marque / Fournisseur',
|
||||
'Brand name' => 'Nom de la marque',
|
||||
@@ -87,7 +87,7 @@ return array(
|
||||
'Default product sale element' => 'Product Sale Element par défaut',
|
||||
'Deleting %obj% for %id% with parent id %parentId%' => 'Suppresion de %obj%, ID %id%, ID parent %parentId%',
|
||||
'Delivery country' => 'Pays de livraison',
|
||||
'Delivery coutry is' => 'Le pays de livraison est',
|
||||
'Delivery country is' => 'Le pays de livraison est',
|
||||
'Delivery module ID not found' => 'Id du module de livraison non trouvé',
|
||||
'Detailed description' => 'Description détaillée',
|
||||
'Disabled' => 'Désactivé',
|
||||
@@ -169,6 +169,7 @@ return array(
|
||||
'Missing \'rel\' parameter in page loop' => 'Le paramètre obligatoire \'rel\' est absent des paramètre de la boucle \'page\'',
|
||||
'Missing \'type\' parameter in loop arguments' => 'Le paramètre obligatoire \'type\' est absent des paramètre de la boucle ',
|
||||
'Missing \'type\' parameter in {count} loop arguments' => 'Le paramètre obligatoire \'type\' est absent des paramètre de la boucle {count}',
|
||||
'Missing or invalid data: %s' => 'Donnée manquante ou non valide : %s',
|
||||
'Module ID not found' => 'Id du module non trouvé',
|
||||
'Name' => 'Nom',
|
||||
'Name *' => 'Nom *',
|
||||
@@ -235,7 +236,7 @@ return array(
|
||||
'Product price including taxes' => 'Prix du produit taxes incluses',
|
||||
'Product reference *' => 'Référence du produit *',
|
||||
'Product sale element ID *' => 'Product sale element ID *',
|
||||
'Product template' => 'Template du produit',
|
||||
'Product template' => 'Gabarit du produit',
|
||||
'Product title *' => 'Titre du produit *',
|
||||
'ProductSaleElement modification' => 'Modification de ProductSaleElement.',
|
||||
'Profile' => 'Profil',
|
||||
@@ -257,8 +258,8 @@ return array(
|
||||
'Replace current image by this file' => 'Remplacer l\'image courante par ce fichier',
|
||||
'Rewriten URL' => 'URL re-écrite',
|
||||
'Rotated Text File' => 'Rotation du fichier texte',
|
||||
'Sale price excluding taxes' => 'Prix de vente Hors Taxes',
|
||||
'Sale price including taxes' => 'Prix de vente Toutes Taxes Comprises',
|
||||
'Sale price excluding taxes' => 'Prix promo HT',
|
||||
'Sale price including taxes' => 'Prix promo TTC',
|
||||
'Saving %obj% for %parentName% parent id %parentId%' => 'Enregistrement de %obj% pour %parentName% ID parent %parentId%',
|
||||
'Select the brand logo' => 'Logo de la marque',
|
||||
'Select the brand logo amongst the brand images' => 'Choisissez le logo de la marque parmis les images associées à cette marque',
|
||||
@@ -291,7 +292,7 @@ return array(
|
||||
'Tax list is not valid JSON' => 'Le JSON de la liste des taxes n\'est pas valide',
|
||||
'Tax rule ID not found' => 'ID de la règle de taxe non trouvé',
|
||||
'Tax rule for this product *' => 'Règle de taxe pour ce produit *',
|
||||
'Template Name *' => 'Nom du template *',
|
||||
'Template Name *' => 'Nom du gabarit *',
|
||||
'Template file %file cannot be found.' => 'Le fichier %file n\'a pas été trouvé dans le template. ',
|
||||
'Text File' => 'Fichier texte',
|
||||
'Text Message' => 'Message au format texte',
|
||||
@@ -302,12 +303,12 @@ return array(
|
||||
'The coupon applies if the cart contains at least one product of the selected categories' => 'Le code promo est valable si le panier contient/ne contient pas des produits appartenant aux catégories sélectionnées',
|
||||
'The coupon applies if the cart contains at least one product of the specified product list' => 'Le code promo est valable si le panier contient/ne contient pas au moins un des produits selectionnés',
|
||||
'The coupon applies to some customers only' => 'Ce code promo est valable pour les clients sélectionnés',
|
||||
'The coupon applies to the selected billing countries' => 'Ce code promo s\'applique pour les pays de facturation sélectionnés',
|
||||
'The coupon applies to the selected delivery countries' => 'Ce code promo s\'applique pour les pays de livraison sélectionnés',
|
||||
'The coupon is valid after a given date' => 'Le code promo est valide à partir de cette date',
|
||||
'The detailed description.' => 'La description détaillée',
|
||||
'The image which replaces an undefined country flag (%file) was not found. Please check unknown-flag-path configuration variable, and check that the image exists.' => 'L\'image qui remplace un drapeau de pays manquant (%file) n\'a pas été trouvée. Merci de vérifier la variable de configuration unknown-flag-path.',
|
||||
'The loop name \'%name\' is already defined in %className class' => 'La boucle \'%name\' est déjà définir dans la classe %className',
|
||||
'The product sale elements reference %ref doesn\'t exist' => 'La déclinaison de produit %ref n\'existe pas',
|
||||
'This brand is online' => 'Cette marque est en ligne',
|
||||
'This category is online.' => 'Cette catégorie est en ligne.',
|
||||
'This condition is always true' => 'Cette condition est troujours vérifiée',
|
||||
@@ -330,7 +331,7 @@ return array(
|
||||
'This product is on sale' => 'Ce produit est en promo',
|
||||
'This product is online' => 'Ce produit est en ligne',
|
||||
'This product_sale_elements_id does not exists for this product : %d' => 'Le product_sale_elements_id n\'existe pas pour ce produit : %d',
|
||||
'This template is in use in some of your products, and cannot be deleted. Delete it from all your products and try again.' => 'Ce template est utilisé par des produits, et ne peut être supprimé. Retirez-le de tous vos produits, et ré-essayez.',
|
||||
'This template is in use in some of your products, and cannot be deleted. Delete it from all your products and try again.' => 'Ce gabarit est utilisé par des produits, et ne peut être supprimé. Retirez-le de tous vos produits, et ré-essayez.',
|
||||
'This value should not be blank.' => 'Cette valeur ne doit pas être vide.',
|
||||
'Timeout' => 'Délai d\'attente expiré',
|
||||
'Title' => 'Titre',
|
||||
@@ -355,6 +356,7 @@ return array(
|
||||
'Value *' => 'Valeur *',
|
||||
'Warnings' => 'Avertissements',
|
||||
'Weight' => 'Poids',
|
||||
'Wrong form method, %s expected.' => 'Méthode HTTP invalide : %s attendu.',
|
||||
'Yes, I have a password :' => 'Oui, j\'ai un mot de passe :',
|
||||
'You are already registered!' => 'Vous êtes déjà enregistré !',
|
||||
'You don\'t need to use commas or other punctuations.' => 'Vous n\'avez pas besoin d\'utiliser de virgules ou d\'autres signes de ponctuation',
|
||||
@@ -366,8 +368,10 @@ return array(
|
||||
'date format' => 'Format de date',
|
||||
'decimal separator' => 'Séparateur décimal',
|
||||
'delivery module %s is not a Thelia\Module\DeliveryModuleInterface' => 'le module de livraison %s n\'est pas un Thelia\Module\DeliveryModuleInterface',
|
||||
'hour(s)' => 'heure(s)',
|
||||
'language locale' => 'Langue locale',
|
||||
'mailing system modification' => 'Modification du système d\'envoi de mail.',
|
||||
'minute(s)' => 'minute(s)',
|
||||
'password confirmation is not the same as password field' => 'le mot de passe de confirmation n\'est pas le même que le champ mot de passe',
|
||||
'password must be composed of at least 4 characters' => 'le mot de passe doit être composé d\'au moins 4 caractères',
|
||||
'payment module %s is not a Thelia\Module\PaymentModuleInterface' => 'Le module de paiement %s n\'est pas une instance de Thelia\Module\PaymentModuleInterface ',
|
||||
@@ -376,6 +380,4 @@ return array(
|
||||
'this product id does not exists : %d' => 'l\'id du produit %d n\'existe pas',
|
||||
'thousands separator' => 'Séparateur des milliers',
|
||||
'time format' => 'Format d\'heure',
|
||||
'hour(s)' => 'heure(s)',
|
||||
'minute(s)' => 'minute(s)',
|
||||
);
|
||||
|
||||
@@ -358,21 +358,22 @@ class FileController extends BaseAdminController
|
||||
|
||||
$file->setLocale($data['locale']);
|
||||
|
||||
if (isset($data['title'])) {
|
||||
if (array_key_exists('title', $data)) {
|
||||
$file->setTitle($data['title']);
|
||||
}
|
||||
if (isset($data['chapo'])) {
|
||||
if (array_key_exists('chapo', $data)) {
|
||||
$file->setChapo($data['chapo']);
|
||||
}
|
||||
if (isset($data['description'])) {
|
||||
if (array_key_exists('description', $data)) {
|
||||
$file->setDescription($data['description']);
|
||||
}
|
||||
if (array_key_exists('postscriptum', $data)) {
|
||||
$file->setPostscriptum($data['postscriptum']);
|
||||
}
|
||||
|
||||
if (isset($data['file'])) {
|
||||
$file->setFile($data['file']);
|
||||
}
|
||||
if (isset($data['postscriptum'])) {
|
||||
$file->setPostscriptum($data['postscriptum']);
|
||||
}
|
||||
|
||||
$event->setModel($file);
|
||||
$event->setOldModel($oldFile);
|
||||
|
||||
@@ -158,6 +158,7 @@ class ProductController extends AbstractSeoCrudController
|
||||
|
||||
$changeEvent
|
||||
->setLocale($formData['locale'])
|
||||
->setRef($formData['ref'])
|
||||
->setTitle($formData['title'])
|
||||
->setChapo($formData['chapo'])
|
||||
->setDescription($formData['description'])
|
||||
|
||||
@@ -218,13 +218,13 @@ abstract class BaseController extends ContainerAware
|
||||
if ($form->get("error_message")->getData() != null) {
|
||||
$errorMessage = $form->get("error_message")->getData();
|
||||
} else {
|
||||
$errorMessage = sprintf("Missing or invalid data: %s", $this->getErrorMessages($form));
|
||||
$errorMessage = sprintf($this->getTranslator()->trans("Missing or invalid data: %s"), $this->getErrorMessages($form));
|
||||
}
|
||||
|
||||
throw new FormValidationException($errorMessage);
|
||||
}
|
||||
} else {
|
||||
throw new FormValidationException(sprintf("Wrong form method, %s expected.", $expectedMethod));
|
||||
throw new FormValidationException(sprintf($this->getTranslator()->trans("Wrong form method, %s expected."), $expectedMethod));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -220,7 +220,6 @@ class Coupon extends BaseI18nLoop implements PropelSearchLoopInterface
|
||||
// which adds a product to the cart.
|
||||
$discount = $couponManager->isInUse() ? $couponManager->exec() : 0;
|
||||
|
||||
|
||||
$loopResultRow
|
||||
->set("ID", $coupon->getId())
|
||||
->set("IS_TRANSLATED", $coupon->getVirtualColumn('IS_TRANSLATED'))
|
||||
|
||||
@@ -179,6 +179,8 @@ class Product extends BaseI18nLoop implements PropelSearchLoopInterface, SearchL
|
||||
$search->innerJoinProductSaleElements('pse');
|
||||
$search->addJoinCondition('pse', '`pse`.IS_DEFAULT=1');
|
||||
|
||||
$search->innerJoinProductSaleElements('pse_count');
|
||||
|
||||
$priceJoin = new Join();
|
||||
$priceJoin->addExplicitCondition(ProductSaleElementsTableMap::TABLE_NAME, 'ID', 'pse', ProductPriceTableMap::TABLE_NAME, 'PRODUCT_SALE_ELEMENTS_ID', 'price');
|
||||
$priceJoin->setJoinType(Criteria::LEFT_JOIN);
|
||||
@@ -396,6 +398,8 @@ class Product extends BaseI18nLoop implements PropelSearchLoopInterface, SearchL
|
||||
$search->withColumn('`pse`.WEIGHT', 'weight');
|
||||
$search->withColumn('`pse`.EAN_CODE', 'ean_code');
|
||||
|
||||
$search->withColumn('COUNT(`pse_count`.ID)', 'pse_count');
|
||||
|
||||
$orders = $this->getOrder();
|
||||
|
||||
foreach ($orders as $order) {
|
||||
@@ -518,6 +522,7 @@ class Product extends BaseI18nLoop implements PropelSearchLoopInterface, SearchL
|
||||
->set("TAXED_PROMO_PRICE" , $taxedPromoPrice)
|
||||
->set("IS_PROMO" , $product->getVirtualColumn('is_promo'))
|
||||
->set("IS_NEW" , $product->getVirtualColumn('is_new'))
|
||||
->set("PSE_COUNT" , $product->getVirtualColumn('pse_count'))
|
||||
;
|
||||
|
||||
|
||||
@@ -571,8 +576,10 @@ class Product extends BaseI18nLoop implements PropelSearchLoopInterface, SearchL
|
||||
$search->where(" CASE WHEN NOT ISNULL(`requested_locale_i18n`.ID) THEN `requested_locale_i18n`.`TITLE` ELSE `default_locale_i18n`.`TITLE` END ".Criteria::LIKE." ?", "%".$title."%", \PDO::PARAM_STR);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* number of pse
|
||||
$search->innerJoinProductSaleElements('pse_count');
|
||||
$search->withColumn('COUNT(`pse_count`.ID)', 'pse_count');
|
||||
*/
|
||||
|
||||
$category = $this->getCategory();
|
||||
$categoryDefault = $this->getCategoryDefault();
|
||||
@@ -985,8 +992,8 @@ class Product extends BaseI18nLoop implements PropelSearchLoopInterface, SearchL
|
||||
->set("BEST_PRICE" , $price)
|
||||
->set("BEST_PRICE_TAX" , $taxedPrice - $price)
|
||||
->set("BEST_TAXED_PRICE" , $taxedPrice)
|
||||
->set("IS_PROMO" , $product->getVirtualColumn('is_promo'))
|
||||
->set("IS_NEW" , $product->getVirtualColumn('is_new'))
|
||||
->set("IS_PROMO" , $product->getVirtualColumn('is_promo'))
|
||||
->set("IS_NEW" , $product->getVirtualColumn('is_new'))
|
||||
;
|
||||
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ 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\Base\BrandQuery;
|
||||
use Thelia\Model\Brand;
|
||||
use Thelia\Model\ConfigQuery;
|
||||
use Thelia\Model\CategoryQuery;
|
||||
use Thelia\Model\ContentQuery;
|
||||
@@ -139,12 +141,12 @@ class DataAccessFunctions extends AbstractSmartyPlugin
|
||||
|
||||
public function brandDataAccess($params, &$smarty)
|
||||
{
|
||||
$contentId = $this->request->get('brand_id');
|
||||
$brandId = $this->request->get('brand_id');
|
||||
|
||||
if ($contentId !== null) {
|
||||
if ($brandId !== null) {
|
||||
|
||||
$search = ContentQuery::create()
|
||||
->filterById($contentId);
|
||||
$search = BrandQuery::create()
|
||||
->filterById($brandId);
|
||||
|
||||
return $this->dataAccessWithI18n("Brand", $params, $search);
|
||||
}
|
||||
|
||||
@@ -217,8 +217,9 @@ class TheliaLoop extends AbstractSmartyPlugin
|
||||
{
|
||||
//Block the smarty interpretation in the elseloop
|
||||
if ($content === null) {
|
||||
if ( ! $this->checkEmptyLoop($params)){
|
||||
if ( ! $this->checkEmptyLoop($params)) {
|
||||
$repeat = false;
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,7 +182,7 @@ abstract class CouponAbstract implements CouponInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @param true $perCustomerUsageCount
|
||||
* @param true $perCustomerUsageCount
|
||||
* @return $this
|
||||
*/
|
||||
public function setPerCustomerUsageCount($perCustomerUsageCount)
|
||||
@@ -428,8 +428,8 @@ abstract class CouponAbstract implements CouponInterface
|
||||
*
|
||||
* This method should be overriden to be useful.
|
||||
*
|
||||
* @param string $fieldName
|
||||
* @param string $fieldValue
|
||||
* @param string $fieldName
|
||||
* @param string $fieldValue
|
||||
* @return mixed
|
||||
* @throws \InvalidArgumentException if the field value is not valid.
|
||||
*/
|
||||
@@ -509,7 +509,8 @@ abstract class CouponAbstract implements CouponInterface
|
||||
// Does nothing. Override this function as needed.
|
||||
}
|
||||
|
||||
public function isInUse() {
|
||||
public function isInUse()
|
||||
{
|
||||
return in_array(
|
||||
$this->code,
|
||||
$this->facade->getRequest()->getSession()->getConsumedCoupons()
|
||||
|
||||
@@ -294,7 +294,7 @@ class FreeProduct extends AbstractRemoveOnProducts
|
||||
{
|
||||
return $this->facade
|
||||
->getTranslator()
|
||||
->trans('Free product when buying one or more selected products', array(), 'coupon');
|
||||
->trans('Free product when buying one or more selected products', array());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -306,8 +306,7 @@ class FreeProduct extends AbstractRemoveOnProducts
|
||||
->getTranslator()
|
||||
->trans(
|
||||
'This coupon adds a free product to the cart if one of the selected products is in the cart.',
|
||||
array(),
|
||||
'coupon'
|
||||
array()
|
||||
);
|
||||
|
||||
return $toolTip;
|
||||
|
||||
@@ -36,7 +36,7 @@ class RemoveAmountOnAttributeValues extends AbstractRemoveOnAttributeValues
|
||||
{
|
||||
return $this->facade
|
||||
->getTranslator()
|
||||
->trans('Fixed amount discount for selected attribute values', array(), 'coupon');
|
||||
->trans('Fixed amount discount for selected attribute values', array());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -48,8 +48,7 @@ class RemoveAmountOnAttributeValues extends AbstractRemoveOnAttributeValues
|
||||
->getTranslator()
|
||||
->trans(
|
||||
'This coupon subtracts the specified amount from the order total for each product which uses the selected attribute values. If the discount is greater than the total order, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.',
|
||||
array(),
|
||||
'coupon'
|
||||
array()
|
||||
);
|
||||
|
||||
return $toolTip;
|
||||
|
||||
@@ -37,7 +37,7 @@ class RemoveAmountOnCategories extends AbstractRemoveOnCategories
|
||||
{
|
||||
return $this->facade
|
||||
->getTranslator()
|
||||
->trans('Fixed amount discount for selected categories', array(), 'coupon');
|
||||
->trans('Fixed amount discount for selected categories', array());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,8 +49,7 @@ class RemoveAmountOnCategories extends AbstractRemoveOnCategories
|
||||
->getTranslator()
|
||||
->trans(
|
||||
'This coupon subtracts the specified amount from the order total for each product which belongs to the selected categories. If the discount is greater than the total order, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.',
|
||||
array(),
|
||||
'coupon'
|
||||
array()
|
||||
);
|
||||
|
||||
return $toolTip;
|
||||
|
||||
@@ -41,7 +41,7 @@ class RemoveAmountOnProducts extends AbstractRemoveOnProducts
|
||||
{
|
||||
return $this->facade
|
||||
->getTranslator()
|
||||
->trans('Fixed amount discount for selected products', array(), 'coupon');
|
||||
->trans('Fixed amount discount for selected products', array());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,8 +53,7 @@ class RemoveAmountOnProducts extends AbstractRemoveOnProducts
|
||||
->getTranslator()
|
||||
->trans(
|
||||
'This coupon subtracts the specified amount from the order total for each selected product. If the discount is greater than the total order, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.',
|
||||
array(),
|
||||
'coupon'
|
||||
array()
|
||||
);
|
||||
|
||||
return $toolTip;
|
||||
|
||||
@@ -42,7 +42,7 @@ class RemovePercentageOnAttributeValues extends AbstractRemoveOnAttributeValues
|
||||
{
|
||||
return $this->facade
|
||||
->getTranslator()
|
||||
->trans('Percentage discount for selected attribute values', array(), 'coupon');
|
||||
->trans('Percentage discount for selected attribute values', array());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,8 +54,7 @@ class RemovePercentageOnAttributeValues extends AbstractRemoveOnAttributeValues
|
||||
->getTranslator()
|
||||
->trans(
|
||||
'This coupon subtracts from the order total the specified percentage of each product price which uses the selected attribute values. If the discount is greater than the total order, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.',
|
||||
array(),
|
||||
'coupon'
|
||||
array()
|
||||
);
|
||||
|
||||
return $toolTip;
|
||||
|
||||
@@ -39,7 +39,7 @@ class RemovePercentageOnCategories extends AbstractRemoveOnCategories
|
||||
{
|
||||
return $this->facade
|
||||
->getTranslator()
|
||||
->trans('Percentage discount for selected categories', array(), 'coupon');
|
||||
->trans('Percentage discount for selected categories', array());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -51,8 +51,7 @@ class RemovePercentageOnCategories extends AbstractRemoveOnCategories
|
||||
->getTranslator()
|
||||
->trans(
|
||||
'This coupon subtracts from the order total a percentage of the price of each product which belongs to the selected categories. If the discount is greater than the total order, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.',
|
||||
array(),
|
||||
'coupon'
|
||||
array()
|
||||
);
|
||||
|
||||
return $toolTip;
|
||||
|
||||
@@ -46,7 +46,7 @@ class RemovePercentageOnProducts extends AbstractRemoveOnProducts
|
||||
{
|
||||
return $this->facade
|
||||
->getTranslator()
|
||||
->trans('Percentage discount for selected products', array(), 'coupon');
|
||||
->trans('Percentage discount for selected products', array());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,8 +58,7 @@ class RemovePercentageOnProducts extends AbstractRemoveOnProducts
|
||||
->getTranslator()
|
||||
->trans(
|
||||
'This coupon subtracts from the order total the specified percentage of each selected product price. If the discount is greater than the total order, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.',
|
||||
array(),
|
||||
'coupon'
|
||||
array()
|
||||
);
|
||||
|
||||
return $toolTip;
|
||||
|
||||
@@ -38,7 +38,7 @@ class RemoveXAmount extends AbstractRemove
|
||||
{
|
||||
return $this->facade
|
||||
->getTranslator()
|
||||
->trans('Fixed Amount Discount', array(), 'coupon');
|
||||
->trans('Fixed Amount Discount', array());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,8 +50,7 @@ class RemoveXAmount extends AbstractRemove
|
||||
->getTranslator()
|
||||
->trans(
|
||||
'This coupon will subtracts a set amount from the total cost of an order. If the discount is greater than the total order corst, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.',
|
||||
array(),
|
||||
'coupon'
|
||||
array()
|
||||
);
|
||||
|
||||
return $toolTip;
|
||||
|
||||
@@ -41,7 +41,7 @@ class RemoveXPercent extends AbstractRemove
|
||||
{
|
||||
return $this->facade
|
||||
->getTranslator()
|
||||
->trans('Remove X percent to total cart', array(), 'coupon');
|
||||
->trans('Remove X percent to total cart', array());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,8 +53,7 @@ class RemoveXPercent extends AbstractRemove
|
||||
->getTranslator()
|
||||
->trans(
|
||||
'This coupon will offert a flat percentage off a shopper\'s entire order (not applied to shipping costs or tax rates). If the discount is greater than the total order corst, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.',
|
||||
array(),
|
||||
'coupon'
|
||||
array()
|
||||
);
|
||||
|
||||
return $toolTip;
|
||||
|
||||
@@ -86,17 +86,8 @@ class CustomerCreateForm extends AddressCreateForm
|
||||
"for" => "newsletter"
|
||||
),
|
||||
"required" => false
|
||||
))
|
||||
// Add terms & conditions
|
||||
->add("agreed", "checkbox", array(
|
||||
"constraints" => array(
|
||||
new Constraints\True(array("message" => Translator::getInstance()->trans("Please accept the Terms and conditions in order to register.")))
|
||||
),
|
||||
"label"=>"Test",
|
||||
"label_attr" => array(
|
||||
"for" => "agreed"
|
||||
)
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
public function verifyPasswordField($value, ExecutionContextInterface $context)
|
||||
|
||||
@@ -43,9 +43,7 @@ class CustomerProfileUpdateForm extends CustomerCreateForm
|
||||
->remove("country")
|
||||
// Remove Login Information
|
||||
->remove("password")
|
||||
->remove("password_confirm")
|
||||
// Remove Terms & conditions
|
||||
->remove("agreed");
|
||||
->remove("password_confirm");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -50,6 +50,16 @@ class OrderPayment extends FirewallForm
|
||||
)
|
||||
))
|
||||
)
|
||||
))
|
||||
// Add terms & conditions
|
||||
->add("agreed", "checkbox", array(
|
||||
"constraints" => array(
|
||||
new Constraints\True(array("message" => Translator::getInstance()->trans("Please accept the Terms and conditions in order to register.")))
|
||||
),
|
||||
"label"=>"Agreed",
|
||||
"label_attr" => array(
|
||||
"for" => "agreed"
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@@ -22,17 +22,15 @@ class ProductCreationForm extends BaseForm
|
||||
{
|
||||
protected function buildForm($change_mode = false)
|
||||
{
|
||||
$ref_constraints = array(new NotBlank());
|
||||
|
||||
if (! $change_mode) {
|
||||
$ref_constraints[] = new Callback(array(
|
||||
"methods" => array(array($this, "checkDuplicateRef"))
|
||||
));
|
||||
}
|
||||
|
||||
$this->formBuilder
|
||||
->add("ref", "text", array(
|
||||
"constraints" => $ref_constraints,
|
||||
"constraints" => array(
|
||||
new NotBlank(),
|
||||
new Callback(array(
|
||||
"methods" => array(array($this, "checkDuplicateRef"))
|
||||
))
|
||||
),
|
||||
"label" => Translator::getInstance()->trans('Product reference *'),
|
||||
"label_attr" => array("for" => "ref")
|
||||
))
|
||||
|
||||
@@ -12,9 +12,12 @@
|
||||
|
||||
namespace Thelia\Form;
|
||||
|
||||
use Propel\Runtime\ActiveQuery\Criteria;
|
||||
use Symfony\Component\Validator\Constraints\GreaterThan;
|
||||
use Symfony\Component\Validator\Constraints\NotBlank;
|
||||
use Symfony\Component\Validator\ExecutionContextInterface;
|
||||
use Thelia\Core\Translation\Translator;
|
||||
use Thelia\Model\ProductQuery;
|
||||
|
||||
class ProductModificationForm extends ProductCreationForm
|
||||
{
|
||||
@@ -49,6 +52,23 @@ class ProductModificationForm extends ProductCreationForm
|
||||
$this->addStandardDescFields(array('title', 'locale'));
|
||||
}
|
||||
|
||||
public function checkDuplicateRef($value, ExecutionContextInterface $context)
|
||||
{
|
||||
$data = $context->getRoot()->getData();
|
||||
|
||||
$count = ProductQuery::create()
|
||||
->filterById($data['id'], Criteria::NOT_EQUAL)
|
||||
->filterByRef($value)->count();
|
||||
|
||||
if ($count > 0) {
|
||||
$context->addViolation(
|
||||
Translator::getInstance()->trans(
|
||||
"A product with reference %ref already exists. Please choose another reference.",
|
||||
array('%ref' => $value)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return "thelia_product_modification";
|
||||
|
||||
@@ -89,7 +89,6 @@ class Order extends BaseOrder
|
||||
return parent::preSave($con);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
||||
378
setup/import.php
@@ -20,6 +20,9 @@
|
||||
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* */
|
||||
/*************************************************************************************/
|
||||
use Thelia\Model\ContentFolderQuery;
|
||||
use Thelia\Model\ProductAssociatedContent;
|
||||
|
||||
if (php_sapi_name() != 'cli') {
|
||||
throw new \Exception('this script can only be launched with cli sapi');
|
||||
}
|
||||
@@ -43,9 +46,15 @@ try {
|
||||
$stmt = $con->prepare("SET foreign_key_checks = 1");
|
||||
$stmt->execute();
|
||||
|
||||
$categories = createCategories($con);
|
||||
$material = createMaterials($con);
|
||||
|
||||
$color = createColors($con);
|
||||
$brand = createBrand($con);
|
||||
$brands = createBrands($faker, $con);
|
||||
|
||||
$folders = createFolders($faker, $con);
|
||||
$contents = createContents($faker, $folders, $con);
|
||||
|
||||
$categories = createCategories($faker, $con);
|
||||
|
||||
echo "creating templates\n";
|
||||
$template = new \Thelia\Model\Template();
|
||||
@@ -67,11 +76,17 @@ try {
|
||||
|
||||
$ft
|
||||
->setTemplate($template)
|
||||
->setFeature($brand)
|
||||
->setFeature($material)
|
||||
->save($con);
|
||||
echo "end creating templates\n";
|
||||
|
||||
createProduct($faker, $categories, $template, $color, $brand, $con);
|
||||
createProduct($faker, $categories, $brands, $contents, $template, $color, $material, $con);
|
||||
|
||||
createCustomer($faker, $con);
|
||||
|
||||
// set some config key
|
||||
createConfig($faker, $folders, $contents, $con);
|
||||
|
||||
|
||||
$con->commit();
|
||||
} catch (Exception $e) {
|
||||
@@ -79,7 +94,7 @@ try {
|
||||
$con->rollBack();
|
||||
}
|
||||
|
||||
function createProduct($faker, $categories, $template, $attribute, $feature, $con)
|
||||
function createProduct($faker, $categories, $brands, $contents, $template, $attribute, $feature, $con)
|
||||
{
|
||||
echo "start creating products\n";
|
||||
$fileSystem = new \Symfony\Component\Filesystem\Filesystem();
|
||||
@@ -89,21 +104,27 @@ function createProduct($faker, $categories, $template, $attribute, $feature, $co
|
||||
$row++;
|
||||
if($row == 1) continue;
|
||||
$product = new \Thelia\Model\Product();
|
||||
$productCategories = explode(';', $data[13]);
|
||||
|
||||
$product
|
||||
->setRef($data[0])
|
||||
->setVisible(1)
|
||||
->setTaxRuleId(1)
|
||||
->setTemplate($template)
|
||||
;
|
||||
foreach ($productCategories as $productCategory) {
|
||||
|
||||
$productCategories = explode(';', $data[15]);
|
||||
foreach ($productCategories as $productCategory) {
|
||||
$productCategory = trim($productCategory);
|
||||
if (array_key_exists($productCategory, $categories)) {
|
||||
$product->addCategory($categories[$productCategory]);
|
||||
}
|
||||
}
|
||||
|
||||
$brand = $data[11];
|
||||
if (array_key_exists($brand, $brands)) {
|
||||
$product->setBrand($brands[$brand]);
|
||||
}
|
||||
|
||||
$product
|
||||
->setLocale('en_US')
|
||||
->setTitle($data[1])
|
||||
@@ -122,7 +143,7 @@ function createProduct($faker, $categories, $template, $attribute, $feature, $co
|
||||
->save($con);
|
||||
|
||||
// Set the position
|
||||
$product->setPosition($product->getNextPosition())->save();
|
||||
$product->setPosition($product->getNextPosition())->save($con);
|
||||
|
||||
$images = explode(';', $data[10]);
|
||||
|
||||
@@ -178,36 +199,115 @@ function createProduct($faker, $categories, $template, $attribute, $feature, $co
|
||||
$productSaleElements = $product->getProductSaleElementss()->getFirst();
|
||||
$productSaleElements->setIsDefault(1)->save($con);
|
||||
|
||||
$brand = $data[11];
|
||||
$featurAv = \Thelia\Model\FeatureAvI18nQuery::create()
|
||||
->filterByLocale('en_US')
|
||||
->filterByTitle($brand)
|
||||
->findOne($con);
|
||||
// associated content
|
||||
$associatedContents = explode(";", $data[14]);
|
||||
foreach ($associatedContents as $associatedContent) {
|
||||
$content = new ProductAssociatedContent();
|
||||
if ( ! array_key_exists($associatedContent, $contents)){
|
||||
continue;
|
||||
}
|
||||
|
||||
$featureProduct = new Thelia\Model\FeatureProduct();
|
||||
$featureProduct->setProduct($product)
|
||||
->setFeatureId($feature->getId())
|
||||
->setFeatureAvId($featurAv->getId())
|
||||
->save($con)
|
||||
;
|
||||
$content
|
||||
->setProduct($product)
|
||||
->setContent($contents[$associatedContent])
|
||||
->save($con)
|
||||
;
|
||||
}
|
||||
|
||||
// feature
|
||||
$features = explode(";", $data[13]);
|
||||
|
||||
foreach ($features as $aFeature) {
|
||||
$featurAv = \Thelia\Model\FeatureAvI18nQuery::create()
|
||||
->filterByLocale('en_US')
|
||||
->filterByTitle($aFeature)
|
||||
->findOne($con);
|
||||
|
||||
$featureProduct = new Thelia\Model\FeatureProduct();
|
||||
$featureProduct->setProduct($product)
|
||||
->setFeatureId($feature->getId())
|
||||
->setFeatureAvId($featurAv->getId())
|
||||
->save($con)
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
echo "end creating products\n";
|
||||
}
|
||||
|
||||
function createBrand($con)
|
||||
function createConfig($faker, $folders, $contents, $con){
|
||||
|
||||
// Store
|
||||
\Thelia\Model\ConfigQuery::write("store_name", "Thelia");
|
||||
\Thelia\Model\ConfigQuery::write("store_description", "E-commerce solution based on Symfony 2");
|
||||
\Thelia\Model\ConfigQuery::write("store_email", "Thelia");
|
||||
\Thelia\Model\ConfigQuery::write("store_address1", "5 rue Rochon");
|
||||
\Thelia\Model\ConfigQuery::write("store_city", "Clermont-Ferrrand");
|
||||
\Thelia\Model\ConfigQuery::write("store_phone", "+(33)444053102");
|
||||
\Thelia\Model\ConfigQuery::write("store_email", "contact@thelia.net");
|
||||
// Contents
|
||||
\Thelia\Model\ConfigQuery::write("information_folder_id", $folders['Information']->getId());
|
||||
\Thelia\Model\ConfigQuery::write("terms_conditions_content_id", $contents["Terms and Conditions"]->getId());
|
||||
}
|
||||
|
||||
function createCustomer($faker, $con){
|
||||
|
||||
echo "Creating customer\n";
|
||||
|
||||
//customer
|
||||
$customer = new Thelia\Model\Customer();
|
||||
$customer->createOrUpdate(
|
||||
1,
|
||||
"thelia",
|
||||
"thelia",
|
||||
"5 rue rochon",
|
||||
"",
|
||||
"",
|
||||
"0102030405",
|
||||
"0601020304",
|
||||
"63000",
|
||||
"Clermont-Ferrand",
|
||||
64,
|
||||
"test@thelia.net",
|
||||
"thelia"
|
||||
);
|
||||
for ($j = 0; $j <= 2; $j++) {
|
||||
$address = new Thelia\Model\Address();
|
||||
$address->setLabel($faker->text(20))
|
||||
->setTitleId(rand(1,3))
|
||||
->setFirstname($faker->firstname)
|
||||
->setLastname($faker->lastname)
|
||||
->setAddress1($faker->streetAddress)
|
||||
->setAddress2($faker->streetAddress)
|
||||
->setAddress3($faker->streetAddress)
|
||||
->setCellphone($faker->phoneNumber)
|
||||
->setPhone($faker->phoneNumber)
|
||||
->setZipcode($faker->postcode)
|
||||
->setCity($faker->city)
|
||||
->setCountryId(64)
|
||||
->setCustomer($customer)
|
||||
->save($con)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
function createMaterials($con)
|
||||
{
|
||||
echo "start creating brands feature\n";
|
||||
if (($handle = fopen(THELIA_ROOT . '/setup/import/brand.csv', "r")) !== FALSE) {
|
||||
echo "start creating materials feature\n";
|
||||
|
||||
$feature = null;
|
||||
$features = array();
|
||||
|
||||
if (($handle = fopen(THELIA_ROOT . '/setup/import/materials.csv', "r")) !== FALSE) {
|
||||
$row=0;
|
||||
$feature = new \Thelia\Model\Feature();
|
||||
$feature
|
||||
->setPosition(1)
|
||||
->setLocale('fr_FR')
|
||||
->setTitle('Marque')
|
||||
->setTitle('Matière')
|
||||
->setLocale('en_US')
|
||||
->setTitle('Brand');
|
||||
->setTitle('Material');
|
||||
|
||||
while (($data = fgetcsv($handle, 1000, ";")) !== FALSE) {
|
||||
$row++;
|
||||
$featureAv = new \Thelia\Model\FeatureAv();
|
||||
@@ -216,19 +316,83 @@ function createBrand($con)
|
||||
->setLocale('fr_FR')
|
||||
->setTitle($data[0])
|
||||
->setLocale('en_US')
|
||||
->setTitle($data[0]);
|
||||
$feature->addFeatureAv($featureAv);
|
||||
->setTitle($data[1]);
|
||||
//$featureAv->setFeature($feature);
|
||||
|
||||
$feature->addFeatureAv($featureAv);
|
||||
}
|
||||
|
||||
$feature->save($con);
|
||||
|
||||
fclose($handle);
|
||||
}
|
||||
echo "brands feature created successfully\n";
|
||||
echo "materials feature created successfully\n";
|
||||
|
||||
return $feature;
|
||||
}
|
||||
|
||||
function createCategories($con)
|
||||
|
||||
function createBrands($faker, $con)
|
||||
{
|
||||
echo "start creating brands\n";
|
||||
|
||||
$fileSystem = new \Symfony\Component\Filesystem\Filesystem();
|
||||
|
||||
$brands = array();
|
||||
if (($handle = fopen(THELIA_ROOT . '/setup/import/brand.csv', "r")) !== FALSE) {
|
||||
$row=0;
|
||||
while (($data = fgetcsv($handle, 1000, ";")) !== FALSE) {
|
||||
$row++;
|
||||
if ($row == 1) continue;
|
||||
|
||||
$brand = new \Thelia\Model\Brand();
|
||||
|
||||
$brand
|
||||
->setVisible(1)
|
||||
->setPosition($row-1)
|
||||
->setLocale('fr_FR')
|
||||
->setTitle(trim($data[0]))
|
||||
->setChapo($faker->text(20))
|
||||
->setDescription($faker->text(100))
|
||||
->setLocale('en_US')
|
||||
->setTitle(trim($data[0]))
|
||||
->setChapo($faker->text(20))
|
||||
->setDescription($faker->text(100))
|
||||
->save($con);
|
||||
|
||||
$brands[trim($data[0])] = $brand;
|
||||
|
||||
$images = explode(';', $data[1]);
|
||||
$logoId = null;
|
||||
foreach ($images as $image) {
|
||||
$image = trim($image);
|
||||
if(empty($image)) continue;
|
||||
$brandImage = new \Thelia\Model\BrandImage();
|
||||
$brandImage
|
||||
->setBrandId($brand->getId())
|
||||
->setFile($image)
|
||||
->save($con);
|
||||
if ($logoId === null) {
|
||||
$logoId = $brandImage->getId();
|
||||
}
|
||||
$fileSystem->copy(THELIA_ROOT . 'setup/import/images/'.$image, THELIA_ROOT . 'local/media/images/brand/'.$image, true);
|
||||
}
|
||||
|
||||
if ($logoId !== null){
|
||||
$brand->setLogoImageId($logoId);
|
||||
$brand->save($con);
|
||||
}
|
||||
|
||||
}
|
||||
fclose($handle);
|
||||
}
|
||||
echo "brands created successfully\n";
|
||||
|
||||
return $brands;
|
||||
}
|
||||
|
||||
|
||||
function createCategories($faker, $con)
|
||||
{
|
||||
echo "start creating categories\n";
|
||||
$categories = array();
|
||||
@@ -244,8 +408,12 @@ function createCategories($con)
|
||||
->setParent(0)
|
||||
->setLocale('fr_FR')
|
||||
->setTitle(trim($data[0]))
|
||||
->setChapo($faker->text(20))
|
||||
->setDescription($faker->text(100))
|
||||
->setLocale('en_US')
|
||||
->setTitle(trim($data[1]))
|
||||
->setChapo($faker->text(20))
|
||||
->setDescription($faker->text(100))
|
||||
->save($con);
|
||||
$categories[trim($data[1])] = $category;
|
||||
}
|
||||
@@ -256,6 +424,127 @@ function createCategories($con)
|
||||
return $categories;
|
||||
}
|
||||
|
||||
function createFolders($faker, $con)
|
||||
{
|
||||
echo "start creating folders\n";
|
||||
|
||||
$fileSystem = new \Symfony\Component\Filesystem\Filesystem();
|
||||
|
||||
$folders = array();
|
||||
if (($handle = fopen(THELIA_ROOT . '/setup/import/folders.csv', "r")) !== FALSE) {
|
||||
$row=0;
|
||||
while (($data = fgetcsv($handle, 1000, ";")) !== FALSE) {
|
||||
$row++;
|
||||
if ($row == 1) continue;
|
||||
|
||||
$folder = new \Thelia\Model\Folder();
|
||||
|
||||
$folder
|
||||
->setVisible(1)
|
||||
->setPosition($row-1)
|
||||
->setLocale('fr_FR')
|
||||
->setTitle(trim($data[0]))
|
||||
->setChapo($faker->text(20))
|
||||
->setDescription($faker->text(100))
|
||||
->setLocale('en_US')
|
||||
->setTitle(trim($data[1]))
|
||||
->setChapo($faker->text(20))
|
||||
->setDescription($faker->text(100))
|
||||
->save($con);
|
||||
|
||||
$folders[trim($data[1])] = $folder;
|
||||
|
||||
$images = explode(';', $data[6]);
|
||||
foreach ($images as $image) {
|
||||
$image = trim($image);
|
||||
if(empty($image)) continue;
|
||||
$folderImage = new \Thelia\Model\FolderImage();
|
||||
$folderImage
|
||||
->setFolderId($folder->getId())
|
||||
->setFile($image)
|
||||
->save($con);
|
||||
$fileSystem->copy(THELIA_ROOT . 'setup/import/images/'.$image, THELIA_ROOT . 'local/media/images/folder/'.$image, true);
|
||||
}
|
||||
}
|
||||
fclose($handle);
|
||||
}
|
||||
echo "Folders created successfully\n";
|
||||
|
||||
return $folders;
|
||||
}
|
||||
|
||||
|
||||
function createContents($faker, $folders, $con)
|
||||
{
|
||||
echo "start creating contents\n";
|
||||
|
||||
$fileSystem = new \Symfony\Component\Filesystem\Filesystem();
|
||||
|
||||
$contents = array();
|
||||
if (($handle = fopen(THELIA_ROOT . '/setup/import/contents.csv', "r")) !== FALSE) {
|
||||
$row=0;
|
||||
while (($data = fgetcsv($handle, 1000, ";")) !== FALSE) {
|
||||
$row++;
|
||||
if ($row == 1) continue;
|
||||
|
||||
$content = new \Thelia\Model\Content();
|
||||
|
||||
$content
|
||||
->setVisible(1)
|
||||
->setPosition($row-1)
|
||||
->setLocale('fr_FR')
|
||||
->setTitle(trim($data[0]))
|
||||
->setChapo($faker->text(20))
|
||||
->setDescription($faker->text(200))
|
||||
->setLocale('en_US')
|
||||
->setTitle(trim($data[1]))
|
||||
->setChapo($faker->text(20))
|
||||
->setDescription($faker->text(200));
|
||||
|
||||
// folder
|
||||
$contentFolders = explode(';', $data[7]);
|
||||
$defaultFolder = null;
|
||||
foreach ($contentFolders as $contentFolder) {
|
||||
$contentFolder = trim($contentFolder);
|
||||
if (array_key_exists($contentFolder, $folders)) {
|
||||
$content->addFolder($folders[$contentFolder]);
|
||||
if (null === $defaultFolder) {
|
||||
$defaultFolder = $folders[$contentFolder]->getId();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$content
|
||||
->getContentFolders()
|
||||
->getFirst()
|
||||
->setDefaultFolder(true)
|
||||
->save($con)
|
||||
;
|
||||
|
||||
$content->save($con);
|
||||
|
||||
$images = explode(';', $data[6]);
|
||||
foreach ($images as $image) {
|
||||
$image = trim($image);
|
||||
if(empty($image)) continue;
|
||||
$contentImage = new \Thelia\Model\ContentImage();
|
||||
$contentImage
|
||||
->setContentId($content->getId())
|
||||
->setFile($image)
|
||||
->save($con);
|
||||
$fileSystem->copy(THELIA_ROOT . 'setup/import/images/'.$image, THELIA_ROOT . 'local/media/images/content/'.$image, true);
|
||||
}
|
||||
|
||||
$contents[trim($data[1])] = $content;
|
||||
}
|
||||
fclose($handle);
|
||||
}
|
||||
echo "Contents created successfully\n";
|
||||
|
||||
return $contents;
|
||||
}
|
||||
|
||||
|
||||
function createColors($con)
|
||||
{
|
||||
echo "start creating colors attributes\n";
|
||||
@@ -291,6 +580,8 @@ function createColors($con)
|
||||
|
||||
function clearTables($con)
|
||||
{
|
||||
echo "Clearing tables\n";
|
||||
|
||||
$productAssociatedContent = Thelia\Model\ProductAssociatedContentQuery::create()
|
||||
->find($con);
|
||||
$productAssociatedContent->delete($con);
|
||||
@@ -339,6 +630,14 @@ function clearTables($con)
|
||||
->find($con);
|
||||
$attributeAv->delete($con);
|
||||
|
||||
$brand = Thelia\Model\BrandQuery::create()
|
||||
->find($con);
|
||||
$brand->delete($con);
|
||||
|
||||
$brand = Thelia\Model\BrandI18nQuery::create()
|
||||
->find($con);
|
||||
$brand->delete($con);
|
||||
|
||||
$category = Thelia\Model\CategoryQuery::create()
|
||||
->find($con);
|
||||
$category->delete($con);
|
||||
@@ -355,6 +654,22 @@ function clearTables($con)
|
||||
->find($con);
|
||||
$product->delete($con);
|
||||
|
||||
$folder = Thelia\Model\FolderQuery::create()
|
||||
->find($con);
|
||||
$folder->delete($con);
|
||||
|
||||
$folder = Thelia\Model\FolderI18nQuery::create()
|
||||
->find($con);
|
||||
$folder->delete($con);
|
||||
|
||||
$content = Thelia\Model\ContentQuery::create()
|
||||
->find($con);
|
||||
$content->delete($con);
|
||||
|
||||
$content = Thelia\Model\ContentI18nQuery::create()
|
||||
->find($con);
|
||||
$content->delete($con);
|
||||
|
||||
$accessory = Thelia\Model\AccessoryQuery::create()
|
||||
->find($con);
|
||||
$accessory->delete($con);
|
||||
@@ -368,4 +683,11 @@ function clearTables($con)
|
||||
$productPrice->delete($con);
|
||||
|
||||
\Thelia\Model\ProductImageQuery::create()->find($con)->delete($con);
|
||||
|
||||
$customer = Thelia\Model\CustomerQuery::create()
|
||||
->find($con);
|
||||
$customer->delete($con);
|
||||
|
||||
echo "Tables cleared with success\n";
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
"MILAN"
|
||||
"MAGIS"
|
||||
"OXYO"
|
||||
"OFFUS"
|
||||
"PLINK"
|
||||
"PARRY"
|
||||
"TOKO"
|
||||
"NAME";"LOGO"
|
||||
"MILAN";"BRAND-1.png"
|
||||
"MAGIS";"BRAND-2.png"
|
||||
"OXYO";"BRAND-3.png"
|
||||
"OFFUS";"BRAND-4.png"
|
||||
"PLINK";"BRAND-5.png"
|
||||
"PARRY";"BRAND-6.png"
|
||||
"TOKO";"BRAND-7.png"
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
"CATEGORIES FR";"CATEGORIES UK"
|
||||
"Chaises";"Chairs"
|
||||
"Tabourets";"Stools"
|
||||
"Fauteuils";"Armchairs"
|
||||
"Canapés";"Sofas"
|
||||
"CATEGORIES FR";"CATEGORIES UK";"CHAPO FR";"CHAPO UK";"DESCRIPTIF FR";"DESCRIPTIF UK";"PHOTO"
|
||||
"Chaises";"Chairs";"";"";"";"";""
|
||||
"Tabourets";"Stools";"";"";"";"";""
|
||||
"Fauteuils";"Armchairs";"";"";"";"";""
|
||||
"Canapés";"Sofas";"";"";"";"";""
|
||||
|
||||
|
12
setup/import/contents.csv
Normal file
@@ -0,0 +1,12 @@
|
||||
"TITLE FR";"TITLE UK";"CHAPO FR";"CHAPO UK";"DESCRIPTIF FR";"DESCRIPTIF UK";"PHOTO","FOLDERS UK"
|
||||
"A propos";"About us";"";"";"";"";"";"Information"
|
||||
"Conditions générales de vente";"Terms and Conditions";"";"";"";"";"";"Information"
|
||||
"Mentions légales";"Imprint";"";"";"";"";"";"Information"
|
||||
"Livraison";"Delivery";"";"";"";"";"";"Information"
|
||||
"Garantie";"Warranty";"";"";"";"";"";"Information"
|
||||
"Nouveau horaire d''ouverture";"New opening times";"";"";"";"";"";"Blog"
|
||||
"Nouveauté : Scarlett";"New product : Scarlett";"";"";"";"";"";"Blog"
|
||||
"Obtenez votre bon de réduction";"Claim your voucher";"";"";"";"";"";"Blog"
|
||||
"Nettoyage du tissu";"Cleaning Tissue";"";"";"";"";"";"Advice"
|
||||
"Entretien du bois";"Maintenance of wood";"";"";"";"";"";"Advice"
|
||||
"Entretien du cuir";"Maintenance of leather";"";"";"";"";"";"Advice"
|
||||
|
Can't render this file because it contains an unexpected character in line 1 and column 83.
|
4
setup/import/folders.csv
Normal file
@@ -0,0 +1,4 @@
|
||||
"TITLE FR";"TITLE UK";"CHAPO FR";"CHAPO UK";"DESCRIPTIF FR";"DESCRIPTIF UK";"PHOTO"
|
||||
"Informations";"Information";"";"";"";"";""
|
||||
"Blog";"Blog";"";"";"";"";""
|
||||
"Conseils";"Advice";"";"";"";"";""
|
||||
|
BIN
setup/import/images/BRAND-1.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
setup/import/images/BRAND-2.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
setup/import/images/BRAND-3.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
setup/import/images/BRAND-4.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
setup/import/images/BRAND-5.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
setup/import/images/BRAND-6.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
setup/import/images/BRAND-7.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
6
setup/import/materials.csv
Normal file
@@ -0,0 +1,6 @@
|
||||
"Tissu";"Tissue"
|
||||
"Bois";"Wood"
|
||||
"Métal";"Metal"
|
||||
"Plastique";"Plastic"
|
||||
"Cuir";"Leather"
|
||||
"Verre";"Glass"
|
||||
|
@@ -1,35 +1,35 @@
|
||||
"REF";"TITRE UK";"CHAPO UK";"CHAPO FR";"DESCRIPTIF UK";"DESCRIPTIF FR";"POSTSCRIPTUM UK";"POSTSCRIPTUM FR";"PRIX";"PRIX2";"PHOTO";"BRAND";"COULEUR UK";"CATEGORIE"
|
||||
"REF";"TITRE UK";"CHAPO UK";"CHAPO FR";"DESCRIPTIF UK";"DESCRIPTIF FR";"POSTSCRIPTUM UK";"POSTSCRIPTUM FR";"PRIX";"PRIX2";"PHOTO";"BRAND";"COULEUR UK";"MATERIAL UK";"CONTENT UK";"CATEGORIE"
|
||||
"PROD001";"Horatio";"Contemporary atypical chair";"Chaise contemporaine hors normes";"Its design is based on a very simple idea : atypical aesthetics for an everyday use. You may even choose to combine the various colours ! A specific look that will happily and impertinently fit with your furniture. ";"Son design est issu d'une idée très simple: un esthétique hors du commun pour un usage de tous les jours. On peut même choisir de combiner les différents coloris! Un look qui se mêle avec bonheur et impertinence à votre mobilier.
|
||||
";"Dimensions : Width : 20'' – Depth: 19'' – Height: 42''";"Dimensions : Larg 52 cm - Prof 50 cm - Haut 108 cm";223;199;"PROD001-1.jpg;PROD001-2.jpg;PROD001-3.jpg;PROD001-4.jpg";"MILAN";"blue;pink;red;green;purple";"Chairs"
|
||||
";"Dimensions : Width : 20'' – Depth: 19'' – Height: 42''";"Dimensions : Larg 52 cm - Prof 50 cm - Haut 108 cm";"223";"199";"PROD001-1.jpg;PROD001-2.jpg;PROD001-3.jpg;PROD001-4.jpg";"MILAN";"blue;pink;red;green;purple";"Plastic";"";"Chairs"
|
||||
"PROD002";"Travis";"Ergonomic & affordable";"Ergonomique et économique";"Ergonomic, affordable, comfortable, stackable, easily dismantled, this little stool became a cult item. Decorative feature or occasional seat, it suits perfectly any room in the house. ";"Ergonomique, économique, confortable, empilable, démontable, ce petit tabouret est devenu un objet culte. Elément de décor ou siège d'appoint, il a sa place dans toute la maison.
|
||||
";"Dimensions : Diam. 11'' – Height: 17''";"Dimensions : Diam 30 cm - Haut 45 cm";25;19;"PROD002-1.jpg;PROD002-2.jpg;PROD002-3.jpg;PROD002-4.jpg;PROD002-5.jpg;PROD002-6.jpg";"MAGIS";"blue;orange;yellow;pink;purple;green";"Stools"
|
||||
"PROD003";"Stacy";"A successfull mix";"Un mariage réussi";"The ''Stacy'' armchair brings a taste of playfulness in the design's world for more than 20 years ! The successfull mix of French Regence style and ultra modern materials creates a strong charismatic personality. ";"Le fauteuil Stacy apporte une note de fantaisie dans le monde du design depuis plus de 20 ans ! Sa personnalité forte et charismatique s'exprime au travers de cette association de style Régence et de matériaux ultramoderne. ";"Dimensions : Width :44'' – Depth:31'' – Height: 42'' . Sitting : width : 25''– Height : 16'' . Armrests height : 27''";"Dimensions : Larg 114 cm x Prof 80 cm x H 108 cm - Assise : larg 65 cm x H 42 cm - Accoudoirs : H 69 cm";653;610;"PROD003-1.jpg;PROD003-2.jpg;PROD003-3.jpg;";"MILAN";"blue;purple;green";"Armchairs"
|
||||
"PROD004";"Scarlett";"A timeless treasure";"Un trésor intemporel";"Treasured and timeless styling characterizes the luxury ''Scarlett'' Armchair. It will instantly add a dash of refined appeal to any living space. Beneath the luxurious fabric cover is a solid wood frame, ensuring that this piece will be passed on from generation to generation. ";"Un style précieux et intemporel caractérise la luxueuse banquette Scarlett. Elle apporte immédiatement une touche de raffinement à n'importe quel salon. Sous l'étoffe précieuse, un solide châssis bois vous assure que cette pièce traversera les époques et les générations. ";"Dimensions : Width :65'' – Depth:31''– Height: 38''";"Dimensions : Larg 165 cm x Prof 80 cm x H 95 cm";956;899;"PROD004-1.jpg;PROD004-2.jpg";"OXYO";"gray;black";"Armchairs"
|
||||
"PROD005";"Owen";"An eye-catching armchair";"Un fauteuil surprenant";"Get a look at the future – retro style - with our cutout ''Owen'' armchair ! Eye-catching and incredibly fun, this armchair is a must-have for today's hottest living space ! ";"Revisitez le futur avec une note retro grâce à notre fauteuil Owen! Spectaculaire et incroyablement fun, ce fauteuil est incontournable pour un salon moderne et branché ! ";"Dimensions : Width :30'' – Depth:31''– Height: 35''";"Dimensions : Larg 75 cm - Prof 80 cm - Haut 90 cm";395;;"PROD005-1.jpg;PROD005-2.jpg;PROD005-3.jpg;PROD005-4.jpg;PROD005-5.jpg;PROD005-6.jpg";"OXYO";"blue;purple;green;pink;red;orange;";"Armchairs"
|
||||
"PROD006";"Nigel";"A comfortable beauty";"Une beauté confortable";"This comfortable beauty does great solo as a lounger or in a book nook. With the ''Nigel'' sofa, you will get hours of cozy relaxation. This oversized seat is the ultimate lounger but the pure design still keeps it modern and hip. ";"La beauté confortable du sofa Nigel permet tous les solos dans votre salon ou votre bibliothèque. Relaxez vous tranquilement avec le canapé Nigel. Ce siège généreux est l'expression même du fauteuil mais ses lignes pures lui assurent un style moderne et tendance. ";"Dimensions: Width : 48"" - Depth : 32"" - Height : 28"" – 17"" seat Height";"Dimensions : Larg 120 cm – Prof 80 cm – Haut. 70 cm . Hauteur d'assise : 40 cm";638;;"PROD006-1.jpg;PROD006-2.jpg;PROD006-3.jpg;PROD006-4.jpg;PROD006-5.jpg;PROD006-6.jpg";"OXYO";"blue;beige;purple;green;pink;turquoise";"Sofas"
|
||||
"PROD007";"Heathcliff";"A unique style";"Un style unique";"Provide a rich texture to any living space thanks to the tufting and velvet of the ''Heathcliff'' sofa. Arched roll arms and vibrant colours add to the fun and unique style of this sofa. ";"Enrichissez votre intérieur de velours et de textures capitonnées du canapé Heathcliff. Les accoudoirs arrondis en finition cloutée et la gamme de couleurs acidulées apportent un style et une fantaisie unique à ce sofa. ";"Dimensions: Width : 92"" - Depth : 43"" - Height : 36""";"Dimensions : Larg 230 cm – Prof. 110 cm – Haut. 90 cm";1120;;"PROD007-1.jpg;PROD007-2.jpg;PROD007-3.jpg;PROD007-4.jpg;";"OFFUS";"turquoise;blue;pink;purple";"Sofas"
|
||||
"PROD008";"Wilson";"Pure luxury !";"Le luxe à l'état pur !";"Choose our ''Wilson'' armchair and surround yourself in luxury. You will appreciate it's high armrests that will keep you nestled in comfort. Beautiful coloured leather upholstery makes a fashion-forward design statement. ";"Adoptez notre fauteuil Wilson et plongez dans le luxe. Vous apprécierez ses hauts accoudoirs qui vous envelopperont de confort et de douceur. L'habillage en cuir de couleur vive en fait une pièce de design avant-gardiste. ";"Dimensions : Width : 38"" - Depth : 36"" - Height : 34""";"Dimensions : larg 95 cm – Prof. 90 cm – Haut. 90 cm";489;;"PROD008-1.jpg;PROD008-2.jpg;PROD008-3.jpg;PROD008-4.jpg;PROD008-5.jpg;";"PLINK";"blue;green;pink;purple;brown;";"Armchairs"
|
||||
";"Dimensions : Diam. 11'' – Height: 17''";"Dimensions : Diam 30 cm - Haut 45 cm";"25";"19";"PROD002-1.jpg;PROD002-2.jpg;PROD002-3.jpg;PROD002-4.jpg;PROD002-5.jpg;PROD002-6.jpg";"MAGIS";"blue;orange;yellow;pink;purple;green";"Plastic";"";"Stools"
|
||||
"PROD003";"Stacy";"A successfull mix";"Un mariage réussi";"The ''Stacy'' armchair brings a taste of playfulness in the design's world for more than 20 years ! The successfull mix of French Regence style and ultra modern materials creates a strong charismatic personality. ";"Le fauteuil Stacy apporte une note de fantaisie dans le monde du design depuis plus de 20 ans ! Sa personnalité forte et charismatique s'exprime au travers de cette association de style Régence et de matériaux ultramoderne. ";"Dimensions : Width :44'' – Depth:31'' – Height: 42'' . Sitting : width : 25''– Height : 16'' . Armrests height : 27''";"Dimensions : Larg 114 cm x Prof 80 cm x H 108 cm - Assise : larg 65 cm x H 42 cm - Accoudoirs : H 69 cm";"653";"610";"PROD003-1.jpg;PROD003-2.jpg;PROD003-3.jpg;";"MILAN";"blue;purple;green";"Tissue;Wood";"Cleaning Tissue";"Armchairs"
|
||||
"PROD004";"Scarlett";"A timeless treasure";"Un trésor intemporel";"Treasured and timeless styling characterizes the luxury ''Scarlett'' Armchair. It will instantly add a dash of refined appeal to any living space. Beneath the luxurious fabric cover is a solid wood frame, ensuring that this piece will be passed on from generation to generation. ";"Un style précieux et intemporel caractérise la luxueuse banquette Scarlett. Elle apporte immédiatement une touche de raffinement à n'importe quel salon. Sous l'étoffe précieuse, un solide châssis bois vous assure que cette pièce traversera les époques et les générations. ";"Dimensions : Width :65'' – Depth:31''– Height: 38''";"Dimensions : Larg 165 cm x Prof 80 cm x H 95 cm";"956";"899";"PROD004-1.jpg;PROD004-2.jpg";"OXYO";"gray;black";"Tissue;Wood";"Cleaning Tissue";"Armchairs"
|
||||
"PROD005";"Owen";"An eye-catching armchair";"Un fauteuil surprenant";"Get a look at the future – retro style - with our cutout ''Owen'' armchair ! Eye-catching and incredibly fun, this armchair is a must-have for today's hottest living space ! ";"Revisitez le futur avec une note retro grâce à notre fauteuil Owen! Spectaculaire et incroyablement fun, ce fauteuil est incontournable pour un salon moderne et branché ! ";"Dimensions : Width :30'' – Depth:31''– Height: 35''";"Dimensions : Larg 75 cm - Prof 80 cm - Haut 90 cm";"395";"";"PROD005-1.jpg;PROD005-2.jpg;PROD005-3.jpg;PROD005-4.jpg;PROD005-5.jpg;PROD005-6.jpg";"OXYO";"blue;purple;green;pink;red;orange;";"Tissue;Metal";"Cleaning Tissue";"Armchairs"
|
||||
"PROD006";"Nigel";"A comfortable beauty";"Une beauté confortable";"This comfortable beauty does great solo as a lounger or in a book nook. With the ''Nigel'' sofa, you will get hours of cozy relaxation. This oversized seat is the ultimate lounger but the pure design still keeps it modern and hip. ";"La beauté confortable du sofa Nigel permet tous les solos dans votre salon ou votre bibliothèque. Relaxez vous tranquilement avec le canapé Nigel. Ce siège généreux est l'expression même du fauteuil mais ses lignes pures lui assurent un style moderne et tendance. ";"Dimensions: Width : 48"" - Depth : 32"" - Height : 28"" – 17"" seat Height";"Dimensions : Larg 120 cm – Prof 80 cm – Haut. 70 cm . Hauteur d'assise : 40 cm";"638";"";"PROD006-1.jpg;PROD006-2.jpg;PROD006-3.jpg;PROD006-4.jpg;PROD006-5.jpg;PROD006-6.jpg";"OXYO";"blue;beige;purple;green;pink;turquoise";"Tissue;Metal";"Cleaning Tissue";"Sofas"
|
||||
"PROD007";"Heathcliff";"A unique style";"Un style unique";"Provide a rich texture to any living space thanks to the tufting and velvet of the ''Heathcliff'' sofa. Arched roll arms and vibrant colours add to the fun and unique style of this sofa. ";"Enrichissez votre intérieur de velours et de textures capitonnées du canapé Heathcliff. Les accoudoirs arrondis en finition cloutée et la gamme de couleurs acidulées apportent un style et une fantaisie unique à ce sofa. ";"Dimensions: Width : 92"" - Depth : 43"" - Height : 36""";"Dimensions : Larg 230 cm – Prof. 110 cm – Haut. 90 cm";"1120";"";"PROD007-1.jpg;PROD007-2.jpg;PROD007-3.jpg;PROD007-4.jpg;";"OFFUS";"turquoise;blue;pink;purple";"Tissue;Wood";"Cleaning Tissue";"Sofas"
|
||||
"PROD008";"Wilson";"Pure luxury !";"Le luxe à l'état pur !";"Choose our ''Wilson'' armchair and surround yourself in luxury. You will appreciate it's high armrests that will keep you nestled in comfort. Beautiful coloured leather upholstery makes a fashion-forward design statement. ";"Adoptez notre fauteuil Wilson et plongez dans le luxe. Vous apprécierez ses hauts accoudoirs qui vous envelopperont de confort et de douceur. L'habillage en cuir de couleur vive en fait une pièce de design avant-gardiste. ";"Dimensions : Width : 38"" - Depth : 36"" - Height : 34""";"Dimensions : larg 95 cm – Prof. 90 cm – Haut. 90 cm";"489";"";"PROD008-1.jpg;PROD008-2.jpg;PROD008-3.jpg;PROD008-4.jpg;PROD008-5.jpg;";"PLINK";"blue;green;pink;purple;brown;";"Tissue;Wood";"Cleaning Tissue;Maintenance of leather";"Armchairs"
|
||||
"PROD009";"Zoe";"An exceptional combination";"Une union exceptionnelle";"Contemporary ''Zoe'' armchair is an exceptional combination of function and design.
|
||||
The seating is generously cushioned for comfort. Contoured, wrap-around back offers optimal support. The brushed stainless steel base ensures stability.
|
||||
Swivel feature for added function. ";"Zoe est un fauteuil contemporain qui combine de manière exceptionnelle fonctionnalité et design. L'assise est garnie d'un coussin généreux pour plus de confort. Le dossier enveloppant offre un appui optimal. La stabilité de l'ensemble est assurée par une base en inox brossé. Siège pivotant. ";"Dimensions : Width : 30'' – Depth : 27'' – height : 31''";"Dimensions : Larg. 75 cm – Prof. 69 cm – Haut. 80 cm";520;;"PROD009-1.jpg;PROD009-2.jpg;PROD009-3.jpg";"PLINK";"blue;purple;orange";"Armchairs"
|
||||
"PROD010";"Sigmund";"A fun project";"Un projet fou";"The contrast of a vintage couch and modern colours provides a really fun project called ''Sigmund'' ! It will instantly add a dash of impertinence for any hip living place. ";"Le projet fantastique appelé Sigmund provient d'un contraste étonnant entre un canapé vintage et un éventail de couleurs moderne. Ce canapé apportera immédiatement une touche d'impertinence à n'importe quel salon branché. ";"Dimensions: Width : 92"" - Depth : 43"" - Height : 36""";"Dimensions : Larg 230 cm – Prof. 110 cm – Haut. 90 cm";834;;"PROD010-1.jpg;PROD010-2.jpg;PROD010-3.jpg;PROD010-4.jpg";"OFFUS";"blue;purple;red;orange";"Armchairs ; Sofas"
|
||||
"PROD011";"Tina";"The little plastic chair";"La petite chaise en plastique";"This little ''Tina'' plastic chair will become your new red hot favourite thanks to its efficient design. Stackable and made of recyclable material, Tina suits perfectly any room in the house ! ";"L'efficacité du design de cette petite chaise en plastique Tina en fera vite votre favorite. Empilable et recyclable, Tina se glissera parfaitement dans n'importe quelle pièce de votre maison ! ";"Dimensions : Width : 19'' – Depth : 23'' – Height : 31''";"Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm ";75;;"PROD011-1.jpg;PROD011-2.jpg;PROD011-3.jpg;PROD011-4.jpg";"PARRY";"blue;orange;red;purple";"Chairs"
|
||||
"PROD012";"Victoria";"Pure lines";"Des lignes éûrées";"A successfull combination of Regence style and ultra modern material. The pure lines of the ''Victoria'' armchair together with its translucent brilliance make a fashion-forward design statement. ";"Un mariage réussit du style Régence et de matériaux ultra modernes. Les lignes pures de la chaise Victoria associées à la brillance translucide de sa matière en font une pièce de design avant-gardiste. ";"Dimensions : Width :44'' – Depth:31'' – Height: 42'' . Sitting : width : 25''– Height : 16'' . Armrests height : 27''";"Dimensions : Larg 114 cm x Prof 80 cm x H 108 cm - Assise : larg 65 cm x H 42 cm - Accoudoirs : H 69 cm";138;;"PROD012-1.jpg;PROD012-2.jpg";"MILAN";"black";"Armchairs"
|
||||
"PROD013";"Violet";"A beautifull classic";"Une beauté classique";"A new edition of a classic. Beneath a beautiful colorfull leather, a strong walnut wood frame. You will appreciate the luxurious stylish details of the ''Violet'' armless chair. ";"La réédition d'un classique. Sous un superbe cuir aux couleurs chatoyantes, une solide structure en noyer. Vous apprécierez les détails stylistiques luxueux de notre chaise Violet. ";"Dimensions : Width : 19'' – Depth : 23'' – Height : 31''";"Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm";98;;"PROD013-1.jpg";"MAGIS";"Gray";"Chairs"
|
||||
"PROD014";"Sally";"Contemporary atypical chair";"Chaise contemporaine hors normes";"Contemporary atypical chair. The atypical sitting of the ''Sally '' chair will nestled you in confort. Play with the vibrant colours range to create a unique dining room. ";"Chaise contemporaine hors normes. L'assise surprenante de la chaise Sally vous enveloppera de confort. Amusez vous avec l'éventail de couleurs lumineuses pour créer une salle à manger unique. ";"Dimensions : Width : 19'' – Depth : 23'' – Height : 31''";"Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm";112;;"PROD014-1.jpg;PROD014-2.jpg;PROD014-3.jpg;PROD014-4.jpg";"PARRY";"blue;purple;orange;yellow";"Chairs"
|
||||
"PROD015";"Oliver";"Comfort & Design";"Confort et Design";"Surround yourself in ultra modern luxury with the ''Oliver'' armchair and get a look at the future ! Eye-catching, this unique combination of comfort and design is a must-have for today's book nook. ";"Abandonnez vous à un univers de luxe ultra moderne avec le fauteuil Oliver et voyagez dans le futur ! Cette combinaison unique de confort et de design est spectaculaire. Un élément incontournable pour votre bibliothèque. ";"Dimensions : Width : 30'' – Depth : 27'' – height : 31''";"Dimensions : Larg. 75 cm – Prof. 69 cm – Haut. 80 cm";340;;"PROD015-1.jpg;PROD015-2.jpg;";"MAGIS";"white;black";"Armchairs;Chairs"
|
||||
"PROD016";"Lexie";"A modern style";"Un style moderne";"Demonstrate your flair for modern style with our ''Lexie'' chair in your dining room. A rectangular cushioned back offers a contemporary feel, while the comfortable seat provides complete comfort. ";"Montrez que vous avez le sens de la modernité en choisissant la chaise ''Lexie'' pour votre salle à manger. Le coussin rectangulaire sur le dossier apporte une touche contemporaine. L'assise généreuse apporte un confort complet. ";"Dimensions : Width : 19'' – Depth : 23'' – Height : 40''";"Dimensions : larg. 50 cm – Prof. 60 cm – Haut. 100 cm";159;;"PROD016-1.jpg";"PLINK";"Beige";"Chairs"
|
||||
"PROD017";"Flynn";"A touch of retro vibe";"Un petit air rétro";"If your destination is up-to-date décor with a touch of retro vibe, look no further than our ''Flynn'' sofa. Sleek, low track arms and high tapering legs give this piece a mid-century flavor. The vibrant tones of the woven upholstery will easily blend with any interior décor. ";"Si vous recherchez une décoration actuelle avec une touche rétro, n'allez pas plus loin et opter pour notre canapé ''Flynn''. Ce canapé a un petit air des années 50 grâce à ses accoudoirs bas, ses pieds allongés et ses lignes pures. Les couleurs chatoyantes de son revêtement en laine lui permettent de se fondre dans tous les intérieurs. ";"Dimensions : Width : 89'' – Depth : 37'' – Height : 36''";"Dimensions : Larg. 225 cm – Prof. 95 cm – Haut. 90 cm";1299;;"PROD017-1.jpg;PROD017-2.jpg;PROD017-3.jpg;PROD017-4.jpg";"OFFUS";"blue;green;red;purple";"Sofas"
|
||||
"PROD018";"Emily";"A old-world feel";"Une touche d'histoire";"Our ''Emily'' armlesschair adds a touch of a old-world feel to your space. Perfect for when defining the seating space in a larger room. A medium wood finish sets off the delicate embellishments at the base, while the luxurous upholstery keeps the look fresh. The cushions guarantee that this is a chair worth relaxing in, not just admiring from afar. ";"La chaise ''Emily'' apporte une touche d'histoire à votre intérieur. Elle est parfaite pour structurer votre espace, notamment dans une grande pièce. Les finitions bois font la part belle à de délicates arabesques, tandis que le luxueux revêtement apporte un look frais. Cette chaise n'est pas destinée à la figuration grâce à la mousse confortable de l'assise. ";"Dimensions : Width : 33'' – Depth : 27'' – Height : 40''";"Dimensions : Larg. 85 cm – Prof. 69 cm – Haut. 100 cm";690;;"PROD018-1.jpg";"PARRY";"red";"Armchairs"
|
||||
"PROD019";"Edgar";"A special spot";"Un endroit à part";"A special spot for reading, lounging or chatting, our '' Edgar '' armchair has no reservations when it comes to style. The design starts with mid-century modern elements like lean arms, while the brushed stainless steel base ensures stability. Swivel feature for added function. ";"Un endroit spécial où lire, rêver ou discuter, notre fauteuil ''Edgar'' n'a pas de limite quand il s'agit de style. Son design part d'éléments contemporains comme ses accoudoirs bas et fins, tandis que sa base en inox brossé assure la stabilité de l'ensemble. Siège pivotant. ";"Dimensions : Width : 33'' – Depth : 27'' – Height : 40''";"Dimensions: Larg. 85 cm – Prof. 69 cm – Haut. 100 cm";275;;"PROD019-1.jpg;PROD019-2.jpg;PROD019-3.jpg;PROD019-4.jpg;PROD019-5.jpg";"TOKO";"blue;yellow;orange;pink;purple";"Armchairs"
|
||||
"PROD020";"Pamela";"Clean lines";"Des lignes pures";"By making our ''Pamela'' chair a centerpiece of your dining area, you'll demonstrate your eye for clean lines and comfortable seating. The contemporary touches of this chair are provided by the light brown wool, a flared seat back and slightly curved wood back legs. The color of the uphostery is the perfect complement to the wood finish of the chair legs. ";"Choisissez notre chaise '' Pamela'' comme pièce maitresse de votre salle à manger et faites la démonstration de votre maitrise des lignes épurées et du confort d'assise. L'allure contemporaine de cette chaise provient de la laine beige, du dossier légèrement évasé et des pieds en bois arrières délicatement incurvés. La couleur du revêtement fait parfaitement écho à la finition bois des pieds. Dimensions : larg. 50 cm – Prof. 60 cm – Haut. 100 cm";"Dimensions : Width : 19'' – Depth : 23'' – Height : 40''";"Dimensions : Width : 19'' – Depth : 23'' – Height : 40''";189;;"PROD020-1.jpg";"OFFUS";"brown";"Chairs"
|
||||
"PROD021";"Courtney";"Mil madness";"Douce folie";"Add a dash of mild madness to your kitchen ! Eye-catching, this ''Courtney'' armless chair is a must-have for hip dining area.";"Mettez une touche de douce folie dans votre cuisine ! Surprenante, notre chaise ''Courtney'' est incontournable pour un coin repas branché. ";"Dimensions : Width : 19'' – Depth : 23'' – Height : 31''";"Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm ";89;;"PROD021-1.jpg;PROD021-2.jpg;PROD021-3.jpg;PROD021-4.jpg";"TOKO";"blue;orange;green;purple";"Chairs"
|
||||
"PROD022";"Barbara";"An amazing look";"Un look détonnant";"An amazing look for our ''Barbara'' chair ! A cut-out oval in the back provides a distinctive character, while the lively range of colours and the mat finish makes a big style statement. Dimensions : Width : 19'' – Depth : 23'' – Height : 31''";"Un look hors du commun pour la chaise ''Barbara'' ! L'ouverture oval du dossier apporte une personnalité toute particulière tandis que la large gamme de couleurs vives et le rendu mat provoque un vrai effet de style. Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm ";"Width : 19'' – Depth : 23'' – Height : 31''";"Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm ";122;;"PROD022-1.jpg;PROD022-2.jpg;PROD022-3.jpg;PROD022-4.jpg;PROD022-5.jpg";"MAGIS";"blue;turquoise;yellow;orange;red";"Chairs"
|
||||
"PROD023";"Haley";"An armless chair coming from outer space !";"Une chaise cosmique !";"This ''Haley'' amazing chair is as light as paper but sturdy as steel. Play with the vibrant colours range to create a unique dining area. ";"La chaise ''Haley'' est étonnante : légère comme le papier mais solide comme l'acier. Jouez avec la gamme de couleurs vibrantes pour composer un espace repas unique.";"Dimensions : Width : 19'' – Depth : 23'' – Height : 31''";"Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm ";93;;"PROD023-1.jpg;PROD023-2.jpg;PROD023-3.jpg;PROD023-4.jpg;PROD023-5.jpg;PROD023-6.jpg";"MILAN";"purple;green;pink;red;orange;turquoise";"Chairs"
|
||||
"PROD024";"Kyle";"A modern silhouette";"Un look moderne";"The modern silhouette of the ''Kyle'' sofa features cantilevered legs in a mirror chrome finish and pillow armrests. The button-tufted seat and back cushions highlight the detailed craftsmanship. ";"Le canapé ''Kyle'' offre une silhouette moderne grâce à ses pieds chromés en porte-à-faux et ses accoudoirs moelleux. L'assise et le dossier capitonnés mettent en valeur le travail précis de l'artisan.";"Dimensions: Width : 92"" - Depth : 43"" - Height : 36""";"Dimensions : Larg 230 cm – Prof. 110 cm – Haut. 90 cm";1799;;"PROD024-1.jpg;PROD024-2.jpg;PROD024-3.jpg;PROD024-4.jpg;PROD024-5.jpg";"TOKO";"blue;pink;red;green;purple";"Sofas"
|
||||
"PROD025";"Kenny";"A fresh take on a classic chair ";"Un classique revisité";"Chic design elements and a lovely pattern bring cool interest to this ''Kenny'' chair. The well-lofted seat cushion offers ultimate comfort and support.";"Des éléments de design élégants et un motif chic apporte un nouvel intérêt à notre chaise ''Kenny''. Un coussin d'assise bien positionné offre un confort suprême.";"Dimensions : Width : 19'' – Depth : 23'' – Height : 31''";"Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm";299;;"PROD025-1.jpg;PROD025-2.jpg;PROD025-3.jpg";"PLINK";"blue;purple;green";"Chairs"
|
||||
"PROD026";"Stuart";"A masterpiece of furniture design";"Une pièce de designer !";"Get the on-trend look of modern masterpieces of furniture design with our ''Stuart'' chair. Paying homage to the classic design, this piece has an architecturally inspired silhouette with its sculptural wood frame and the clean lines of seat and back cushions. The crisp white hue will blend easily with a range of color schemes. ";"Offrez vous le look branché d'une grande pièce de designer avec la chaise ''Stuart''. Rendant hommage aux classiques du Design, cette chaise a une silhouette inspirée de l'architecture par son cadre bois sculptural et par les lignes pures de son assise et de son dossier. La fraiche nuance de blanc se fondera facilement dans toutes les harmonies de couleurs.";"Dimensions : Width : 19'' – Depth : 23'' – Height : 31''";"Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm";189;;"PROD026-1.jpg";"PLINK";"white";"Chairs"
|
||||
"PROD027";"Marie-Claire";"A naturally appealing";"Une sobre élégance";"There's no denying the naturally appealing of our Marie-Claire chair! Its organic feeling is enhanced by the pretty wood veneers and faux leather upholstery, adding rustic charm and comfort.";"On ne peut nier l'élégance sobre de notre chaise Marie-Claire. Son allure naturelle est rehaussée par les finitions bois et le revêtement imitation cuir ajoute à son charme rustique et son confort.";"Dimensions : Width : 19'' – Depth : 23'' – Height : 31''";"Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm";104;;"PROD027-1.jpg";"TOKO";"green";"Chairs"
|
||||
"PROD028";"Leela";"Contemporary fun chair";"Une fantaisie contemporaine";"At once contemporary and chic, The ''Leela'' chair makes your strong sense of personal style evident. Stylish, easy-clean, leather-like upholstery makes the cut-out in the back more stunning in the light of its vibrant yellow.";"Tout à la fois chic et contemporaine, la chaise ''Leela'' rend votre sens du style évident. Le revêtement en similicuir, facile d'entretien met en valeur l'ouverture du dossier par son jaune lumineux.";"Width : 19'' – Depth : 23'' – Height : 31''";"Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm ";144;;"PROD028-1.jpg";"MILAN";"yellow";"Chairs;Armchairs"
|
||||
"PROD029";"Nibbler";"A modern bar stool";"Un tabouret de bar moderne";"If you're looking for a chic, counter height stool that features clean lines and a modern sensibility, look no further than our ''Nibbler'' stool. A chrome-finished base, oval footrest and adjustable, gas-lift mechanism add to its modern look.";"Si vous recherchez un tabouret haut et chic, n'allez pas plus loin que notre tabouret ''Nibbler'' avec ses lignes pures et sa modernité. Une base chromée, un repose-pieds oval ajustable et un mécanisme à gaz ajoute à son look moderne.";"Dimensions : Width : 19'' – Depth : 18'' – Height : 29''";"Dimensions : Larg 50 cm – Prof. 45 cm – Haut. 75 cm";78;;"PROD029-1.jpg";"MAGIS";"black";"Stools"
|
||||
"PROD030";"Ron";"Get a look at the futur";"Une incursion dans le futur";"Get a look at the future — retro style — with our ''Ron'' bar stool! The contemporary design of the seating with a cut-out oval in the back for distinctive character, while the lively range of colours and high gloss make a big style statement. A chrome-finished base, oval footrest and adjustable, gas-lift mechanism add to the fresh look. Eye-catching and fun, the ''ron'' stool is a must-have for today's hottest dining area and bars. ";"Revisitez le futur avec une note retro grâce au tabouret de bar ''Ron''! Le design contemporain de ce siège grâce à l'ouverture ovale dans son dossier et une large gamme de couleurs vives. Son rendu glossy lui donne un style tout particulier. Une base chromée, un repose-pieds oval ajustable et un mécanisme à gaz ajoute à son look moderne. Surprenant et joyeux, le tabouret ''Ron'' est un incontournable des coin repas et des bars les plus branchés";"Dimensions : Width : 19'' – Depth : 18'' – Height : 29''";"Dimensions : Larg 50 cm – Prof. 45 cm – Haut. 75 cm";96;;"PROD030-1.jpg;PROD030-2.jpg;PROD030-3.jpg;PROD030-4.jpg;";"OFFUS";"blue;yellow;orange;purple";"Stools"
|
||||
Swivel feature for added function. ";"Zoe est un fauteuil contemporain qui combine de manière exceptionnelle fonctionnalité et design. L'assise est garnie d'un coussin généreux pour plus de confort. Le dossier enveloppant offre un appui optimal. La stabilité de l'ensemble est assurée par une base en inox brossé. Siège pivotant. ";"Dimensions : Width : 30'' – Depth : 27'' – height : 31''";"Dimensions : Larg. 75 cm – Prof. 69 cm – Haut. 80 cm";"520";"";"PROD009-1.jpg;PROD009-2.jpg;PROD009-3.jpg";"PLINK";"blue;purple;orange";"Plastic;Metal";"";"Armchairs"
|
||||
"PROD010";"Sigmund";"A fun project";"Un projet fou";"The contrast of a vintage couch and modern colours provides a really fun project called ''Sigmund'' ! It will instantly add a dash of impertinence for any hip living place. ";"Le projet fantastique appelé Sigmund provient d'un contraste étonnant entre un canapé vintage et un éventail de couleurs moderne. Ce canapé apportera immédiatement une touche d'impertinence à n'importe quel salon branché. ";"Dimensions: Width : 92"" - Depth : 43"" - Height : 36""";"Dimensions : Larg 230 cm – Prof. 110 cm – Haut. 90 cm";"834";"";"PROD010-1.jpg;PROD010-2.jpg;PROD010-3.jpg;PROD010-4.jpg";"OFFUS";"blue;purple;red;orange";"Tissue;Wood";"Cleaning Tissue";"Armchairs ; Sofas"
|
||||
"PROD011";"Tina";"The little plastic chair";"La petite chaise en plastique";"This little ''Tina'' plastic chair will become your new red hot favourite thanks to its efficient design. Stackable and made of recyclable material, Tina suits perfectly any room in the house ! ";"L'efficacité du design de cette petite chaise en plastique Tina en fera vite votre favorite. Empilable et recyclable, Tina se glissera parfaitement dans n'importe quelle pièce de votre maison ! ";"Dimensions : Width : 19'' – Depth : 23'' – Height : 31''";"Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm ";"75";"";"PROD011-1.jpg;PROD011-2.jpg;PROD011-3.jpg;PROD011-4.jpg";"PARRY";"blue;orange;red;purple";"Plastic";"";"Chairs"
|
||||
"PROD012";"Victoria";"Pure lines";"Des lignes éûrées";"A successfull combination of Regence style and ultra modern material. The pure lines of the ''Victoria'' armchair together with its translucent brilliance make a fashion-forward design statement. ";"Un mariage réussit du style Régence et de matériaux ultra modernes. Les lignes pures de la chaise Victoria associées à la brillance translucide de sa matière en font une pièce de design avant-gardiste. ";"Dimensions : Width :44'' – Depth:31'' – Height: 42'' . Sitting : width : 25''– Height : 16'' . Armrests height : 27''";"Dimensions : Larg 114 cm x Prof 80 cm x H 108 cm - Assise : larg 65 cm x H 42 cm - Accoudoirs : H 69 cm";"138";"";"PROD012-1.jpg;PROD012-2.jpg";"MILAN";"black";"Plastic";"";"Armchairs"
|
||||
"PROD013";"Violet";"A beautifull classic";"Une beauté classique";"A new edition of a classic. Beneath a beautiful colorfull leather, a strong walnut wood frame. You will appreciate the luxurious stylish details of the ''Violet'' armless chair. ";"La réédition d'un classique. Sous un superbe cuir aux couleurs chatoyantes, une solide structure en noyer. Vous apprécierez les détails stylistiques luxueux de notre chaise Violet. ";"Dimensions : Width : 19'' – Depth : 23'' – Height : 31''";"Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm";"98";"";"PROD013-1.jpg";"MAGIS";"Gray";"Leather;Wood";"Maintenance of leather";"Chairs"
|
||||
"PROD014";"Sally";"Contemporary atypical chair";"Chaise contemporaine hors normes";"Contemporary atypical chair. The atypical sitting of the ''Sally '' chair will nestled you in confort. Play with the vibrant colours range to create a unique dining room. ";"Chaise contemporaine hors normes. L'assise surprenante de la chaise Sally vous enveloppera de confort. Amusez vous avec l'éventail de couleurs lumineuses pour créer une salle à manger unique. ";"Dimensions : Width : 19'' – Depth : 23'' – Height : 31''";"Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm";"112";"";"PROD014-1.jpg;PROD014-2.jpg;PROD014-3.jpg;PROD014-4.jpg";"PARRY";"blue;purple;orange;yellow";"Leather;Metal";"";"Chairs"
|
||||
"PROD015";"Oliver";"Comfort & Design";"Confort et Design";"Surround yourself in ultra modern luxury with the ''Oliver'' armchair and get a look at the future ! Eye-catching, this unique combination of comfort and design is a must-have for today's book nook. ";"Abandonnez vous à un univers de luxe ultra moderne avec le fauteuil Oliver et voyagez dans le futur ! Cette combinaison unique de confort et de design est spectaculaire. Un élément incontournable pour votre bibliothèque. ";"Dimensions : Width : 30'' – Depth : 27'' – height : 31''";"Dimensions : Larg. 75 cm – Prof. 69 cm – Haut. 80 cm";"340";"";"PROD015-1.jpg;PROD015-2.jpg;";"MAGIS";"white;black";"Tissue;Plastic";"Cleaning Tissue";"Armchairs;Chairs"
|
||||
"PROD016";"Lexie";"A modern style";"Un style moderne";"Demonstrate your flair for modern style with our ''Lexie'' chair in your dining room. A rectangular cushioned back offers a contemporary feel, while the comfortable seat provides complete comfort. ";"Montrez que vous avez le sens de la modernité en choisissant la chaise ''Lexie'' pour votre salle à manger. Le coussin rectangulaire sur le dossier apporte une touche contemporaine. L'assise généreuse apporte un confort complet. ";"Dimensions : Width : 19'' – Depth : 23'' – Height : 40''";"Dimensions : larg. 50 cm – Prof. 60 cm – Haut. 100 cm";"159";"";"PROD016-1.jpg";"PLINK";"Beige";"Tissue;Wood";"Cleaning Tissue;Maintenance of wood";"Chairs"
|
||||
"PROD017";"Flynn";"A touch of retro vibe";"Un petit air rétro";"If your destination is up-to-date décor with a touch of retro vibe, look no further than our ''Flynn'' sofa. Sleek, low track arms and high tapering legs give this piece a mid-century flavor. The vibrant tones of the woven upholstery will easily blend with any interior décor. ";"Si vous recherchez une décoration actuelle avec une touche rétro, n'allez pas plus loin et opter pour notre canapé ''Flynn''. Ce canapé a un petit air des années 50 grâce à ses accoudoirs bas, ses pieds allongés et ses lignes pures. Les couleurs chatoyantes de son revêtement en laine lui permettent de se fondre dans tous les intérieurs. ";"Dimensions : Width : 89'' – Depth : 37'' – Height : 36''";"Dimensions : Larg. 225 cm – Prof. 95 cm – Haut. 90 cm";"1299";"";"PROD017-1.jpg;PROD017-2.jpg;PROD017-3.jpg;PROD017-4.jpg";"OFFUS";"blue;green;red;purple";"Tissue;Metal";"Cleaning Tissue";"Sofas"
|
||||
"PROD018";"Emily";"A old-world feel";"Une touche d'histoire";"Our ''Emily'' armlesschair adds a touch of a old-world feel to your space. Perfect for when defining the seating space in a larger room. A medium wood finish sets off the delicate embellishments at the base, while the luxurous upholstery keeps the look fresh. The cushions guarantee that this is a chair worth relaxing in, not just admiring from afar. ";"La chaise ''Emily'' apporte une touche d'histoire à votre intérieur. Elle est parfaite pour structurer votre espace, notamment dans une grande pièce. Les finitions bois font la part belle à de délicates arabesques, tandis que le luxueux revêtement apporte un look frais. Cette chaise n'est pas destinée à la figuration grâce à la mousse confortable de l'assise. ";"Dimensions : Width : 33'' – Depth : 27'' – Height : 40''";"Dimensions : Larg. 85 cm – Prof. 69 cm – Haut. 100 cm";"690";"";"PROD018-1.jpg";"PARRY";"red";"Tissue;Wood";"Cleaning Tissue";"Armchairs"
|
||||
"PROD019";"Edgar";"A special spot";"Un endroit à part";"A special spot for reading, lounging or chatting, our '' Edgar '' armchair has no reservations when it comes to style. The design starts with mid-century modern elements like lean arms, while the brushed stainless steel base ensures stability. Swivel feature for added function. ";"Un endroit spécial où lire, rêver ou discuter, notre fauteuil ''Edgar'' n'a pas de limite quand il s'agit de style. Son design part d'éléments contemporains comme ses accoudoirs bas et fins, tandis que sa base en inox brossé assure la stabilité de l'ensemble. Siège pivotant. ";"Dimensions : Width : 33'' – Depth : 27'' – Height : 40''";"Dimensions: Larg. 85 cm – Prof. 69 cm – Haut. 100 cm";"275";"";"PROD019-1.jpg;PROD019-2.jpg;PROD019-3.jpg;PROD019-4.jpg;PROD019-5.jpg";"TOKO";"blue;yellow;orange;pink;purple";"Tissue;Metal";"Cleaning Tissue";"Armchairs"
|
||||
"PROD020";"Pamela";"Clean lines";"Des lignes pures";"By making our ''Pamela'' chair a centerpiece of your dining area, you'll demonstrate your eye for clean lines and comfortable seating. The contemporary touches of this chair are provided by the light brown wool, a flared seat back and slightly curved wood back legs. The color of the uphostery is the perfect complement to the wood finish of the chair legs. ";"Choisissez notre chaise '' Pamela'' comme pièce maitresse de votre salle à manger et faites la démonstration de votre maitrise des lignes épurées et du confort d'assise. L'allure contemporaine de cette chaise provient de la laine beige, du dossier légèrement évasé et des pieds en bois arrières délicatement incurvés. La couleur du revêtement fait parfaitement écho à la finition bois des pieds. Dimensions : larg. 50 cm – Prof. 60 cm – Haut. 100 cm";"Dimensions : Width : 19'' – Depth : 23'' – Height : 40''";"Dimensions : Width : 19'' – Depth : 23'' – Height : 40''";"189";"";"PROD020-1.jpg";"OFFUS";"brown";"Tissue;Wood";"Cleaning Tissue";"Chairs"
|
||||
"PROD021";"Courtney";"Mil madness";"Douce folie";"Add a dash of mild madness to your kitchen ! Eye-catching, this ''Courtney'' armless chair is a must-have for hip dining area.";"Mettez une touche de douce folie dans votre cuisine ! Surprenante, notre chaise ''Courtney'' est incontournable pour un coin repas branché. ";"Dimensions : Width : 19'' – Depth : 23'' – Height : 31''";"Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm ";"89";"";"PROD021-1.jpg;PROD021-2.jpg;PROD021-3.jpg;PROD021-4.jpg";"TOKO";"blue;orange;green;purple";"Plastic;Glass";"";"Chairs"
|
||||
"PROD022";"Barbara";"An amazing look";"Un look détonnant";"An amazing look for our ''Barbara'' chair ! A cut-out oval in the back provides a distinctive character, while the lively range of colours and the mat finish makes a big style statement. Dimensions : Width : 19'' – Depth : 23'' – Height : 31''";"Un look hors du commun pour la chaise ''Barbara'' ! L'ouverture oval du dossier apporte une personnalité toute particulière tandis que la large gamme de couleurs vives et le rendu mat provoque un vrai effet de style. Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm ";"Width : 19'' – Depth : 23'' – Height : 31''";"Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm ";"122";"";"PROD022-1.jpg;PROD022-2.jpg;PROD022-3.jpg;PROD022-4.jpg;PROD022-5.jpg";"MAGIS";"blue;turquoise;yellow;orange;red";"Plastic;Metal";"";"Chairs"
|
||||
"PROD023";"Haley";"An armless chair coming from outer space !";"Une chaise cosmique !";"This ''Haley'' amazing chair is as light as paper but sturdy as steel. Play with the vibrant colours range to create a unique dining area. ";"La chaise ''Haley'' est étonnante : légère comme le papier mais solide comme l'acier. Jouez avec la gamme de couleurs vibrantes pour composer un espace repas unique.";"Dimensions : Width : 19'' – Depth : 23'' – Height : 31''";"Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm ";"93";"";"PROD023-1.jpg;PROD023-2.jpg;PROD023-3.jpg;PROD023-4.jpg;PROD023-5.jpg;PROD023-6.jpg";"MILAN";"purple;green;pink;red;orange;turquoise";"Plastic";"";"Chairs"
|
||||
"PROD024";"Kyle";"A modern silhouette";"Un look moderne";"The modern silhouette of the ''Kyle'' sofa features cantilevered legs in a mirror chrome finish and pillow armrests. The button-tufted seat and back cushions highlight the detailed craftsmanship. ";"Le canapé ''Kyle'' offre une silhouette moderne grâce à ses pieds chromés en porte-à-faux et ses accoudoirs moelleux. L'assise et le dossier capitonnés mettent en valeur le travail précis de l'artisan.";"Dimensions: Width : 92"" - Depth : 43"" - Height : 36""";"Dimensions : Larg 230 cm – Prof. 110 cm – Haut. 90 cm";"1799";"";"PROD024-1.jpg;PROD024-2.jpg;PROD024-3.jpg;PROD024-4.jpg;PROD024-5.jpg";"TOKO";"blue;pink;red;green;purple";"Tissue;Metal";"Cleaning Tissue";"Sofas"
|
||||
"PROD025";"Kenny";"A fresh take on a classic chair ";"Un classique revisité";"Chic design elements and a lovely pattern bring cool interest to this ''Kenny'' chair. The well-lofted seat cushion offers ultimate comfort and support.";"Des éléments de design élégants et un motif chic apporte un nouvel intérêt à notre chaise ''Kenny''. Un coussin d'assise bien positionné offre un confort suprême.";"Dimensions : Width : 19'' – Depth : 23'' – Height : 31''";"Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm";"299";"";"PROD025-1.jpg;PROD025-2.jpg;PROD025-3.jpg";"PLINK";"blue;purple;green";"Tissue;Wood";"Cleaning Tissue";"Chairs"
|
||||
"PROD026";"Stuart";"A masterpiece of furniture design";"Une pièce de designer !";"Get the on-trend look of modern masterpieces of furniture design with our ''Stuart'' chair. Paying homage to the classic design, this piece has an architecturally inspired silhouette with its sculptural wood frame and the clean lines of seat and back cushions. The crisp white hue will blend easily with a range of color schemes. ";"Offrez vous le look branché d'une grande pièce de designer avec la chaise ''Stuart''. Rendant hommage aux classiques du Design, cette chaise a une silhouette inspirée de l'architecture par son cadre bois sculptural et par les lignes pures de son assise et de son dossier. La fraiche nuance de blanc se fondera facilement dans toutes les harmonies de couleurs.";"Dimensions : Width : 19'' – Depth : 23'' – Height : 31''";"Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm";"189";"";"PROD026-1.jpg";"PLINK";"white";"Tissue;Wood";"Cleaning Tissue";"Chairs"
|
||||
"PROD027";"Marie-Claire";"A naturally appealing";"Une sobre élégance";"There's no denying the naturally appealing of our Marie-Claire chair! Its organic feeling is enhanced by the pretty wood veneers and faux leather upholstery, adding rustic charm and comfort.";"On ne peut nier l'élégance sobre de notre chaise Marie-Claire. Son allure naturelle est rehaussée par les finitions bois et le revêtement imitation cuir ajoute à son charme rustique et son confort.";"Dimensions : Width : 19'' – Depth : 23'' – Height : 31''";"Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm";"104";"";"PROD027-1.jpg";"TOKO";"green";"Tissue;Wood";"Cleaning Tissue";"Chairs"
|
||||
"PROD028";"Leela";"Contemporary fun chair";"Une fantaisie contemporaine";"At once contemporary and chic, The ''Leela'' chair makes your strong sense of personal style evident. Stylish, easy-clean, leather-like upholstery makes the cut-out in the back more stunning in the light of its vibrant yellow.";"Tout à la fois chic et contemporaine, la chaise ''Leela'' rend votre sens du style évident. Le revêtement en similicuir, facile d'entretien met en valeur l'ouverture du dossier par son jaune lumineux.";"Width : 19'' – Depth : 23'' – Height : 31''";"Dimensions : Larg. 50 cm – Prof.60 cm – Haut. 80 cm ";"144";"";"PROD028-1.jpg";"MILAN";"yellow";"Leather;Metal";"";"Chairs;Armchairs"
|
||||
"PROD029";"Nibbler";"A modern bar stool";"Un tabouret de bar moderne";"If you're looking for a chic, counter height stool that features clean lines and a modern sensibility, look no further than our ''Nibbler'' stool. A chrome-finished base, oval footrest and adjustable, gas-lift mechanism add to its modern look.";"Si vous recherchez un tabouret haut et chic, n'allez pas plus loin que notre tabouret ''Nibbler'' avec ses lignes pures et sa modernité. Une base chromée, un repose-pieds oval ajustable et un mécanisme à gaz ajoute à son look moderne.";"Dimensions : Width : 19'' – Depth : 18'' – Height : 29''";"Dimensions : Larg 50 cm – Prof. 45 cm – Haut. 75 cm";"78";"";"PROD029-1.jpg";"MAGIS";"black";"Plastic;Metal";"";"Stools"
|
||||
"PROD030";"Ron";"Get a look at the futur";"Une incursion dans le futur";"Get a look at the future — retro style — with our ''Ron'' bar stool! The contemporary design of the seating with a cut-out oval in the back for distinctive character, while the lively range of colours and high gloss make a big style statement. A chrome-finished base, oval footrest and adjustable, gas-lift mechanism add to the fresh look. Eye-catching and fun, the ''ron'' stool is a must-have for today's hottest dining area and bars. ";"Revisitez le futur avec une note retro grâce au tabouret de bar ''Ron''! Le design contemporain de ce siège grâce à l'ouverture ovale dans son dossier et une large gamme de couleurs vives. Son rendu glossy lui donne un style tout particulier. Une base chromée, un repose-pieds oval ajustable et un mécanisme à gaz ajoute à son look moderne. Surprenant et joyeux, le tabouret ''Ron'' est un incontournable des coin repas et des bars les plus branchés";"Dimensions : Width : 19'' – Depth : 18'' – Height : 29''";"Dimensions : Larg 50 cm – Prof. 45 cm – Haut. 75 cm";"96";"";"PROD030-1.jpg;PROD030-2.jpg;PROD030-3.jpg;PROD030-4.jpg;";"OFFUS";"blue;yellow;orange;purple";"Plastic;Metal";"";"Stools"
|
||||
|
||||
|
@@ -36,6 +36,9 @@ INSERT INTO `config` (`name`, `value`, `secured`, `hidden`, `created_at`, `updat
|
||||
('pdf_delivery_file', 'delivery', 0, 0, NOW(), NOW()),
|
||||
('unknown-flag-path','assets/img/flags/unknown.png', 0, 0, NOW(), NOW()),
|
||||
('html_output_trim_level','1', 0, 0, NOW(), NOW()),
|
||||
('default_available_stock', '100', 0, 0, NOW(), NOW()),
|
||||
('information_folder_id', '', 0, 0, NOW(), NOW()),
|
||||
('terms_conditions_content_id', '', 0, 0, NOW(), NOW()),
|
||||
|
||||
('session_config.default', '1', 1, 1, NOW(), NOW()),
|
||||
('default_lang_without_translation', '1', 1, 1, NOW(), NOW()),
|
||||
@@ -59,7 +62,6 @@ INSERT INTO `config` (`name`, `value`, `secured`, `hidden`, `created_at`, `updat
|
||||
('form_firewall_attempts', '6', 0, 0, NOW(), NOW()),
|
||||
('from_firewall_active', '1', 0, 0, NOW(), NOW());
|
||||
|
||||
|
||||
INSERT INTO `config_i18n` (`id`, `locale`, `title`, `description`, `chapo`, `postscriptum`) VALUES
|
||||
(1, 'en_US', 'Class name of the session handler', NULL, NULL, NULL),
|
||||
(2, 'en_US', 'Check available product stock (1) or ignore it (0) when displaying and changing ordered quantity', NULL, NULL, NULL),
|
||||
@@ -90,6 +92,9 @@ INSERT INTO `config_i18n` (`id`, `locale`, `title`, `description`, `chapo`, `pos
|
||||
(27, 'en_US', 'Name of the delivery view in the current PDF template (without extension)', NULL, NULL, NULL),
|
||||
(28, 'en_US', 'The path (relative to the default back-office template) to the image used when no flag image can be found for a country', NULL, NULL, NULL),
|
||||
(29, 'en_US', 'Whitespace trim level of the generated HTML code (0 = none, 1 = medium, 2 = maximum)', NULL, NULL, NULL),
|
||||
(30, 'en_US', 'Default available stock when check-available-stock is set to 0.', NULL, NULL, NULL),
|
||||
(31, 'en_US', 'The ID of the folder containing your information pages : terms, imprint, ...', NULL, NULL, NULL),
|
||||
(32, 'en_US', 'The ID of the ''Terms & Conditions'' content.', NULL, NULL, NULL),
|
||||
(1, 'fr_FR', 'Nom de la classe du gestionnaire de session', NULL, NULL, NULL),
|
||||
(2, 'fr_FR', 'Vérifier la présence de produits en stock (1) ou l''ignorer (0) lors de l''affichage et la modification des quantités commandées', NULL, NULL, NULL),
|
||||
(3, 'fr_FR', 'Nom du modèle de front-office actif', NULL, NULL, NULL),
|
||||
@@ -118,7 +123,11 @@ INSERT INTO `config_i18n` (`id`, `locale`, `title`, `description`, `chapo`, `pos
|
||||
(26, 'fr_FR', 'Nom de la vue de la facture dans le modèle PDF en cours (sans extension)', NULL, NULL, NULL),
|
||||
(27, 'fr_FR', 'Nom de la vue de la livraison dans le modèle PDF en cours (sans extension)', NULL, NULL, NULL),
|
||||
(28, 'fr_FR', 'Le chemin (par rapport au modèle de back-office par défaut) vers l''image utilisée lorsque aucune image de drapeau ne peut être trouvée pour un pays', NULL, NULL, NULL),
|
||||
(29, 'fr_FR', 'Niveau de découpe des espaces dans le code HTML généré (0 = aucun, 1 = moyen, 2 = maximum)', NULL, NULL, NULL);
|
||||
(29, 'fr_FR', 'Niveau de découpe des espaces dans le code HTML généré (0 = aucun, 1 = moyen, 2 = maximum)', NULL, NULL, NULL),
|
||||
(30, 'fr_FR', 'Stock disponible par défaut quand check-available-stock est à 0.', NULL, NULL, NULL),
|
||||
(31, 'fr_FR', 'L''ID du dossier contenant vos pages d''informations : CGV, mentions légales, ...', NULL, NULL, NULL),
|
||||
(32, 'fr_FR', 'L''ID du contenu de vos ''CGV''.', NULL, NULL, NULL);
|
||||
|
||||
|
||||
INSERT INTO `module` (`id`, `code`, `type`, `activate`, `position`, `full_namespace`, `created_at`, `updated_at`) VALUES
|
||||
(1, 'TheliaDebugBar', 1, 1, 1, 'TheliaDebugBar\\TheliaDebugBar', NOW(), NOW()),
|
||||
|
||||
@@ -9,6 +9,32 @@ UPDATE `config` SET `value`='' WHERE `name`='thelia_extra_version';
|
||||
INSERT INTO `config` (`name`, `value`, `secured`, `hidden`, `created_at`, `updated_at`) VALUES
|
||||
('store_description', '', 0, 0, NOW(), NOW());
|
||||
|
||||
# default available stock
|
||||
|
||||
INSERT INTO `config` (`name`, `value`, `secured`, `hidden`, `created_at`, `updated_at`) VALUES
|
||||
('default_available_stock', '100', 0, 0, NOW(), NOW());
|
||||
|
||||
SELECT @max := MAX(`id`) FROM `config`;
|
||||
|
||||
INSERT INTO `config_i18n` (`id`, `locale`, `title`, `description`, `chapo`, `postscriptum`) VALUES
|
||||
(@max, 'en_US', 'Default available stock when check-available-stock is set to 0.', NULL, NULL, NULL),
|
||||
(@max, 'fr_FR', 'Stock disponible par défaut quand check-available-stock est à 0.', NULL, NULL, NULL);
|
||||
|
||||
# default information, terms and conditions
|
||||
|
||||
INSERT INTO `config` (`name`, `value`, `secured`, `hidden`, `created_at`, `updated_at`) VALUES
|
||||
('information_folder_id', '', 0, 0, NOW(), NOW()),
|
||||
('terms_conditions_content_id', '', 0, 0, NOW(), NOW());
|
||||
|
||||
SELECT @max := MAX(`id`) FROM `config`;
|
||||
|
||||
INSERT INTO `config_i18n` (`id`, `locale`, `title`, `description`, `chapo`, `postscriptum`) VALUES
|
||||
(@max - 1, 'en_US', 'The ID of the folder containing your information pages : terms, imprint, ...', NULL, NULL, NULL),
|
||||
(@max, 'en_US', 'The ID of the ''Terms & Conditions'' content.', NULL, NULL, NULL),
|
||||
(@max - 1, 'fr_FR', 'L''ID du dossier contenant vos pages d''informations : CGV, mentions légales, ...', NULL, NULL, NULL),
|
||||
(@max, 'fr_FR', 'L''ID du contenu de vos ''CGV''.', NULL, NULL, NULL);
|
||||
|
||||
|
||||
# Add new column to order (version, version_created_at, version_created_by)
|
||||
|
||||
ALTER TABLE `order` ADD `version` INT DEFAULT 0 AFTER `updated_at`;
|
||||
|
||||
@@ -219,6 +219,7 @@ return array(
|
||||
'Current version' => 'Current version',
|
||||
'Customer' => 'Customer',
|
||||
'Customer export' => 'Customer export',
|
||||
'Customer information' => 'Customer information',
|
||||
'Customer informations' => 'Customer information',
|
||||
'Customer is' => 'Customer is',
|
||||
'Customers' => 'Customers',
|
||||
@@ -352,6 +353,7 @@ return array(
|
||||
'E-mail templates' => 'E-mail templates',
|
||||
'EAN Code' => 'EAN Code',
|
||||
'Ecotax is a tax wich add a defined amount (throug a product feature) to the product price.' => 'Ecotax is a tax wich add a defined amount (throug a product feature) to the product price.',
|
||||
'Edit Prices' => 'Edit Prices',
|
||||
'Edit a country' => 'Edit a country',
|
||||
'Edit a currency' => 'Edit a currency',
|
||||
'Edit a customer' => 'Edit a customer',
|
||||
@@ -478,6 +480,7 @@ return array(
|
||||
'Enter new value position' => 'Enter new value position',
|
||||
'Enter one or more IP V4 addresses separated by ";". Leave empty to display logs for all IP addresses' => 'Enter one or more IP V4 addresses separated by ";". Leave empty to display logs for all IP addresses',
|
||||
'Enter one or more file names without path separated by ";". Use "!" before a file name to exclude it. Use "*" to activate logs for all files.' => 'Enter one or more file names without path separated by ";". Use "!" before a file name to exclude it. Use "*" to activate logs for all files.',
|
||||
'Enter quantity' => 'Enter quantity',
|
||||
'Error' => 'Error',
|
||||
'Example :' => 'Example :',
|
||||
'Existing combinations will be deleted. Do you want to continue ?' => 'Existing combinations will be deleted. Do you want to continue ?',
|
||||
@@ -1024,6 +1027,7 @@ return array(
|
||||
'order amount' => 'order amount',
|
||||
'orders for this customer' => 'orders for this customer',
|
||||
'permanent discount' => 'permanent discount (in percent)',
|
||||
'ref.:' => 'ref.:',
|
||||
'short description' => 'short description',
|
||||
'tax rules' => 'tax rules',
|
||||
'taxes' => 'taxes',
|
||||
|
||||
@@ -219,6 +219,7 @@ return array(
|
||||
'Current version' => 'Version en cours',
|
||||
'Customer' => 'Client',
|
||||
'Customer export' => 'Export client',
|
||||
'Customer information' => 'Information client',
|
||||
'Customer informations' => 'Informations client',
|
||||
'Customer is' => 'Le client',
|
||||
'Customers' => 'Clients',
|
||||
@@ -352,6 +353,7 @@ return array(
|
||||
'E-mail templates' => 'Templates E-mail',
|
||||
'EAN Code' => 'Code EAN',
|
||||
'Ecotax is a tax wich add a defined amount (throug a product feature) to the product price.' => 'L\'écotaxe est une taxe qui ajoute un montant défini (grâce à une caractéristique produit) au prix du produit.',
|
||||
'Edit Prices' => 'Modifier les prix',
|
||||
'Edit a country' => 'Modifier un pays',
|
||||
'Edit a currency' => 'Modifier une devise',
|
||||
'Edit a customer' => 'Éditer un client',
|
||||
@@ -478,6 +480,7 @@ return array(
|
||||
'Enter new value position' => 'Entrez une nouvelle position',
|
||||
'Enter one or more IP V4 addresses separated by ";". Leave empty to display logs for all IP addresses' => 'Entrer une ou plusieurs adresse IP (V4) séparés pas des ";". Laisser vide pour afficher les logs pour toutes les adresses IP',
|
||||
'Enter one or more file names without path separated by ";". Use "!" before a file name to exclude it. Use "*" to activate logs for all files.' => 'entrer un ou plusieurs nom de fichiers, séparés par des ";". Utiliser "!" avant le nom d\'un fichier pour l\'exclure. Utiliser "*" pour activer les logs sur tous les fichiers',
|
||||
'Enter quantity' => 'Entrez la quantité',
|
||||
'Error' => 'Erreur',
|
||||
'Example :' => 'Exemple :',
|
||||
'Existing combinations will be deleted. Do you want to continue ?' => 'Les combinaisons existantes seront supprimées. Voulez-vous continuer ?',
|
||||
@@ -846,7 +849,7 @@ return array(
|
||||
'Template title' => 'Titre du gabarit',
|
||||
'Templates' => 'Gabarits de produit',
|
||||
'Text version of this message' => 'Version texte du message',
|
||||
'The default pricing is used when no combination is defined.' => 'Le prix pas défaut est utilisez lorsqu\'aucune combinaison n\'est utilisé',
|
||||
'The default pricing is used when no combination is defined.' => 'Le prix par défaut est utilisé lorsqu\'aucune combinaison n\'est utilisée',
|
||||
'The destinations processes logs to display, store or send them. You can select and configure zero, one or more destinations below.' => 'Les destinations permettent d\'afficher, stocker ou bien envoyer les logs. Vous pouvez en sélectionner zéro, un ou plusieurs dans la liste ci-dessous',
|
||||
'The detailed description.' => 'La description détaillée.',
|
||||
'The mailing template in HTML format.' => 'Le template de mailing au format HTML',
|
||||
@@ -854,7 +857,7 @@ return array(
|
||||
'The page you\'ve requested was not found. Please check the page address, and try again.' => 'La page désirée n\'existe pas. Merci de vérifier votre adresse et réessayer',
|
||||
'The rate from Euro (Price in Euro * rate = Price in this currency)' => 'Le taux à partir de l\'Euro (Prix en Euro * taux = Prix dans la devise)',
|
||||
'The selected categories :' => 'Dans les catégories sélectionnées :',
|
||||
'The selected countries :' => 'Les propduits sélectionnés',
|
||||
'The selected countries :' => 'Les pays sélectionnés',
|
||||
'The selected customer :' => 'Les clients sélectionnés',
|
||||
'The selected products :' => 'Les produits sélectionnés',
|
||||
'The server returned a "404 Not Found"' => 'Le serveur a retourné une erreur "404 Not Found"',
|
||||
@@ -1024,6 +1027,7 @@ return array(
|
||||
'order amount' => 'Montant de la commande',
|
||||
'orders for this customer' => 'commandes pour ce client',
|
||||
'permanent discount' => 'Remise permanente (en pourcentage)',
|
||||
'ref.:' => 'réf.:',
|
||||
'short description' => 'description court',
|
||||
'tax rules' => 'règles de taxe',
|
||||
'taxes' => 'taxes',
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{default_translation_domain domain='bo.default'}
|
||||
<div id="condition-add-operators-values" class="form-group">
|
||||
<label for="operator">{$label}</label>
|
||||
<div class="row">
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{default_translation_domain domain='bo.default'}
|
||||
<div class="form-group">
|
||||
<label for="operator">{intl l="Products are :"}</label>
|
||||
{$operatorSelectHtml nofilter}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{default_translation_domain domain='bo.default'}
|
||||
<div class="form-group">
|
||||
<label for="operator">{intl l="Products are :"}</label>
|
||||
{$operatorSelectHtml nofilter}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{default_translation_domain domain='bo.default'}
|
||||
<div id="condition-add-operators-values" class="form-group">
|
||||
<label for="operator">{$label}</label>
|
||||
<div class="row">
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{default_translation_domain domain='bo.default'}
|
||||
<div class="form-group">
|
||||
|
||||
<label for="operator">{$label}</label>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{default_translation_domain domain='bo.default'}
|
||||
<select class="form-control" id="{$inputKey}-operator" name="{$inputKey}[operator]">
|
||||
{foreach $operators as $key => $operator}
|
||||
<option value="{$key}"{if $key == $value}selected="selected"{/if}>{$operator}</option>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{default_translation_domain domain='bo.default'}
|
||||
<div class="form-group">
|
||||
<label for="operator">{$countryLabel}</label>
|
||||
{$operatorSelectHtml nofilter}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{default_translation_domain domain='bo.default'}
|
||||
<select class="form-control" id="{$inputKey}-value" name="{$inputKey}[value]">
|
||||
{foreach $currencies as $key => $currency}
|
||||
<option value="{$key}"{if $key == $value}selected="selected"{/if}>{$currency}</option>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{default_translation_domain domain='bo.default'}
|
||||
<div class="form-group">
|
||||
<label for="operator">{intl l="Customer is"}</label>
|
||||
{$operatorSelectHtml nofilter}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<input type="number" value="{$value}" class="form-control" id="{$inputKey}-value" name="{$inputKey}[value]" placeholder="Enter quantity" />
|
||||
|
||||
<input type="number" value="{$value}" class="form-control" id="{$inputKey}-value" name="{$inputKey}[value]" placeholder="{intl l='Enter quantity'}" />
|
||||
{* Use a text field instead
|
||||
<select class="form-control" id="{$inputKey}-value" name="{$inputKey}[value]">
|
||||
{for $index=$min to $max}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
{default_translation_domain domain='bo.default'}
|
||||
|
||||
<input type="hidden" name="{$fieldName}[operator]" value="{$criteria}" />
|
||||
|
||||
<div id="condition-add-operators-values" class="form-group">
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
{default_translation_domain domain='bo.default'}
|
||||
|
||||
{block name="discount-field"}{/block}
|
||||
|
||||
<div class="form-group input-coupon-attribute-id">
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
{default_translation_domain domain='bo.default'}
|
||||
|
||||
{block name="discount-field"}{/block}
|
||||
|
||||
<div class="form-group input-coupon-categories-id">
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
{default_translation_domain domain='bo.default'}
|
||||
|
||||
{block name="discount-field"}{/block}
|
||||
|
||||
<div class="form-group input-coupon-category-id">
|
||||
|
||||
@@ -226,10 +226,6 @@
|
||||
<input type="hidden" name="{$name}" value="random" />
|
||||
{/form_field}
|
||||
|
||||
{form_field form=$form field="agreed"}
|
||||
<input type="hidden" name="{$name}" value="on" />
|
||||
{/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">{$label} : </label>
|
||||
|
||||
@@ -40,9 +40,7 @@
|
||||
{$label} :
|
||||
</label>
|
||||
<div class="control-input">
|
||||
{* If ref's 'value is not empty the field is disable and the value is sent with an hidden field *}
|
||||
<input type="text" id="{$label_attr.for}" {if $value}name="{$name}_disabled" disabled{else}name="{$name}"{/if} class="form-control" value="{$value}"{if $required} aria-required="true" required{/if}>
|
||||
{if $value}<input type="hidden" name="{$name}" value="{$value}">{/if}
|
||||
<input type="text" id="{$label_attr.for}" name="{$name}" class="form-control" value="{$value}"{if $required} aria-required="true" required{/if}>
|
||||
</div>
|
||||
</div>
|
||||
{/form_field}
|
||||
|
||||
@@ -228,13 +228,13 @@
|
||||
|
||||
<tbody>
|
||||
{loop type="product" name="product-search" visible="*" search_mode="sentence" search_term=trim($smarty.get.search_term) search_in="ref,title"}
|
||||
|
||||
{$id_product=$ID}
|
||||
<tr>
|
||||
<td>{$ID}</td>
|
||||
|
||||
<td>
|
||||
{loop type="image" name="cat_image" source="product" source_id="$ID" limit="1" width="50" height="50" resize_mode="crop" backend_context="1"}
|
||||
<a href="{url path='/admin/products/update' product_id=$ID}" title="{intl l='Edit this product'}">
|
||||
<a href="{url path='/admin/products/update' product_id=$id_product}" title="{intl l='Edit this product'}">
|
||||
<img src="{$IMAGE_URL}" alt="{$TITLE}" />
|
||||
</a>
|
||||
{/loop}
|
||||
|
||||
@@ -77,7 +77,7 @@ return array(
|
||||
'Google+' => 'Google+',
|
||||
'Grid' => 'Grid',
|
||||
'Home' => 'Home',
|
||||
'I\'ve read and agreed on <a href=\'#\'>Terms & Conditions</a>' => 'I\'ve read and agreed on <a href=\'#\'>Terms & Conditions</a>',
|
||||
'I\'ve read and agreed on <a href=\'%link\' class=\'terms-quickview\'>Terms & Conditions</a>' => 'I\'ve read and agreed on <a href=\'%link\' class=\'terms-quickview\'>Terms & Conditions</a>',
|
||||
'If nothing happens within 10 seconds, <a id="force-submit-payment-form" href="#">please click here</a>.' => 'Si rien ne se passe dans les 10 prochaines secondes, <a id="force-submit-payment-form" href="#">merci de cliquer ici</a>. ',
|
||||
'In Stock' => 'In Stock',
|
||||
'Instagram' => 'Instagram',
|
||||
@@ -110,7 +110,7 @@ return array(
|
||||
'Next' => 'Next',
|
||||
'Next Step' => 'Next Step',
|
||||
'Next product' => 'Next product',
|
||||
'No Content in this folder.' => 'No Content in this folder.',
|
||||
'No Contents in this folder.' => 'No Contents in this folder.',
|
||||
'No articles currently' => 'No articles currently',
|
||||
'No deliveries available for this cart and this country' => 'No deliveries available for this cart and this country',
|
||||
'No products available in this brand' => 'No products available in this brand',
|
||||
@@ -193,22 +193,29 @@ return array(
|
||||
'Sign In' => 'Sign In',
|
||||
'Sign up to receive our latest news.' => 'Sign up to receive our latest news.',
|
||||
'Skip to content' => 'Skip to content',
|
||||
'Sorry but this combination does not exist.' => 'Sorry but this combination does not exist.',
|
||||
'Sorry, your cart is empty. There\'s nothing to pay.' => 'Désolé, mais votre panier est vide. Il n\'y a rien à payer.',
|
||||
'Sort By' => 'Sort By',
|
||||
'Special Price:' => 'Special Price:',
|
||||
'Status' => 'Status',
|
||||
'Subscribe' => 'Subscribe',
|
||||
'Taxed Price' => 'Taxed Price',
|
||||
'Thank you for the trust you place in us.' => 'Thank you for the trust you place in us.',
|
||||
'Thanks !' => 'Thanks !',
|
||||
'Thanks for signing up! We\'ll keep you posted whenever we have any new updates.' => 'Thanks for signing up! We\'ll keep you posted whenever we have any new updates.',
|
||||
'Thanks for your message, we will contact as soon as possible.' => 'Thanks for your message, we will contact as soon as possible.',
|
||||
'The page cannot be found' => 'The page cannot be found',
|
||||
'The product has been added to your cart' => 'The product has been added to your cart',
|
||||
'Thelia V2' => 'Thelia V2',
|
||||
'Toggle navigation' => 'Toggle navigation',
|
||||
'Total' => 'Total',
|
||||
'Total excl. taxes' => 'Total excl. taxes',
|
||||
'Total incl. taxes' => 'Total incl. taxes',
|
||||
'Try again' => 'Merci de ré-essayer.',
|
||||
'Twitter' => 'Twitter',
|
||||
'Unit Price' => 'Unit Price',
|
||||
'Unit Price incl. taxes' => 'Unit Price incl. taxes',
|
||||
'Unit Taxed Price' => 'Unit Taxed Price',
|
||||
'Update' => 'Update',
|
||||
'Update Profile' => 'Update Profile',
|
||||
'Update Quantity' => 'Update Quantity',
|
||||
|
||||
@@ -77,7 +77,7 @@ return array(
|
||||
'Google+' => 'Google+',
|
||||
'Grid' => 'Grille',
|
||||
'Home' => 'Accueil',
|
||||
'I\'ve read and agreed on <a href=\'#\'>Terms & Conditions</a>' => 'J\'ai lu et j\'accepte les <a href=\'#\'>CGV</a>',
|
||||
'I\'ve read and agreed on <a href=\'%link\' class=\'terms-quickview\'>Terms & Conditions</a>' => 'J\'ai lu et j\'accepte <a href=\'%link\' class=\'terms-quickview\'>les conditions générales de vente</a>',
|
||||
'If nothing happens within 10 seconds, <a id="force-submit-payment-form" href="#">please click here</a>.' => 'Si rien ne se passe dans les 10 secondes, <a id="force-submit-payment-form" href="#">meri de cliquer ici</a>. ',
|
||||
'In Stock' => 'Disponible',
|
||||
'Instagram' => 'Instagram',
|
||||
@@ -110,7 +110,7 @@ return array(
|
||||
'Next' => 'Suivant',
|
||||
'Next Step' => 'Etape suivante',
|
||||
'Next product' => 'Produit suivant.',
|
||||
'No Content in this folder.' => 'Aucun contenu dans ce dossier.',
|
||||
'No Contents in this folder.' => 'Aucun contenu pour ce dossier.',
|
||||
'No articles currently' => 'Aucun article en ce moment',
|
||||
'No deliveries available for this cart and this country' => 'Aucun mode de livraison disponible pour ce panier et ce pays',
|
||||
'No products available in this brand' => 'Aucun produit de cette marque n\'est disponible',
|
||||
@@ -193,22 +193,29 @@ return array(
|
||||
'Sign In' => 'Se connecter',
|
||||
'Sign up to receive our latest news.' => 'Inscrivez-vous pour recevoir les dernières nouveautés.',
|
||||
'Skip to content' => 'Aller au contenu',
|
||||
'Sorry but this combination does not exist.' => 'Désolé, cette déclinaison n\'existe pas.',
|
||||
'Sorry, your cart is empty. There\'s nothing to pay.' => 'Désolé, votre panier est vide. Il n\'y a rien à payer.',
|
||||
'Sort By' => 'Trier par',
|
||||
'Special Price:' => 'Prix promo',
|
||||
'Status' => 'Etat',
|
||||
'Subscribe' => 'Inscription',
|
||||
'Taxed Price' => 'Prix TTC',
|
||||
'Thank you for the trust you place in us.' => 'Merci pour votre confiance. ',
|
||||
'Thanks !' => 'Merci !',
|
||||
'Thanks for signing up! We\'ll keep you posted whenever we have any new updates.' => 'Merci de votre inscription ! Nous vous tiendrons informé dès qu\'il y aura des nouveautés.',
|
||||
'Thanks for your message, we will contact as soon as possible.' => 'Merci de votre message, nous vous contacterons dès que possible.',
|
||||
'The page cannot be found' => 'La page ne peut pas être trouvée',
|
||||
'The product has been added to your cart' => 'Le produit a été ajouté à votre panier',
|
||||
'Thelia V2' => 'Thelia v2',
|
||||
'Toggle navigation' => 'Basculer la navigation',
|
||||
'Total' => 'Total',
|
||||
'Total excl. taxes' => 'Total HT',
|
||||
'Total incl. taxes' => 'Total TTC',
|
||||
'Try again' => 'Ré-essayer le paiement',
|
||||
'Twitter' => 'Twitter',
|
||||
'Unit Price' => 'Prix unitaire',
|
||||
'Unit Price incl. taxes' => 'Prix unitaire HT',
|
||||
'Unit Taxed Price' => 'Prix unitaire TTC',
|
||||
'Update' => 'Mettre à jour',
|
||||
'Update Profile' => 'Mettre à jour votre profil',
|
||||
'Update Quantity' => 'Mettre à jour la quantité',
|
||||
|
||||
@@ -26,7 +26,12 @@
|
||||
{loop name="customer.update" type="address" customer="current" id="{$address_id}"}
|
||||
<form id="form-address" class="form-horizontal" action="{url path="/address/update/{$address_id}"}" method="post">
|
||||
{form_field form=$form field='success_url'}
|
||||
<input type="hidden" name="{$name}" value="{url path="/account"}" />
|
||||
{if $value}
|
||||
{$next_url=$value}
|
||||
{else}
|
||||
{$next_url=$smarty.get.next|default:{url path="/account"}}
|
||||
{/if}
|
||||
<input type="hidden" name="{$name}" value="{$next_url}" />
|
||||
{/form_field}
|
||||
|
||||
{form_field form=$form field='error_message'}
|
||||
|
||||
@@ -25,7 +25,12 @@
|
||||
{form name="thelia.front.address.create"}
|
||||
<form id="form-address" class="form-horizontal" action="{url path="/address/create"}" method="post">
|
||||
{form_field form=$form field='success_url'}
|
||||
<input type="hidden" name="{$name}" value="{url path="/account"}" />
|
||||
{if $value}
|
||||
{$next_url=$value}
|
||||
{else}
|
||||
{$next_url=$smarty.get.next|default:{url path="/account"}}
|
||||
{/if}
|
||||
<input type="hidden" name="{$name}" value="{$next_url}" />
|
||||
{/form_field}
|
||||
|
||||
{form_field form=$form field='error_message'}
|
||||
|
||||
@@ -21,6 +21,303 @@
|
||||
}
|
||||
}());
|
||||
|
||||
|
||||
var pseManager = (function($){
|
||||
|
||||
// cache dom elements
|
||||
var manager = {};
|
||||
var $pse = {};
|
||||
|
||||
function init(){
|
||||
$pse = {
|
||||
"id": $("#pse-id"),
|
||||
"product": $("#product"),
|
||||
"name": $("#pse-name"),
|
||||
"ref": $("#pse-ref"),
|
||||
"ean": $("#pse-ean"),
|
||||
"availability": $("#pse-availability"),
|
||||
"validity": $("#pse-validity"),
|
||||
"quantity": $("#quantity"),
|
||||
"promo": $("#pse-promo"),
|
||||
"new": $("#pse-new"),
|
||||
"weight": $("#pse-weight"),
|
||||
"price": $("#pse-price"),
|
||||
"priceOld": $("#pse-price-old"),
|
||||
"submit": $("#pse-submit"),
|
||||
"options": {},
|
||||
"pseId": null,
|
||||
"useFallback": false,
|
||||
"fallback": $("#pse-options .pse-fallback")
|
||||
};
|
||||
}
|
||||
|
||||
function buildProductForm() {
|
||||
var pse = null,
|
||||
combinationId = null,
|
||||
combinationValue = null,
|
||||
combinationValueId = null,
|
||||
combinations = null,
|
||||
combinationName = [],
|
||||
i;
|
||||
|
||||
// initialization for the first default pse
|
||||
$pse.pseId = $pse.id.val();
|
||||
|
||||
if (PSE_COUNT > 1) {
|
||||
// Use fallback method ?
|
||||
$pse.useFallback = useFallback();
|
||||
|
||||
if ($pse.useFallback) {
|
||||
$("#pse-options .option-option").remove();
|
||||
|
||||
for (pse in PSE){
|
||||
combinations = PSE[pse].combinations;
|
||||
combinationName = [];
|
||||
for (i = 0; i < combinations.length; i++){
|
||||
combinationName.push(PSE_COMBINATIONS_VALUE[combinations[i]][0]);
|
||||
}
|
||||
$pse.fallback
|
||||
.append("<option value='" + pse + "'>"
|
||||
+ combinationName.join(', ') + "</option>");
|
||||
}
|
||||
|
||||
$("#pse-options .pse-fallback").on("change",function(){
|
||||
updateProductForm();
|
||||
});
|
||||
|
||||
} else {
|
||||
$("#pse-options .option-fallback").remove();
|
||||
|
||||
// get the select for options
|
||||
$("#pse-options .pse-option").each(function(){
|
||||
var $option = $(this);
|
||||
if ( $option.data("attribute") in PSE_COMBINATIONS){
|
||||
$pse['options'][$option.data("attribute")] = $option;
|
||||
$option.on("change", updateProductForm);
|
||||
} else {
|
||||
// not affected to this product -> remove
|
||||
$option.closest(".option").remove();
|
||||
}
|
||||
});
|
||||
|
||||
// build select
|
||||
for (combinationValueId in PSE_COMBINATIONS_VALUE) {
|
||||
combinationValue = PSE_COMBINATIONS_VALUE[combinationValueId];
|
||||
$pse.options[combinationValue[1]]
|
||||
.append("<option value='" + combinationValueId + "'>"
|
||||
+ combinationValue[0] + "</option>");
|
||||
}
|
||||
|
||||
setPseForm();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setPseForm(id) {
|
||||
var i = 0,
|
||||
pse = null,
|
||||
combinationValueId;
|
||||
pse = PSE[id || $pse.pseId];
|
||||
if ($pse.useFallback) {
|
||||
$pse.fallbak.val(pse.id);
|
||||
} else {
|
||||
for (var i=0; i<pse.combinations.length; i++){
|
||||
combinationValueId = pse.combinations[i];
|
||||
$pse['options'][PSE_COMBINATIONS_VALUE[combinationValueId][1]].val(pse.combinations[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateProductForm() {
|
||||
var pseId = null,
|
||||
selection;
|
||||
|
||||
if (PSE_COUNT > 1) {
|
||||
|
||||
if ($pse.useFallback) {
|
||||
pseId = $pse.fallback.val();
|
||||
} else {
|
||||
// get form data
|
||||
selection = getFormSelection();
|
||||
// get the pse
|
||||
pseId = pseExist(selection);
|
||||
|
||||
if ( ! pseId ) {
|
||||
// not exists, revert
|
||||
displayNotice();
|
||||
setPseForm();
|
||||
} else {
|
||||
$pse.validity.hide();
|
||||
}
|
||||
}
|
||||
|
||||
$pse.id.val(pseId);
|
||||
$pse.pseId = pseId;
|
||||
}
|
||||
|
||||
// Update UI
|
||||
updateProductUI();
|
||||
}
|
||||
|
||||
function displayNotice() {
|
||||
var $validity = $pse.validity;
|
||||
$validity.show('fast', function(){
|
||||
setTimeout(function(){
|
||||
$validity.hide('fast');
|
||||
}, 3000);
|
||||
});
|
||||
}
|
||||
|
||||
function updateProductUI() {
|
||||
var pse = PSE[$pse.pseId],
|
||||
name = [],
|
||||
pseValueId,
|
||||
i
|
||||
;
|
||||
|
||||
$pse.ref.html(pse.ref);
|
||||
// $pse.ean.html(pse.ean);
|
||||
// name
|
||||
if (PSE_COUNT > 1) {
|
||||
|
||||
for (i = 0; i < pse.combinations.length; i++){
|
||||
pseValueId = pse.combinations[i]
|
||||
name.push(
|
||||
//PSE_COMBINATIONS[PSE_COMBINATIONS_VALUE[pseValueId][1]].name +
|
||||
//":" +
|
||||
PSE_COMBINATIONS_VALUE[pseValueId][0]
|
||||
)
|
||||
}
|
||||
|
||||
$pse.name.html(" - " + name.join(", ") + "");
|
||||
}
|
||||
|
||||
// promo
|
||||
if (pse.isPromo) {
|
||||
$pse.product.addClass("product--is-promo");
|
||||
} else {
|
||||
$pse.product.removeClass("product--is-promo");
|
||||
}
|
||||
|
||||
// new
|
||||
if (pse.isNew) {
|
||||
$pse.product.addClass("product--is-new");
|
||||
} else {
|
||||
$pse.product.removeClass("product--is-new");
|
||||
}
|
||||
|
||||
// availability
|
||||
if (pse.quantity > 0 || ! PSE_CHECK_AVAILABILITY) {
|
||||
$pse.availability
|
||||
.removeClass("out-of-stock")
|
||||
.addClass("in-stock")
|
||||
.attr("href", "http://schema.org/InStock");
|
||||
|
||||
if (parseInt($pse.quantity.val()) > pse.quantity){
|
||||
$pse.quantity.val(pse.quantity);
|
||||
}
|
||||
|
||||
if (PSE_CHECK_AVAILABILITY) {
|
||||
$pse.quantity.attr("max", pse.quantity);
|
||||
} else {
|
||||
$pse.quantity.attr("max", PSE_DEFAULT_AVAILABLE_STOCK);
|
||||
}
|
||||
$pse.submit.prop("disabled", false);
|
||||
|
||||
} else {
|
||||
$pse.availability.removeClass("in-stock")
|
||||
.addClass("out-of-stock")
|
||||
.attr("href", "http://schema.org/OutOfStock");
|
||||
|
||||
$pse.submit.prop("disabled", true);
|
||||
}
|
||||
|
||||
// price
|
||||
if (pse.isPromo){
|
||||
$pse.priceOld.html(pse.price);
|
||||
$pse.price.html(pse.promo);
|
||||
} else {
|
||||
$pse.priceOld.html("");
|
||||
$pse.price.html(pse.price);
|
||||
}
|
||||
}
|
||||
|
||||
function pseExist(selection) {
|
||||
var pseId,
|
||||
pse = null,
|
||||
combinations,
|
||||
i,
|
||||
j,
|
||||
existCombination;
|
||||
|
||||
for (pse in PSE){
|
||||
pseId = pse;
|
||||
combinations = PSE[pse].combinations;
|
||||
for (i = 0; i < selection.length; i++){
|
||||
existCombination = false;
|
||||
for (j = 0; j < combinations.length; j++){
|
||||
if (selection[i] == combinations[j]){
|
||||
existCombination = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (existCombination === false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (existCombination) {
|
||||
return pseId;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function useFallback() {
|
||||
var pse = null,
|
||||
count = -1,
|
||||
pseCount = 0,
|
||||
combinations,
|
||||
i;
|
||||
|
||||
for (pse in PSE){
|
||||
combinations = PSE[pse].combinations;
|
||||
pseCount = 0;
|
||||
for (i = 0; i < combinations.length; i++) {
|
||||
pseCount += PSE_COMBINATIONS_VALUE[combinations[i]][1];
|
||||
}
|
||||
if (count == -1){
|
||||
count = pseCount;
|
||||
} else if (count != pseCount) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return (count <= 0);
|
||||
}
|
||||
|
||||
function getFormSelection() {
|
||||
var selection = [],
|
||||
combinationId;
|
||||
|
||||
for (combinationId in $pse.options){
|
||||
selection.push($pse.options[combinationId].val());
|
||||
}
|
||||
|
||||
return selection;
|
||||
}
|
||||
|
||||
manager.load = function(){
|
||||
init();
|
||||
buildProductForm();
|
||||
updateProductForm();
|
||||
}
|
||||
|
||||
return manager;
|
||||
|
||||
}(jQuery));
|
||||
|
||||
|
||||
/* JQUERY PREVENT CONFLICT */
|
||||
(function ($) {
|
||||
|
||||
@@ -129,6 +426,7 @@
|
||||
bootbox.hideAll();
|
||||
}
|
||||
});
|
||||
window.pseManager.load();
|
||||
}
|
||||
);
|
||||
return false;
|
||||
@@ -137,15 +435,20 @@
|
||||
});
|
||||
|
||||
// Product AddtoCard - OnSubmit
|
||||
$(document).on('submit.form-product', '.form-product', function () {
|
||||
if (typeof window.PSE_FORM !== "undefined"){
|
||||
window.pseManager.load();
|
||||
}
|
||||
|
||||
$(document).on('submit.form-product', '.form-product', function () {
|
||||
if (doAjax) {
|
||||
var url_action = $(this).attr("action"),
|
||||
product_id = $("input[name$='product_id']",this).val();
|
||||
|
||||
product_id = $("input[name$='product_id']",this).val(),
|
||||
pse_id = $("input#pse-id",this).val();
|
||||
|
||||
$.ajax({type: "POST", data: $(this).serialize(), url: url_action,
|
||||
success: function(data){
|
||||
$(".cart-container").html($(data).html());
|
||||
$.ajax({url:"ajax/addCartMessage", data:{ product_id: product_id },
|
||||
$.ajax({url:"ajax/addCartMessage", data:{ product_id: product_id, pse_id: pse_id },
|
||||
success: function (data) {
|
||||
// Hide all currently active bootbox dialogs
|
||||
bootbox.hideAll();
|
||||
@@ -167,51 +470,7 @@
|
||||
}
|
||||
return;
|
||||
});
|
||||
|
||||
$(document).on('change.quantity', 'select:has([data-quantity])', function () {
|
||||
var $productDetails = $(this).closest("#product-details"),
|
||||
$stockInformation = $("#stock-information", $productDetails),
|
||||
$quantityInput = $("#quantity", $productDetails),
|
||||
$btnAddToCart = $(".btn_add_to_cart", $productDetails);
|
||||
|
||||
var $current = $(":selected", this);
|
||||
var qty = $current.data("quantity");
|
||||
|
||||
// Show Out Of Stock OR In Stock
|
||||
if (qty == 0) {
|
||||
// Disable button
|
||||
$btnAddToCart.attr("disabled", true);
|
||||
|
||||
// Update stock information
|
||||
$stockInformation
|
||||
.removeClass("in-stock")
|
||||
.addClass("out-of-stock")
|
||||
.attr("href", "http://schema.org/OutOfStock");
|
||||
|
||||
} else {
|
||||
// Active button
|
||||
$btnAddToCart.attr("disabled", false);
|
||||
|
||||
// Update Field Quantity if the current value is over Max
|
||||
if (parseInt($quantityInput.val()) > parseInt(qty)) {
|
||||
$quantityInput.val(qty);
|
||||
}
|
||||
|
||||
// Update stock information
|
||||
$stockInformation
|
||||
.removeClass("out-of-stock")
|
||||
.addClass("in-stock")
|
||||
.attr("href", "http://schema.org/InStock");
|
||||
}
|
||||
|
||||
// HTML5 number attribute
|
||||
$quantityInput.attr("max", qty);
|
||||
|
||||
// Update Prices
|
||||
$(".old-price > .price", $productDetails).html($current.data('old-price'));
|
||||
$(".special-price > .price, .regular-price > .price", $productDetails).html($current.data('price'));
|
||||
|
||||
});
|
||||
|
||||
// Toolbar
|
||||
var $category_products = $ ('#category-products');
|
||||
@@ -353,5 +612,6 @@
|
||||
|
||||
});
|
||||
|
||||
|
||||
})(jQuery);
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
margin-bottom: @line-height-computed;
|
||||
|
||||
.block-subtitle {
|
||||
border-bottom: 1px solid @block-subheading-border;
|
||||
/*border-bottom: 1px solid @block-subheading-border;*/
|
||||
color: @block-subheading-color;
|
||||
font-size: @block-subheading-font-size;
|
||||
font-weight: 300;
|
||||
|
||||
99
templates/frontOffice/default/assets/less/thelia/brand.less
Normal file
@@ -0,0 +1,99 @@
|
||||
// Thelia : Brand
|
||||
|
||||
// Brand Info
|
||||
.brand-chapo {}
|
||||
.brand-description {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
// Content List
|
||||
#brands {
|
||||
.brands > ul { .brands-list; }
|
||||
}
|
||||
|
||||
.brands-grid,
|
||||
.brands-list {
|
||||
// Animation
|
||||
@media (min-width: @screen-tablet) {
|
||||
.brand-image {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
> .mask {
|
||||
background-color: @brand-primary;
|
||||
background-color: rgba(red(@brand-primary), green(@brand-primary), blue(@brand-primary), .4);
|
||||
display: block;
|
||||
.opacity(0);
|
||||
overflow: visible;
|
||||
position: absolute;
|
||||
top: 0; left: 0;
|
||||
visibility: hidden;
|
||||
width: 100%; height: 100%;
|
||||
.transition(opacity 300ms ease-in-out 50ms);
|
||||
}
|
||||
&:hover,
|
||||
&:focus {
|
||||
.mask {
|
||||
visibility: visible;
|
||||
.opacity(1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Contents Grid
|
||||
.brands-grid {
|
||||
.make-row();
|
||||
.list-unstyled();
|
||||
.item { .make-sm-column(4); .make-md-column(4); .clearfix(); } // default
|
||||
&.content-col-2 > .item { .make-md-column(6); }
|
||||
&.content-col-3 > .item { .make-md-column(4); }
|
||||
&.content-col-4 > .item { .make-md-column(3); }
|
||||
&.content-col-5 > .item { .make-md-column(2.4); }
|
||||
&.content-col-6 > .item { .make-md-column(2); }
|
||||
|
||||
.item {
|
||||
margin-bottom: @line-height-computed;
|
||||
|
||||
.brand-image {
|
||||
> img { .img-responsive(); width: 100%; }
|
||||
> .mask {}
|
||||
}
|
||||
|
||||
.brand-info {
|
||||
.name { margin: 4px 0; }
|
||||
.description { .visible-xs; }
|
||||
.short-description { display: block; margin-bottom: 5px; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Content List
|
||||
.brands-list {
|
||||
.list-unstyled();
|
||||
.item {
|
||||
padding-bottom: 15px;
|
||||
+ .item { border-top: 1px solid #ededed; padding-top: 15px; }
|
||||
> article {
|
||||
.make-row();
|
||||
margin-left: 0;
|
||||
|
||||
.brand-image {
|
||||
.make-sm-column(2);
|
||||
margin-bottom: 15px; padding: 0;
|
||||
> img { .img-responsive(); width: 100%; }
|
||||
> .mask {}
|
||||
}
|
||||
|
||||
.brand-info {
|
||||
.make-sm-column(7);
|
||||
.name { margin-top: 0; }
|
||||
.description {}
|
||||
.short-description {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -47,6 +47,12 @@
|
||||
font-size: @font-size-base;
|
||||
}
|
||||
}
|
||||
.secondary-price {
|
||||
.price {
|
||||
font-size: @font-size-base;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.qty {
|
||||
.group-qty {
|
||||
@@ -82,6 +88,21 @@
|
||||
}
|
||||
}
|
||||
|
||||
.table-cart-total{
|
||||
td {
|
||||
width: 50%;
|
||||
&.coupon {}
|
||||
&.total {
|
||||
.price {
|
||||
font-size: ceil(@font-size-base * 1.3);
|
||||
}
|
||||
}
|
||||
&.empty {
|
||||
border-bottom-color: transparent; border-left-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Message if no product in the cart
|
||||
.cart-warning {
|
||||
clear: both;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
// Content List
|
||||
#folder-contents {
|
||||
.contents > ul { .contents-grid; }
|
||||
.contents > ul { .contents-list; }
|
||||
}
|
||||
|
||||
.contents-grid,
|
||||
@@ -75,20 +75,21 @@
|
||||
.contents-list {
|
||||
.list-unstyled();
|
||||
.item {
|
||||
padding-bottom: 15px;
|
||||
+ .item { border-top: 1px solid #ededed; padding-top: 15px; }
|
||||
> article {
|
||||
.make-row();
|
||||
margin-left: 0;
|
||||
|
||||
.content-image {
|
||||
.make-sm-column(3);
|
||||
.make-sm-column(2);
|
||||
margin-bottom: 15px; padding: 0;
|
||||
> img { .img-responsive(); width: 100%; }
|
||||
> .mask {}
|
||||
}
|
||||
|
||||
.content-info {
|
||||
.make-sm-column(6);
|
||||
.make-sm-column(7);
|
||||
.name { margin-top: 0; }
|
||||
.description {}
|
||||
.short-description {}
|
||||
|
||||
@@ -31,6 +31,9 @@
|
||||
// Thelia : Contents
|
||||
@import "folder";
|
||||
|
||||
// Thelia : Brands
|
||||
@import "brand";
|
||||
|
||||
// Thelia : Pages
|
||||
@import "page-home";
|
||||
@import "page-error";
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
// In Stock
|
||||
.in-stock {
|
||||
color: #44B661;
|
||||
color: @brand-success;
|
||||
font-style: italic; font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
}
|
||||
// Out of Stock
|
||||
.out-of-stock {
|
||||
color: #FF0000;
|
||||
color: @brand-warning;
|
||||
font-style: italic; font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
|
||||
@@ -42,6 +42,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
.product-pse-name {
|
||||
|
||||
}
|
||||
|
||||
// Option block
|
||||
.option {
|
||||
|
||||
@@ -330,17 +330,18 @@ td.product,
|
||||
.special-price {
|
||||
.price {
|
||||
display: block;
|
||||
font-size: 20px; line-height: 25px;
|
||||
font-style: italic;
|
||||
font-size: 14px; line-height: 25px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
|
||||
.old-price {
|
||||
.price {
|
||||
display: block;
|
||||
font-size: 18px; line-height: 25px;
|
||||
font-size: 14px; line-height: 25px;
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
font-weight: 400;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
}
|
||||
@@ -606,6 +607,12 @@ td.product,
|
||||
font-size: ceil(@font-size-base * 0.94);
|
||||
margin-top: -8px; margin-bottom: 20px;
|
||||
}
|
||||
.pse-name {
|
||||
color: @gray;
|
||||
font-size: ceil(@font-size-base * 0.94);
|
||||
//margin-left: 10px;
|
||||
}
|
||||
|
||||
}
|
||||
.product-price {
|
||||
.price-container {
|
||||
|
||||
@@ -1,39 +1,53 @@
|
||||
{extends file="layout.tpl"}
|
||||
|
||||
{block name="init"}
|
||||
{$brand_id={brand attr="id"}}
|
||||
{/block}
|
||||
|
||||
{* Body Class *}
|
||||
{block name="body-class"}page-content{/block}
|
||||
{block name="body-class"}page-brand{/block}
|
||||
|
||||
{* Page Title *}
|
||||
{block name='no-return-functions' append}
|
||||
{loop name="brand.seo.title" type="brand" id="{brand attr="id"}"}
|
||||
{if $brand_id}
|
||||
{loop name="brand.seo.title" type="brand" id=$brand_id limit="1"}
|
||||
{$page_title = {$META_TITLE}}
|
||||
{/loop}
|
||||
{/if}
|
||||
{/block}
|
||||
|
||||
{* Meta *}
|
||||
{block name="meta"}
|
||||
{loop name="brand.seo.meta" type="brand" id="{brand attr="id"}"}
|
||||
{if $META_DESCRIPTION}
|
||||
<meta name="description" content="{$META_DESCRIPTION}">{/if}
|
||||
{if $META_KEYWORDS}
|
||||
<meta name="keywords" content="{$META_KEYWORDS}">{/if}
|
||||
{if $brand_id}
|
||||
{loop name="brand.seo.meta" type="brand" id=$brand_id limit="1"}
|
||||
{include file="includes/meta-seo.html"}
|
||||
{/loop}
|
||||
{/if}
|
||||
{/block}
|
||||
|
||||
{* Feeds *}
|
||||
{block name="feeds"}
|
||||
<link rel="alternate" type="application/rss+xml" title="{intl l='All product in brand %title' title={brand attr='title'}}" href="{url path="/feed/brand/{lang attr='locale'}/{brand attr='id'}"}"/>
|
||||
{if $brand_id}
|
||||
<link rel="alternate" type="application/rss+xml" title="{intl l='All product in brand %title' title={brand attr='title'}}" href="{url path="/feed/brand/{lang attr='locale'}/{$brand_id}"}"/>
|
||||
{/if}
|
||||
{/block}
|
||||
|
||||
{* Breadcrumb *}
|
||||
{block name='no-return-functions' append}
|
||||
{if $brand_id}
|
||||
{$breadcrumbs = []}
|
||||
{loop type="brand" name="brand-breadcrumb" id="{brand attr="id"}"}
|
||||
{$breadcrumbs[] = ['title' => {$TITLE}, 'url'=> {$URL}]}
|
||||
{/loop}
|
||||
{if $brand_id}
|
||||
{loop type="brand" name="brand-breadcrumb" id=$brand_id limit="1"}
|
||||
{$breadcrumbs[] = ['title' => {$TITLE}, 'url'=> {$URL}]}
|
||||
{/loop}
|
||||
{else}
|
||||
{$breadcrumbs[] = ['title' => {intl l="All brands"}, 'url'=> '']}
|
||||
{/if}
|
||||
{/if}
|
||||
{/block}
|
||||
|
||||
{block name="main-content"}
|
||||
{if $brand_id}
|
||||
<div class="main layout-col-2-left">
|
||||
{$limit={$smarty.get.limit|default:8}}
|
||||
{$product_page={$smarty.get.page|default:1}}
|
||||
@@ -41,7 +55,7 @@
|
||||
{$mode=$smarty.get.mode|default:'grid'}
|
||||
|
||||
<article class="col-main {$mode}" role="main" aria-labelledby="main-label">
|
||||
{loop name="brand.info" type="brand" current="yes"}
|
||||
{loop name="brand.info" type="brand" id=$brand_id limit="1"}
|
||||
<section class="brand-description">
|
||||
<h1 id="main-label" class="page-header">{$TITLE}</h1>
|
||||
|
||||
@@ -154,4 +168,40 @@
|
||||
</aside>
|
||||
|
||||
</div><!-- /.layout -->
|
||||
{else}
|
||||
<div class="main" id="brands">
|
||||
<div class="col-main brands" role="main" aria-labelledby="main-label">
|
||||
{ifloop rel="brands"}
|
||||
<ul>
|
||||
{loop name="brands" type="brand"}
|
||||
<li class="item">
|
||||
<article>
|
||||
<div class="brand-info">
|
||||
{ifloop rel="brand_logo"}
|
||||
<a href="{$URL}" tabindex="-1" class="brand-image">
|
||||
{loop name="brand_logo" type="image" source="brand" id={$LOGO_IMAGE_ID} width=218 height=146 resize_mode="borders" limit="1"}
|
||||
<img src="{$IMAGE_URL}" alt="{$TITLE}">
|
||||
{/loop}
|
||||
<span class="mask"></span>
|
||||
</a>
|
||||
{/ifloop}
|
||||
|
||||
<h2 class="name"><a href="{$URL}">{$TITLE}</a></h2>
|
||||
{if $CHAPO}
|
||||
<div class="short-description">
|
||||
{$CHAPO}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</article>
|
||||
</li>
|
||||
{/loop}
|
||||
</ul>
|
||||
{/ifloop}
|
||||
{elseloop rel="brand_logo"}
|
||||
|
||||
{/elseloop}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{/block}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
<h1 id="main-label" class="page-header">{intl l="Your Cart"}</h1>
|
||||
|
||||
{nocache}
|
||||
|
||||
{ifloop rel="cartloop"}
|
||||
{include file="misc/checkout-progress.tpl" step="cart"}
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
<span class="visible-xs">{intl l="Name"}</span>
|
||||
</th>
|
||||
<th class="unitprice">
|
||||
<span class="hidden-xs">{intl l="Unit Price"}</span>
|
||||
<span class="hidden-xs">{intl l="Unit Price incl. taxes"}</span>
|
||||
<span class="visible-xs">{intl l="Price"}</span>
|
||||
</th>
|
||||
<th class="qty">
|
||||
@@ -44,7 +44,7 @@
|
||||
<span class="visible-xs">{intl l="Qty"}</span>
|
||||
</th>
|
||||
<th class="subprice">
|
||||
<span class="hidden-xs">{intl l="Total"}</span>
|
||||
<span class="hidden-xs">{intl l="Total incl. taxes"}</span>
|
||||
<span class="visible-xs">{intl l="Total"}</span>
|
||||
</th>
|
||||
</tr>
|
||||
@@ -53,21 +53,17 @@
|
||||
{loop type="cart" name="cartloop"}
|
||||
<tr>
|
||||
<td class="image">
|
||||
{ifloop rel='product-image'}
|
||||
<a href="{$PRODUCT_URL}" class="thumbnail">
|
||||
{assign "cart_count" $LOOP_COUNT}
|
||||
{ifloop rel='product-image'}
|
||||
{loop type="image" name="product-image" product=$PRODUCT_ID limit="1" width="118" height="85" force_return="true"}
|
||||
<img src="{$IMAGE_URL}" alt="Product #{$cart_count}"></a>
|
||||
{/loop}
|
||||
{/ifloop}
|
||||
{elseloop rel="product-image"}
|
||||
{images file='assets/img/product/1/118x85.png'}<img itemprop="image" src="{$asset_url}" alt="Product #{$cart_count}">{/images}
|
||||
{/elseloop}
|
||||
{loop type="image" name="product-image" product=$PRODUCT_ID limit="1" width="118" height="85" force_return="true"}
|
||||
<img src="{$IMAGE_URL}" alt="Product #{$cart_count}">
|
||||
{/loop}
|
||||
</a>
|
||||
{/ifloop}
|
||||
</td>
|
||||
<td class="product" >
|
||||
<h3 class="name"><a href="{$PRODUCT_URL}">
|
||||
{$TITLE}
|
||||
</a></h3>
|
||||
<h3 class="name"><a href="{$PRODUCT_URL}">{$TITLE}</a></h3>
|
||||
<div class="product-options">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>{intl l="Available"} :</dt>
|
||||
@@ -164,7 +160,7 @@
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="3" class="empty"> </td>
|
||||
<th class="total">{intl l="Total"}</th>
|
||||
<th class="total">{intl l="Total incl. taxes"}</th>
|
||||
<td class="total">
|
||||
<div class="total-price">
|
||||
{assign var="totalAmount" value={cart attr='total_taxed_price_without_discount'} + $postageAmount }
|
||||
@@ -184,7 +180,7 @@
|
||||
<strong>{intl l="Warning"}!</strong> {intl l="You have no items in your shopping cart."}
|
||||
</div>
|
||||
{/elseloop}
|
||||
{/nocache}
|
||||
|
||||
</article>
|
||||
|
||||
{ifloop rel="product_upsell"}
|
||||
@@ -198,7 +194,6 @@
|
||||
{loop name="product_upsell" type="product" promo="yes" limit="5"}
|
||||
{include file="includes/single-product.html" product_id=$ID hasBtn=false hasDescription=true width="218" height="146"}
|
||||
{/loop}
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</aside><!-- #products-upsell -->
|
||||
|
||||
@@ -1,45 +1,99 @@
|
||||
{extends file='layout.tpl'}
|
||||
|
||||
{block name="init"}
|
||||
{$category_id={category attr="id"}}
|
||||
{/block}
|
||||
|
||||
|
||||
{* Body Class *}
|
||||
{block name="body-class"}page-category{/block}
|
||||
|
||||
{* Page Title *}
|
||||
{block name='no-return-functions' append}
|
||||
{loop name="category.seo.title" type="category" current="yes"}
|
||||
{$page_title = {$META_TITLE}}
|
||||
{if $category_id}
|
||||
{loop name="category.seo.title" type="category" id=$category_id limit="1"}
|
||||
{$page_title = {$META_TITLE}}
|
||||
{/loop}
|
||||
{/if}
|
||||
{/block}
|
||||
|
||||
{* Meta *}
|
||||
{block name="meta"}
|
||||
{loop name="category.seo.meta" type="category" current="yes"}
|
||||
{if $META_DESCRIPTION}<meta name="description" content="{$META_DESCRIPTION}">{/if}
|
||||
{if $META_KEYWORDS}<meta name="keywords" content="{$META_KEYWORDS}">{/if}
|
||||
{if $category_id}
|
||||
{loop name="category.seo.meta" type="category" id=$category_id limit="1"}
|
||||
{include file="includes/meta-seo.html"}
|
||||
{/loop}
|
||||
{/if}
|
||||
{/block}
|
||||
|
||||
{* Feeds *}
|
||||
{block name="feeds"}
|
||||
{if $category_id}
|
||||
<link rel="alternate" type="application/rss+xml" title="{intl l='All products in'} {category attr='title'}" href="{url path="/feed/catalog/{lang attr="locale"}/{category attr="id"}"}" />
|
||||
{/if}
|
||||
{/block}
|
||||
|
||||
{* Breadcrumb *}
|
||||
{block name='no-return-functions' append}
|
||||
{if $category_id}
|
||||
{$breadcrumbs = []}
|
||||
{loop name="category_path" type="category-path" category="{category attr="id"}"}
|
||||
{loop name="category_path" type="category-path" category=$category_id}
|
||||
{$breadcrumbs[] = ['title' => {$TITLE}, 'url'=> {$URL nofilter}]}
|
||||
{/loop}
|
||||
{/if}
|
||||
{/block}
|
||||
|
||||
{* Content *}
|
||||
{block name="main-content"}
|
||||
|
||||
|
||||
{$limit={$smarty.get.limit|default:8}}
|
||||
{$product_page={$smarty.get.page|default:1}}
|
||||
{$product_order={$smarty.get.order|default:'alpha'}}
|
||||
|
||||
<div class="main layout-col-2-left">
|
||||
{$limit={$smarty.get.limit|default:8}}
|
||||
{$product_page={$smarty.get.page|default:1}}
|
||||
{$product_order={$smarty.get.order|default:'alpha'}}
|
||||
<article class="col-main {$smarty.get.mode|default:"grid"}" role="main">
|
||||
|
||||
{if #category_display_detail# && $category_id}
|
||||
<section class="category-description">
|
||||
{loop name="category.description" type="category" id={$category_id} limit="1" }
|
||||
<h1 id="main-label" class="page-header">{category attr="title"}</h1>
|
||||
{loop name="category.image" type="image" source="category" id={$ID} width=218 height=146 resize_mode="borders"}
|
||||
<p><img itemprop="image" src="{$IMAGE_URL}" alt="{$TITLE}"></p>
|
||||
{/loop}
|
||||
{if $DESCRIPTION}
|
||||
<div class="description">
|
||||
{$DESCRIPTION nofilter}
|
||||
</div>
|
||||
{/if}
|
||||
{if $POSTSCRIPTUM}
|
||||
<small class="postscriptum">
|
||||
{$POSTSCRIPTUM}
|
||||
</small>
|
||||
{/if}
|
||||
{/loop}
|
||||
</section>
|
||||
<hr/>
|
||||
{/if}
|
||||
|
||||
{if #category_display_subcategories#}
|
||||
{ifloop rel="subcategories"}
|
||||
<div class="block-links">
|
||||
<div class="block-content">
|
||||
<ul>
|
||||
{loop name="subcategories" type="category" parent=$category_id}
|
||||
<li>
|
||||
<a href="{url path={navigate to="current"} category_id=$ID }">{$TITLE}</a>
|
||||
</li>
|
||||
{/loop}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{/ifloop}
|
||||
{/if}
|
||||
|
||||
{ifloop rel="product_list"}
|
||||
{assign var="amount" value="{count type="product" category="{category attr="id"}"}"}
|
||||
{assign var="amount" value="{count type="product" category=$category_id}"}
|
||||
<div class="toolbar toolbar-top" role="toolbar">
|
||||
<div class="sorter-container">
|
||||
<span class="amount">{if ($amount > 1)}{intl l="%nb Items" nb="{$amount}"}{else}{intl l="%nb Item" nb="{$amount}"}{/if}</span>
|
||||
@@ -80,7 +134,7 @@
|
||||
<div id="category-products">
|
||||
<div class="products-content">
|
||||
<ul class="product-col-4">
|
||||
{loop type="product" name="product_list" category={category attr="id"} limit=$limit page=$product_page order=$product_order}
|
||||
{loop type="product" name="product_list" category=$category_id limit=$limit page=$product_page order=$product_order}
|
||||
{include file="includes/single-product.html" product_id=$ID hasBtn=true hasDescription=true hasQuickView=true width="218" height="146"}
|
||||
{/loop}
|
||||
</ul>
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
# Display
|
||||
category_display_detail = true
|
||||
category_display_subcategories = false
|
||||
|
||||
folder_display_detail = true
|
||||
folder_display_subfolders = false
|
||||
|
||||
|
||||
# Maximum number of lines in lists
|
||||
# --------------------------------
|
||||
max_displayed_orders = 20
|
||||
|
||||
@@ -1,39 +1,48 @@
|
||||
{extends file="layout.tpl"}
|
||||
|
||||
{block name='init'}
|
||||
{assign var="content_id" value={content attr="id"}}
|
||||
{/block}
|
||||
|
||||
{* Body Class *}
|
||||
{block name="body-class"}page-content{/block}
|
||||
|
||||
{* Page Title *}
|
||||
{block name='no-return-functions' append}
|
||||
{loop name="content.seo.title" type="content" id="{content attr="id"}"}
|
||||
{$page_title = {$META_TITLE}}
|
||||
{/loop}
|
||||
{if {$content_id}}
|
||||
{loop name="content.seo.title" type="content" id={$content_id} limit="1"}
|
||||
{$page_title = {$META_TITLE}}
|
||||
{/loop}
|
||||
{/if}
|
||||
{/block}
|
||||
|
||||
{* Meta *}
|
||||
{block name="meta"}
|
||||
{loop name="content.seo.meta" type="content" id="{content attr="id"}"}
|
||||
{if $META_DESCRIPTION}<meta name="description" content="{$META_DESCRIPTION}">{/if}
|
||||
{if $META_KEYWORDS}<meta name="keywords" content="{$META_KEYWORDS}">{/if}
|
||||
{/loop}
|
||||
{if $content_id}
|
||||
{loop name="content.seo.meta" type="content" id=$content_id limit="1"}
|
||||
{include file="includes/meta-seo.html"}
|
||||
{/loop}
|
||||
{/if}
|
||||
{/block}
|
||||
|
||||
{* Breadcrumb *}
|
||||
{block name='no-return-functions' append}
|
||||
{$breadcrumbs = []}
|
||||
{loop type="content" name="content-breadcrumb" id="{content attr="id"}"}
|
||||
{loop name="folder_path" type="folder-path" folder="{$DEFAULT_FOLDER}"}
|
||||
{if $content_id}
|
||||
{$breadcrumbs = []}
|
||||
{loop type="content" name="content-breadcrumb" id=$content_id limit="1"}
|
||||
{loop name="folder_path" type="folder-path" folder="{$DEFAULT_FOLDER}"}
|
||||
{$breadcrumbs[] = ['title' => {$TITLE}, 'url'=> {$URL}]}
|
||||
{/loop}
|
||||
{$breadcrumbs[] = ['title' => {$TITLE}, 'url'=> {$URL}]}
|
||||
{/loop}
|
||||
{$breadcrumbs[] = ['title' => {$TITLE}, 'url'=> {$URL}]}
|
||||
{/loop}
|
||||
{/if}
|
||||
{/block}
|
||||
|
||||
{block name="main-content"}
|
||||
{if $content_id}
|
||||
<div class="main layout-col-2-left">
|
||||
|
||||
<article class="col-main" role="main" aria-labelledby="main-label">
|
||||
{loop name="blog.content" type="content" current="yes"}
|
||||
<article id="content-main" class="col-main" role="main" aria-labelledby="main-label">
|
||||
{loop name="blog.content" type="content" id=$content_id limit="1"}
|
||||
<h1 id="main-label" class="page-header">{$TITLE}</h1>
|
||||
{if $CHAPO}
|
||||
<div class="chapo">
|
||||
@@ -48,14 +57,19 @@
|
||||
{if $POSTSCRIPTUM}
|
||||
<small class="postscriptum">
|
||||
{$POSTSCRIPTUM}
|
||||
</small>
|
||||
</small>
|
||||
{/if}
|
||||
{/loop}
|
||||
</article>
|
||||
|
||||
<aside class="col-left" role="complementary" itemscope itemtype="http://schema.org/WPSideBar">
|
||||
{include file="includes/asides/articles.html"}
|
||||
</aside>
|
||||
|
||||
</div><!-- /.layout -->
|
||||
{else}
|
||||
<div class="main">
|
||||
<article id="content-main" class="col-main" role="main" aria-labelledby="main-label">
|
||||
{include file="includes/empty.html"}
|
||||
</article>
|
||||
</div><!-- /.layout -->
|
||||
{/if}
|
||||
{/block}
|
||||
|
||||
@@ -1,29 +1,38 @@
|
||||
{extends file="layout.tpl"}
|
||||
|
||||
{block name="init"}
|
||||
{$folder_id={folder attr="id"}}
|
||||
{/block}
|
||||
|
||||
{* Body Class *}
|
||||
{block name="body-class"}page-folder{/block}
|
||||
|
||||
{* Page Title *}
|
||||
{block name='no-return-functions' append}
|
||||
{loop name="folder.seo.title" type="folder" id="{folder attr="id"}"}
|
||||
{$page_title = {$META_TITLE}}
|
||||
{/loop}
|
||||
{if $folder_id}
|
||||
{loop name="folder.seo.title" type="folder" id=$folder_id limit="1"}
|
||||
{$page_title = {$META_TITLE}}
|
||||
{/loop}
|
||||
{/if}
|
||||
{/block}
|
||||
|
||||
{* Meta *}
|
||||
{block name="meta"}
|
||||
{loop name="folder.seo.meta" type="folder" id="{folder attr="id"}"}
|
||||
{if $META_DESCRIPTION}<meta name="description" content="{$META_DESCRIPTION}">{/if}
|
||||
{if $META_KEYWORDS}<meta name="keywords" content="{$META_KEYWORDS}">{/if}
|
||||
{/loop}
|
||||
{if $folder_id}
|
||||
{loop name="folder.seo.meta" type="folder" id=$folder_id limit="1"}
|
||||
{include file="includes/meta-seo.html"}
|
||||
{/loop}
|
||||
{/if}
|
||||
{/block}
|
||||
|
||||
{* Breadcrumb *}
|
||||
{block name='no-return-functions' append}
|
||||
{$breadcrumbs = []}
|
||||
{loop name="folder_path" type="folder-path" folder="{folder attr="id"}"}
|
||||
{$breadcrumbs[] = ['title' => {$TITLE}, 'url'=> {$URL}]}
|
||||
{/loop}
|
||||
{if $folder_id}
|
||||
{$breadcrumbs = []}
|
||||
{loop name="folder_path" type="folder-path" folder=$folder_id}
|
||||
{$breadcrumbs[] = ['title' => {$TITLE}, 'url'=> {$URL}]}
|
||||
{/loop}
|
||||
{/if}
|
||||
{/block}
|
||||
|
||||
{block name="feeds"}
|
||||
@@ -33,69 +42,86 @@
|
||||
{* Content *}
|
||||
{block name="main-content"}
|
||||
<div class="main">
|
||||
<div class="col-main contents-list" role="main" aria-labelledby="main-label">
|
||||
{if $folder_id}
|
||||
{loop name="folder" type="folder" id=$folder_id limit="1"}
|
||||
<h1 id="main-label" class="page-header">{$TITLE}</h1>
|
||||
{if $CHAPO}
|
||||
<div class="folder-chapo">
|
||||
{$CHAPO}
|
||||
</div>
|
||||
{/if}
|
||||
{if $DESCRIPTION}
|
||||
<div class="folder-description">
|
||||
{$DESCRIPTION nofilter}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="col-main" role="main" aria-labelledby="main-label">
|
||||
<div id="folder-contents">
|
||||
<div class="contents">
|
||||
{ifloop rel="folder_content"}
|
||||
<ul>
|
||||
{loop name="folder_content" type="content" folder="$ID"}
|
||||
<li class="item">
|
||||
<article>
|
||||
{ifloop rel="content_thumbnail"}
|
||||
<a href="{$URL}" tabindex="-1" class="content-image">
|
||||
{loop name="content_thumbnail" type="image" width="369" height="247" content=$ID limit="1"}
|
||||
<img src="{$IMAGE_URL}" alt="{$TITLE}">
|
||||
{/loop}
|
||||
<span class="mask"></span>
|
||||
</a>
|
||||
{/ifloop}
|
||||
|
||||
{loop name="folder" type="folder" id="{folder attr="id"}"}
|
||||
<h1 id="main-label" class="page-header">{$TITLE}</h1>
|
||||
{if $CHAPO}
|
||||
<div class="folder-chapo">
|
||||
{$CHAPO}
|
||||
</div>
|
||||
{/if}
|
||||
{if $DESCRIPTION}
|
||||
<div class="folder-description">
|
||||
{$DESCRIPTION nofilter}
|
||||
</div>
|
||||
{/if}
|
||||
<div class="content-info">
|
||||
<h3 class="name"><a href="{$URL}">{$TITLE}</a></h3>
|
||||
|
||||
<div id="folder-contents">
|
||||
<div class="contents">
|
||||
{ifloop rel="folder_content"}
|
||||
<ul>
|
||||
{loop name="folder_content" type="content" folder="$ID"}
|
||||
<li class="item">
|
||||
<article>
|
||||
<a href="{$URL}" tabindex="-1" class="content-image">
|
||||
{loop name="content_thumbnail" type="image" width="369" height="247" content=$ID limit="1"}
|
||||
<img src="{$IMAGE_URL}" alt="{$TITLE}">
|
||||
{/loop}
|
||||
{elseloop rel="content_thumbnail"}
|
||||
{images file='assets/img/280x196.png'}<img src="{$asset_url}" alt="{$TITLE}">{/images}
|
||||
{/elseloop}
|
||||
<span class="mask"></span>
|
||||
</a>
|
||||
|
||||
<div class="content-info">
|
||||
<h3 class="name"><a href="{$URL}">{$TITLE}</a></h3>
|
||||
|
||||
{if $CHAPO}
|
||||
<div class="short-description">
|
||||
{$CHAPO}
|
||||
{if $CHAPO}
|
||||
<div class="short-description">
|
||||
{$CHAPO}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</article><!-- /content -->
|
||||
</li>
|
||||
{/loop}
|
||||
</ul>
|
||||
{/ifloop}
|
||||
{elseloop rel="folder_content"}
|
||||
<div class="folder-warning">
|
||||
{intl l="No Content in this folder."}
|
||||
</article><!-- /content -->
|
||||
</li>
|
||||
{/loop}
|
||||
</ul>
|
||||
{/ifloop}
|
||||
{elseloop rel="folder_content"}
|
||||
<div class="folder-warning">
|
||||
{intl l="No Contents in this folder."}
|
||||
</div>
|
||||
{/elseloop}
|
||||
</div>
|
||||
</div><!-- /#category-products -->
|
||||
|
||||
|
||||
{if $POSTSCRIPTUM}
|
||||
<small class="folder-postscriptum">
|
||||
{$POSTSCRIPTUM}
|
||||
</small>
|
||||
{/if}
|
||||
{/loop}
|
||||
{else}
|
||||
{ifloop rel="folders"}
|
||||
<ul>
|
||||
{loop name="folders" type="folder"}
|
||||
<li class="item">
|
||||
<article>
|
||||
<div class="content-info">
|
||||
<h2 class="name"><a href="{$URL}">{$TITLE}</a></h2>
|
||||
{if $CHAPO}
|
||||
<div class="short-description">
|
||||
{$CHAPO}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/elseloop}
|
||||
</div>
|
||||
</div><!-- /#category-products -->
|
||||
|
||||
|
||||
{if $POSTSCRIPTUM}
|
||||
<small class="folder-postscriptum">
|
||||
{$POSTSCRIPTUM}
|
||||
</small>
|
||||
{/if}
|
||||
{/loop}
|
||||
|
||||
</article>
|
||||
</li>
|
||||
{/loop}
|
||||
</ul>
|
||||
{/ifloop}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
||||
|
||||
@@ -1,34 +1,38 @@
|
||||
{default_translation_domain domain='fo.default'}
|
||||
{loop type="product" name="add_product_to_cart" id={product attr="id"}}
|
||||
<div class="clearfix">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="col-md-4">
|
||||
{loop name="product_thumbnail" type="image" product=$ID width="218" height="146" resize_mode="borders" limit="1"}
|
||||
<img itemprop="image" src="{$IMAGE_URL}" alt="Product #{$LOOP_COUNT}">
|
||||
{/loop}
|
||||
</td>
|
||||
<td class="col-md-4">
|
||||
<h2>{$TITLE}</h2>
|
||||
{loop type="attribute_combination" name="product_options" product_sale_elements="$PRODUCT_SALE_ELEMENTS_ID"}
|
||||
<p>{$ATTRIBUTE_TITLE}</p>
|
||||
<p>{$ATTRIBUTE_AVAILABILITY_TITLE}</p>
|
||||
{/loop}
|
||||
</td>
|
||||
<td class="col-md-4">
|
||||
<table>
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<h3 class="text-center">{intl l="The product has been added to your cart" }</h3>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="col-md-4">
|
||||
{loop name="product_thumbnail" type="image" product=$ID width="218" height="146" resize_mode="borders" limit="1"}
|
||||
<img itemprop="image" src="{$IMAGE_URL}" alt="Product #{$LOOP_COUNT}">
|
||||
{/loop}
|
||||
</td>
|
||||
<td class="col-md-4">
|
||||
<h2>{$TITLE}</h2>
|
||||
{loop type="attribute_combination" name="product_options" product_sale_elements="{$smarty.get.pse_id}"}
|
||||
<p>{$ATTRIBUTE_TITLE} : {$ATTRIBUTE_AVAILABILITY_TITLE}</p>
|
||||
{/loop}
|
||||
</td>
|
||||
<td class="col-md-4">
|
||||
|
||||
{if $IS_PROMO == 1}
|
||||
{assign "real_price" $TAXED_PROMO_PRICE}
|
||||
<div class="special-price"><span class="price">{$TAXED_PROMO_PRICE} {currency attr="symbol"}</span></div>
|
||||
<small class="old-price"> <span class="price">{$TAXED_PRICE} {currency attr="symbol"}</span></small>
|
||||
{else}
|
||||
{assign "real_price" $TAXED_PRICE}
|
||||
<div class="special-price"><span class="price">{$TAXED_PRICE} {currency attr="symbol"}</span></div>
|
||||
{/if}
|
||||
{if $IS_PROMO == 1}
|
||||
{assign "real_price" $TAXED_PROMO_PRICE}
|
||||
<div class="special-price"><span class="price">{$TAXED_PROMO_PRICE} {currency attr="symbol"}</span></div>
|
||||
<small class="old-price"> <span class="price">{$TAXED_PRICE} {currency attr="symbol"}</span></small>
|
||||
{else}
|
||||
{assign "real_price" $TAXED_PRICE}
|
||||
<div class="special-price"><span class="price">{$TAXED_PRICE} {currency attr="symbol"}</span></div>
|
||||
{/if}
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<a href="{url path="/cart"}" role="button" class="btn btn_add_to_cart pull-right"><span>{intl l="View Cart"}</span></a>
|
||||
<button type="button" class="btn btn-checkout pull-right" data-dismiss="modal"><span>{intl l="Continue Shopping"}</span></button>
|
||||
</div>
|
||||
|
||||
10
templates/frontOffice/default/includes/empty.html
Normal file
@@ -0,0 +1,10 @@
|
||||
{if ! $title_empty}
|
||||
{$title={intl l="The page cannot be found"}}
|
||||
{/if}
|
||||
<h1 id="main-label" class="page-header">{$title}</h1>
|
||||
|
||||
{if ! $message_empty}
|
||||
<div class="description">
|
||||
{$message_empty nofilter}
|
||||
</div>
|
||||
{/if}
|
||||
@@ -18,7 +18,7 @@
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
{loop name="cat-parent-$level" type="category" parent=$parent need_count_child=1}
|
||||
{loop name="cat-parent-$level" type="category" parent=$parent need_count_child=1 not_empty="1"}
|
||||
|
||||
{if $CHILD_COUNT> 0}
|
||||
<li><a href="{$URL}#collapse{$ID}" class="accordion-toggle collapsed" data-toggle="collapse" data-parent="#collapse{$ID}">{$TITLE}</a>
|
||||
|
||||
6
templates/frontOffice/default/includes/meta-seo.html
Normal file
@@ -0,0 +1,6 @@
|
||||
{if $META_DESCRIPTION}
|
||||
<meta name="description" content="{$META_DESCRIPTION}">
|
||||
{elseif $CHAPO}
|
||||
<meta name="description" content="{$CHAPO|truncate:150:""}">
|
||||
{/if}
|
||||
{if $META_KEYWORDS}<meta name="keywords" content="{$META_KEYWORDS}">{/if}
|
||||
@@ -1,19 +1,14 @@
|
||||
<li class="item">
|
||||
{assign var="hasSubmit" value = false}
|
||||
{if $PSE_COUNT > 1}
|
||||
{assign var="hasSubmit" value = false}
|
||||
{else}
|
||||
{assign var="hasSubmit" value = true}
|
||||
{/if}
|
||||
{assign var="productTitle" value="{$TITLE}"}
|
||||
{if not $product_id}
|
||||
{assign var="product_id" value=$ID}
|
||||
{/if}
|
||||
<article itemscope itemtype="http://schema.org/Product">
|
||||
<!-- Use the meta tag to specify content that is not visible on the page in any way -->
|
||||
{loop name="brand" type="brand" product=$product_id }
|
||||
<meta itemprop="brand" content="{$TITLE}">
|
||||
{/loop}
|
||||
{loop name="isbn.feature" type="feature" product=$product_id title="isbn"}
|
||||
{loop name="isbn.value" type="feature_value" feature=$ID product=$product_id}
|
||||
<meta itemprop="productID" content="isbn:{$TITLE}">
|
||||
{/loop}
|
||||
{/loop}
|
||||
|
||||
<a href="{$URL}" itemprop="url" tabindex="-1" class="product-image{if $hasQuickView == true} product-quickview{/if}">
|
||||
{loop name="product_thumbnail" type="image" product=$product_id width="{$width}" height="{$height}" resize_mode="borders" limit="1"}
|
||||
@@ -26,7 +21,7 @@
|
||||
</a>
|
||||
|
||||
<div class="product-info">
|
||||
<h3 class="name"><a href="{$URL}"><span itemprop="name">{$productTitle}</span></a></h3>
|
||||
<h2 class="name"><a href="{$URL}"><span itemprop="name">{$productTitle}</span></a></h2>
|
||||
{if $hasDescription}
|
||||
<div class="description" itemprop="description">
|
||||
<p>{$DESCRIPTION nofilter}</p>
|
||||
@@ -34,117 +29,76 @@
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{* Default value *}
|
||||
{* Stock *}
|
||||
{assign var="current_stock_content" value = "in_stock"}
|
||||
{assign var="current_stock_href" value = "http://schema.org/InStock"}
|
||||
|
||||
{loop name="stock_meta" type="product_sale_elements" product=$product_id}
|
||||
{loop name="combi_meta" type="attribute_combination" product_sale_elements="$ID"}
|
||||
{if $LOOP_COUNT == 0}
|
||||
{if $QUANTITY == 0}
|
||||
{assign var="current_stock_content" value = "out_stock"}
|
||||
{assign var="current_stock_href" value = "http://schema.org/OutOfStock"}
|
||||
{/if}
|
||||
{/if}
|
||||
{/loop}
|
||||
{/loop}
|
||||
{if {config key="check-available-stock"} != 0}
|
||||
{if $QUANTITY == 0}
|
||||
{assign var="current_stock_content" value = "out_stock"}
|
||||
{assign var="current_stock_href" value = "http://schema.org/OutOfStock"}
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
<div class="product-price">
|
||||
<div class="price-container" itemprop="offers" itemscope itemtype="http://schema.org/Offer">
|
||||
<meta itemprop="category" content="{category attr="title"}">
|
||||
<meta itemprop="itemCondition" itemscope itemtype="http://schema.org/NewCondition"> <!-- List of condition : NewCondition, DamagedCondition, UsedCondition, RefurbishedCondition -->
|
||||
<meta itemprop="priceCurrency" content="{currency attr="symbol"}"> <!-- List of currency : The currency used to describe the product price, in three-letter ISO format. -->
|
||||
{* List of condition : NewCondition, DamagedCondition, UsedCondition, RefurbishedCondition *}
|
||||
<meta itemprop="itemCondition" itemscope itemtype="http://schema.org/NewCondition">
|
||||
{* List of currency : The currency used to describe the product price, in three-letter ISO format. *}
|
||||
<meta itemprop="priceCurrency" content="{currency attr="symbol"}">
|
||||
<link itemprop="availability" href="{$current_stock_href}" content="{$current_stock_content}" />
|
||||
<!-- List of availibility :
|
||||
out_of_stock : http://schema.org/OutOfStock
|
||||
in_stock : http://schema.org/InStock
|
||||
instore_only : http://schema.org/InStoreOnly
|
||||
preorder : http://schema.org/PreOrder
|
||||
online_only : http://schema.org/OnlineOnly
|
||||
-->
|
||||
{if $IS_PROMO }
|
||||
{loop name="productSaleElements_promo" type="product_sale_elements" product=$product_id limit="1" order="min_price"}
|
||||
{assign var="default_product_sale_elements" value=$ID}
|
||||
<span class="special-price"><span itemprop="price" class="price-label">{intl l="Special Price:"} </span><span class="price">{format_number number=$TAXED_PROMO_PRICE} {currency attr="symbol"}</span></span>
|
||||
<span class="old-price"><span class="price-label">{intl l="Regular Price:"} </span><span class="price">{format_number number=$TAXED_PRICE} {currency attr="symbol"}</span></span>
|
||||
{/loop}
|
||||
<span class="special-price"><span itemprop="price" class="price-label">{intl l="Special Price:"} </span><span class="price">{format_number number=$TAXED_PROMO_PRICE} {currency attr="symbol"}</span></span>
|
||||
<span class="old-price"><span class="price-label">{intl l="Regular Price:"} </span><span class="price">{format_number number=$TAXED_PRICE} {currency attr="symbol"}</span></span>
|
||||
{else}
|
||||
<span class="regular-price"><span itemprop="price" class="price">{format_number number=$BEST_TAXED_PRICE} {currency attr="symbol"}</span></span>
|
||||
{/if}
|
||||
|
||||
</div>
|
||||
|
||||
{if $hasBtn == true}
|
||||
{form name="thelia.cart.add" }
|
||||
<form id="form-product-details{$product_id}" action="{url path="/cart/add" }" method="post" class="form-product">
|
||||
{form_hidden_fields form=$form}
|
||||
<input type="hidden" name="view" value="product">
|
||||
<input type="hidden" name="product_id" value="{$product_id}">
|
||||
{if $hasSubmit == true}
|
||||
{form name="thelia.cart.add" }
|
||||
<form id="form-product-details{$product_id}" action="{url path="/cart/add" }" method="post" class="form-product">
|
||||
{form_hidden_fields form=$form}
|
||||
<input type="hidden" name="view" value="product">
|
||||
<input type="hidden" name="product_id" value="{$product_id}">
|
||||
|
||||
{if $form_error}<div class="alert alert-error">{$form_error_message}</div>{/if}
|
||||
{if $form_error}<div class="alert alert-error">{$form_error_message}</div>{/if}
|
||||
|
||||
{form_field form=$form field='product_sale_elements_id'}
|
||||
{if $default_product_sale_elements }
|
||||
<input type="hidden" name="{$name}" value="{$default_product_sale_elements}" {$attr}>
|
||||
{else}
|
||||
{loop name="productSaleElements_promo" type="product_sale_elements" product="{$product_id}" limit="1"}
|
||||
<input type="hidden" name="{$name}" value="{$ID}" {$attr}>
|
||||
{/loop}
|
||||
{/if}
|
||||
{/form_field}
|
||||
{form_field form=$form field="product"}
|
||||
<input id="{$label_attr.for}" type="hidden" name="{$name}" value="{$product_id}" {$attr} >
|
||||
{/form_field}
|
||||
{form_field form=$form field='product_sale_elements_id'}
|
||||
<input type="hidden" name="{$name}" value="{$PRODUCT_SALE_ELEMENT}" {$attr}>
|
||||
{/form_field}
|
||||
{form_field form=$form field="product"}
|
||||
<input id="{$label_attr.for}" type="hidden" name="{$name}" value="{$product_id}" {$attr} >
|
||||
{/form_field}
|
||||
|
||||
<fieldset class="product-options hide">
|
||||
{ifloop rel="stock"}
|
||||
<div class="option">
|
||||
<label for="options" class="option-heading">Options</label>
|
||||
<div class="option-content">
|
||||
<select name="options" class="form-control">
|
||||
{loop name="stock" type="product_sale_elements" product="$product_id" order="min_price"}
|
||||
{if $LOOP_TOTAL == 1}
|
||||
{assign var="hasSubmit" value = true}
|
||||
<fieldset class="product-cart form-inline">
|
||||
{form_field form=$form field='quantity'}
|
||||
<div class="form-group group-qty hide {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
|
||||
<label for="{$label_attr.for}">{$label}</label>
|
||||
<input type="number" name="{$name}" id="{$label_attr.for}" class="form-control" value="{$value|default:1}" min="0" required>
|
||||
{if $error }
|
||||
<span class="help-block"><i class="icon-remove"></i> {$message}</span>
|
||||
{elseif $value != "" && !$error}
|
||||
<span class="help-block"><i class="icon-ok"></i></span>
|
||||
{/if}
|
||||
{loop name="combi" type="attribute_combination" product_sale_elements="$product_id" order="alpha"}
|
||||
<option value="{$ID}" data-quantity="{$QUANTITY}" data-price="{format_number number="{$BEST_TAXED_PRICE}"} {currency attr="symbol"}" data-old-price="{format_number number="{$TAXED_PRICE}"} {currency attr="symbol"}">{$ATTRIBUTE_AVAILABILITY_TITLE}</small></option>
|
||||
{/loop}
|
||||
{/loop}
|
||||
</select>
|
||||
</div>
|
||||
{/form_field}
|
||||
<div>
|
||||
<div class="product-btn">
|
||||
<button type="submit" class="btn btn-cart">{intl l="Add to cart"}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/ifloop}
|
||||
</fieldset>
|
||||
<fieldset class="product-cart form-inline">
|
||||
{form_field form=$form field='quantity'}
|
||||
<div class="form-group group-qty hide {if $error}has-error{elseif $value != "" && !$error}has-success{/if}">
|
||||
<label for="{$label_attr.for}">{$label}</label>
|
||||
<input type="number" name="{$name}" id="{$label_attr.for}" class="form-control" value="{$value|default:1}" min="0" required>
|
||||
{if $error }
|
||||
<span class="help-block"><i class="icon-remove"></i> {$message}</span>
|
||||
{elseif $value != "" && !$error}
|
||||
<span class="help-block"><i class="icon-ok"></i></span>
|
||||
{/if}
|
||||
</div>
|
||||
{/form_field}
|
||||
|
||||
<div class="form-group group-btn">
|
||||
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
{/form}
|
||||
{else}
|
||||
<div>
|
||||
<div class="product-btn">
|
||||
|
||||
{if $hasSubmit == true}
|
||||
<button type="submit" class="btn btn-cart">{intl l="Add to cart"}</button>
|
||||
{else}
|
||||
<a href="{$URL}" class="btn btn-cart">{intl l="View product"}</a>
|
||||
{/if}
|
||||
|
||||
<a href="{$URL}" class="btn btn-cart">{intl l="View product"}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</fieldset>
|
||||
</form>
|
||||
{/form}
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
</article><!-- /product -->
|
||||
|
||||
@@ -24,7 +24,7 @@ GNU General Public License : http://www.gnu.org/licenses/
|
||||
|
||||
{* -- Define some stuff for Smarty ------------------------------------------ *}
|
||||
{config_load file='variables.conf'}
|
||||
|
||||
{block name="init"}{/block}
|
||||
{block name="no-return-functions"}{/block}
|
||||
{assign var="store_name" value="{config key="store_name"}"}
|
||||
{assign var="store_description" value="{config key="store_description"}"}
|
||||
@@ -181,6 +181,7 @@ GNU General Public License : http://www.gnu.org/licenses/
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{if {count type="lang" exclude="{lang attr='id'}"} != 0 }
|
||||
<div class="language-switch" aria-labelledby="language-label" role="form">
|
||||
<span id="language-label" class="dropdown-label">{intl l="Language:"}</span>
|
||||
<a class="current dropdown-toggle" data-toggle="dropdown" href="{url path="/language"}">{lang attr="title"}</a>
|
||||
@@ -190,7 +191,9 @@ GNU General Public License : http://www.gnu.org/licenses/
|
||||
{/loop}
|
||||
</ul>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{if {count type="currency" exclude="{currency attr='id'}"} != 0 }
|
||||
<div class="currency-switch" aria-labelledby="currency-label" role="form">
|
||||
<span id="currency-label" class="dropdown-label">{intl l="Currency:"}</span>
|
||||
<a class="current dropdown-toggle" data-toggle="dropdown" href="{url path="/currency"}">{currency attr="code"}</a>
|
||||
@@ -200,6 +203,7 @@ GNU General Public License : http://www.gnu.org/licenses/
|
||||
{/loop}
|
||||
</ul>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -291,7 +295,7 @@ GNU General Public License : http://www.gnu.org/licenses/
|
||||
<p>{intl l="Follow us introduction"}</p>
|
||||
<ul role="presentation">
|
||||
<li>
|
||||
<a href="http://facebook.com" rel="nofollow" class="facebook" data-toggle="tooltip" data-placement="top" title="{intl l="Facebook"}" target="_blank">
|
||||
<a href="https://www.facebook.com/theliaecommerce" rel="nofollow" class="facebook" data-toggle="tooltip" data-placement="top" title="{intl l="Facebook"}" target="_blank">
|
||||
<span class="icon-stack">
|
||||
<span class="icon-circle icon-stack-base"></span>
|
||||
<span class="icon-facebook icon-light"></span>
|
||||
@@ -300,7 +304,7 @@ GNU General Public License : http://www.gnu.org/licenses/
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://twitter.com" rel="nofollow" class="twitter" data-toggle="tooltip" data-placement="top" title="{intl l="Twitter"}" target="_blank">
|
||||
<a href="https://twitter.com/theliaecommerce" rel="nofollow" class="twitter" data-toggle="tooltip" data-placement="top" title="{intl l="Twitter"}" target="_blank">
|
||||
<span class="icon-stack">
|
||||
<span class="icon-circle icon-stack-base"></span>
|
||||
<span class="icon-twitter icon-light"></span>
|
||||
@@ -318,7 +322,7 @@ GNU General Public License : http://www.gnu.org/licenses/
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://www.google.com" rel="nofollow" class="google-plus" data-toggle="tooltip" data-placement="top" title="{intl l="Google+"}" target="_blank">
|
||||
<a href="https://plus.google.com/+TheliaNet" rel="nofollow" class="google-plus" data-toggle="tooltip" data-placement="top" title="{intl l="Google+"}" target="_blank">
|
||||
<span class="icon-stack">
|
||||
<span class="icon-circle icon-stack-base"></span>
|
||||
<span class="icon-google-plus icon-light"></span>
|
||||
@@ -336,7 +340,7 @@ GNU General Public License : http://www.gnu.org/licenses/
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#rss" class="rss" rel="nofollow" data-toggle="tooltip" data-placement="top" title="{intl l="RSS"}" target="_blank">
|
||||
<a href="http://thelia.net/feed/" class="rss" rel="nofollow" data-toggle="tooltip" data-placement="top" title="{intl l="RSS"}" target="_blank">
|
||||
<span class="icon-stack">
|
||||
<span class="icon-circle icon-stack-base"></span>
|
||||
<span class="icon-rss icon-light"></span>
|
||||
@@ -410,11 +414,12 @@ GNU General Public License : http://www.gnu.org/licenses/
|
||||
<div class="info">
|
||||
<nav class="nav-footer" role="navigation">
|
||||
<ul>
|
||||
{loop name="footer_links" type="content" folder="2"}
|
||||
<li><a href="{$URL}">{$TITLE}</a></li>
|
||||
{/loop}
|
||||
{*<li><a href="#">Site Map</a></li>
|
||||
<li><a href="#">Terms & Conditions</a></li>*}
|
||||
{$folder_information={config key="information_folder_id"}}
|
||||
{if $folder_information}
|
||||
{loop name="footer_links" type="content" folder=$folder_information}
|
||||
<li><a href="{$URL}">{$TITLE}</a></li>
|
||||
{/loop}
|
||||
{/if}
|
||||
<li><a href="{url path="/contact"}">{intl l="Contact Us"}</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
<div id="delivery-address" class="panel">
|
||||
<div class="panel-heading clearfix">
|
||||
<a href="{url path="/address/create"}" class="btn btn-add-address">{intl l="Add a new address"}</a>
|
||||
<a href="{url path="/address/create" next="{navigate to='current'}" }" class="btn btn-add-address">{intl l="Add a new address"}</a>
|
||||
{intl l="Choose your delivery address"}
|
||||
{if $error}
|
||||
<span class="help-block"><span class="icon-remove"></span> {$message}</span>
|
||||
@@ -97,7 +97,7 @@
|
||||
</td>
|
||||
<td>
|
||||
<div class="group-btn">
|
||||
<a href="{url path="/address/update/{$ID}"}" class="btn btn-edit-address" data-toggle="tooltip" title="{intl l="Edit this address"}"><i class="icon-pencil"></i> <span>{intl l="Edit"}</span></a>
|
||||
<a href="{url path="/address/update/{$ID}" next="{navigate to='current'}"}" class="btn btn-edit-address" data-toggle="tooltip" title="{intl l="Edit this address"}"><i class="icon-pencil"></i> <span>{intl l="Edit"}</span></a>
|
||||
{if $DEFAULT != 1}
|
||||
<a href="{url path="/address/delete/{$ID}"}" class="btn btn-remove-address" data-confirm="{intl l="Do you really want to delete this address ?"}" data-confirm-callback="address.delete" title="{intl l="Remove this address"}" data-toggle="tooltip"><i class="icon-remove"></i> <span>{intl l="Cancel"}</span></a>
|
||||
{/if}
|
||||
|
||||
@@ -53,6 +53,10 @@
|
||||
<span class="hidden-xs">{intl l="Unit Price"}</span>
|
||||
<span class="visible-xs">{intl l="Price"}</span>
|
||||
</th>
|
||||
<th class="unitprice">
|
||||
<span class="hidden-xs">{intl l="Unit Taxed Price"}</span>
|
||||
<span class="visible-xs">{intl l="Taxed Price"}</span>
|
||||
</th>
|
||||
<th class="qty">
|
||||
<span class="hidden-xs">{intl l="Quantity"}</span>
|
||||
<span class="visible-xs">{intl l="Qty"}</span>
|
||||
@@ -68,8 +72,8 @@
|
||||
{loop type="cart" name="cartloop"}
|
||||
<tr>
|
||||
<td class="image">
|
||||
|
||||
{assign "cart_count" $LOOP_COUNT}
|
||||
<a href="{$PRODUCT_URL}">
|
||||
{ifloop rel='product-image'}
|
||||
{loop type="image" name="product-image" product=$PRODUCT_ID limit="1" width="118" height="85" force_return="true"}
|
||||
<img src="{$IMAGE_URL}" alt="Product #{$cart_count}">
|
||||
@@ -78,10 +82,11 @@
|
||||
{elseloop rel="product-image"}
|
||||
{images file='assets/img/product/1/118x85.png'}<img itemprop="image" src="{$asset_url}" alt="Product #{$cart_count}">{/images}
|
||||
{/elseloop}
|
||||
</a>
|
||||
</td>
|
||||
<td class="product" >
|
||||
<h3 class="name">
|
||||
{$TITLE}
|
||||
<a href="{$PRODUCT_URL}">{$TITLE}</a>
|
||||
</h3>
|
||||
<div class="product-options">
|
||||
<dl class="dl-horizontal">
|
||||
@@ -100,6 +105,15 @@
|
||||
</dl>
|
||||
</div>
|
||||
</td>
|
||||
<td class="unitprice">
|
||||
<div class="secondary-price">
|
||||
{if $IS_PROMO == 1}
|
||||
<small><span class="price">{$PROMO_PRICE} {currency attr="symbol"}</span></small>
|
||||
{else}
|
||||
<small><span class="price">{$PRICE} {currency attr="symbol"}</span></small>
|
||||
{/if}
|
||||
</div>
|
||||
</td>
|
||||
<td class="unitprice">
|
||||
{if $IS_PROMO == 1}
|
||||
{assign "real_price" $PROMO_TAXED_PRICE}
|
||||
@@ -107,7 +121,7 @@
|
||||
<small class="old-price">{intl l="instead of"} <span class="price">{$TAXED_PRICE} {currency attr="symbol"}</span></small>
|
||||
{else}
|
||||
{assign "real_price" $TAXED_PRICE}
|
||||
<div class="special-price"><span class="price">{$TAXED_PRICE} {currency attr="symbol"} </span></div>
|
||||
<div class="special-price"><span class="price">{$TAXED_PRICE} {currency attr="symbol"}</span></div>
|
||||
{/if}
|
||||
</td>
|
||||
<td class="qty">
|
||||
@@ -121,56 +135,72 @@
|
||||
{/loop}
|
||||
|
||||
</tbody>
|
||||
<tfoot>
|
||||
|
||||
<tr >
|
||||
<td rowspan="4" colspan="3" class="empty"> </td>
|
||||
<th class="shipping">{intl l="Discount"}</th>
|
||||
<td class="shipping">
|
||||
<div class="shipping-price">
|
||||
<span class="price">{order attr="discount"} {currency attr="symbol"}</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr >
|
||||
<th class="shipping">{intl l="Shipping Tax"}</th>
|
||||
<td class="shipping">
|
||||
<div class="shipping-price">
|
||||
<span class="price">{order attr="postage"} {currency attr="symbol"}</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr >
|
||||
<th class="coupon"><label for="coupon">{intl l="You may have a coupon ?"}</label></th>
|
||||
<td class="coupon">
|
||||
{form_field form=$form field='success_url'}
|
||||
<input type="hidden" name="{$name}" value="{url path="/order/invoice"}" />
|
||||
{/form_field}
|
||||
{form_field form=$form field='coupon-code'}
|
||||
<div class="{if $error}has-error{/if}">
|
||||
<div class="input-group">
|
||||
<label class="control-label sr-only" for="code">{intl l='Code :'}</label>
|
||||
<input id="coupon" class="form-control" type="text" name="{$name}" value="{$value}" placeholder="{intl l='Coupon code'}" required>
|
||||
<span class="input-group-btn">
|
||||
<button type="submit" class="btn btn-coupon">{intl l="Ok"}</button>
|
||||
</span>
|
||||
</div>
|
||||
{if $error}<span class="help-block">{$message}</span>{/if}
|
||||
</div>
|
||||
{/form_field}
|
||||
<!-- /input-group -->
|
||||
</td>
|
||||
</tr>
|
||||
<tr >
|
||||
<th class="total">{intl l="Total"}</th>
|
||||
<td class="total">
|
||||
<div class="total-price">
|
||||
<span class="price">{{cart attr="total_taxed_price"} + {order attr="postage"}} {currency attr="symbol"}</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-6 col-sm-9 col-sm-offset-3 col-xs-12">
|
||||
<table class="table table-cart table-cart-total">
|
||||
<tfoot>
|
||||
{$discount={order attr="discount"}}
|
||||
{if $discount}
|
||||
<tr>
|
||||
<th class="discount">{intl l="Discount"}</th>
|
||||
<td class="shipping">
|
||||
<div class="shipping-price">
|
||||
<span class="price">{$discount} {currency attr="symbol"}</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{/if}
|
||||
<tr>
|
||||
<th class="coupon"><label for="coupon">{intl l="You may have a coupon ?"}</label></th>
|
||||
<td class="coupon">
|
||||
{form_field form=$form field='success_url'}
|
||||
<input type="hidden" name="{$name}" value="{url path="/order/invoice"}" />
|
||||
{/form_field}
|
||||
{form_field form=$form field='coupon-code'}
|
||||
<div class="{if $error}has-error{/if}">
|
||||
<div class="input-group">
|
||||
<label class="control-label sr-only" for="code">{intl l='Code :'}</label>
|
||||
<input id="coupon" class="form-control" type="text" name="{$name}" value="{$value}" placeholder="{intl l='Coupon code'}" required>
|
||||
<span class="input-group-btn">
|
||||
<button type="submit" class="btn btn-coupon">{intl l="Ok"}</button>
|
||||
</span>
|
||||
</div>
|
||||
{if $error}<span class="help-block">{$message}</span>{/if}
|
||||
</div>
|
||||
{/form_field}
|
||||
<!-- /input-group -->
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="shipping">{intl l="Shipping Tax"}</th>
|
||||
<td class="shipping">
|
||||
<div class="shipping-price">
|
||||
<span class="price">{order attr="postage"} {currency attr="symbol"}</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{intl l="Total excl. taxes"}</th>
|
||||
<td>
|
||||
<div>
|
||||
<span class="price">{{cart attr="total_price"} + {order attr="postage"}} {currency attr="symbol"}</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="total">{intl l="Total incl. taxes"}</th>
|
||||
<td class="total">
|
||||
<div class="total-price">
|
||||
<span class="price">{{cart attr="total_taxed_price"} + {order attr="postage"}} {currency attr="symbol"}</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{/form}
|
||||
|
||||
@@ -244,7 +274,6 @@
|
||||
{/loop}
|
||||
|
||||
<a href="#" class="btn btn-change-address hidden">{intl l="Change address"}</a>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -266,21 +295,44 @@
|
||||
{loop type="payment" name="payments" force_return="true"}
|
||||
{assign "paymentModuleId" $ID}
|
||||
<li class="list-group-item text-left">
|
||||
<label for="payment_{$paymentModuleId}">
|
||||
<input type="radio" name="{$name}" id="payment_{$paymentModuleId}" value="{$paymentModuleId}" {if $LOOP_TOTAL ==1 && $LOOP_COUNT == 1}checked{/if}>
|
||||
<label for="payment_{$paymentModuleId}">
|
||||
<input type="radio" name="{$name}" id="payment_{$paymentModuleId}" value="{$paymentModuleId}" {if $LOOP_TOTAL ==1 && $LOOP_COUNT == 1}checked{/if}>
|
||||
|
||||
{loop type="image" name="paymentspicture" source="module" source_id=$ID force_return="true" width="100" height="72"}
|
||||
<img src="{$IMAGE_URL}" alt="{intl l="Pay with %module_title" module_title={$TITLE}}">
|
||||
{/loop}
|
||||
{loop type="image" name="paymentspicture" source="module" source_id=$ID force_return="true" width="100" height="72"}
|
||||
<img src="{$IMAGE_URL}" alt="{intl l="Pay with %module_title" module_title={$TITLE}}">
|
||||
{/loop}
|
||||
|
||||
{$TITLE}
|
||||
</label>
|
||||
{$TITLE}
|
||||
</label>
|
||||
</li>
|
||||
{/loop}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{/form_field}
|
||||
|
||||
{form_field form=$form field="agreed"}
|
||||
<div class="well">
|
||||
<div class="form-group group-agreed{if $error} has-error{/if}">
|
||||
<div class="control-input">
|
||||
<div class="checkbox">
|
||||
<label class="control-label" for="{$label_attr.for}">
|
||||
<input type="checkbox" name="{$name}" id="{$label_attr.for}" value="{$value}"{if $checked} checked{/if} {if $required} aria-required="true" required{/if}>
|
||||
{$termsAndConditionsId={config key="terms_conditions_content_id"}}
|
||||
{if $termsAndConditionsId}
|
||||
{loop name="content-terms" type="content" id=$termsAndConditionsId}
|
||||
{$termsAndConditionsUrl=$URL}
|
||||
{/loop}
|
||||
{/if}
|
||||
{intl l="I've read and agreed on <a href='%link' class='terms-quickview'>Terms & Conditions</a>" link="$termsAndConditionsUrl"}.
|
||||
</label>
|
||||
{if $error }
|
||||
<span class="help-block">{$message}</span>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div><!--/.form-group-->
|
||||
</div>
|
||||
{/form_field}
|
||||
|
||||
<a href="{url path="/order/delivery"}" role="button" class="btn btn-back"><span>{intl l="Back"}</span></a>
|
||||
@@ -309,6 +361,25 @@ jQuery(function($) {
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
$(".terms-quickview").on('click', function (ev) {
|
||||
ev.preventDefault();
|
||||
|
||||
$.get(this.href, function (data) {
|
||||
// Hide all currently active bootbox dialogs
|
||||
bootbox.hideAll();
|
||||
// Show dialog
|
||||
bootbox.dialog({
|
||||
message : $("#content-main",data),
|
||||
onEscape: function() {
|
||||
bootbox.hideAll();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
{/block}
|
||||
|
||||