diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt new file mode 100644 index 000000000..6dca9789e --- /dev/null +++ b/CONTRIBUTORS.txt @@ -0,0 +1,12 @@ +If you contributes or contributed to this project and do not appear in this list below, +please email us (info@thelia.net) or fork this file on Github and send a pull-request. + +Manuel Raynaud - mraynaud@openstudio.fr +Etienne Roudeix - eroudeix@openstudio.fr +Franck Allimant - franck@allimant.org +Guillaume Morel - gmorel@openstudio.fr +Michael Espeche - mespeche@openstudio.fr +Christophe Laffont - claffont@openstudio.fr +Bruno Goléo - bgoleo@openstudio.fr +Stéphanie Pinet - spinet@openstudio.fr +Cédric Sibaud - csibaud@openstudio.fr \ No newline at end of file diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index 5a6556598..efdbefe24 100755 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -1,5 +1,4 @@ THELIA -Copyright (C) 2005-2013 par OpenStudio - -If you contribute to THELIA and you are not in the contributor list, please contact us. +Copyright (C) 2005 OpenStudio +THELIA application uses externals components and libraries which are released under their own GPL compatible license terms. \ No newline at end of file diff --git a/COPYING.txt b/LICENSE.txt similarity index 100% rename from COPYING.txt rename to LICENSE.txt diff --git a/Licence.txt b/Licence.txt deleted file mode 100755 index 65c5ca88a..000000000 --- a/Licence.txt +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/composer.json b/composer.json index e96385edd..9eb036a76 100755 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name" : "thelia/thelia", "description" : "Thelia is an ecommerce CMS.", "license" : "GPL-3.0+", - "homepage" : "http://thelia.net", + "homepage" : "http://thelia.net/v2", "support" : { "forum" : "http://thelia.net/forum", "wiki" : "http://thelia.net/wiki" diff --git a/composer.lock b/composer.lock index a6f05615a..2b0e5a88a 100755 --- a/composer.lock +++ b/composer.lock @@ -3,7 +3,7 @@ "This file locks the dependencies of your project to a known state", "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file" ], - "hash": "4f3fabbb795a71df45ae9f6ccb6df355", + "hash": "009aced8b279e1c14558460fff2cc993", "packages": [ { "name": "ensepar/html2pdf", diff --git a/core/lib/Thelia/Action/Administrator.php b/core/lib/Thelia/Action/Administrator.php index 0f3891e15..2bbfce8a8 100644 --- a/core/lib/Thelia/Action/Administrator.php +++ b/core/lib/Thelia/Action/Administrator.php @@ -23,11 +23,9 @@ namespace Thelia\Action; -use Propel\Runtime\ActiveQuery\Criteria; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Thelia\Core\Event\Administrator\AdministratorEvent; use Thelia\Core\Event\TheliaEvents; -use Thelia\Core\Security\AccessManager; use Thelia\Model\Admin as AdminModel; use Thelia\Model\AdminQuery; @@ -69,7 +67,7 @@ class Administrator extends BaseAction implements EventSubscriberInterface ->setProfileId($event->getProfile()) ; - if('' !== $event->getPassword()) { + if ('' !== $event->getPassword()) { $administrator->setPassword($event->getPassword()); } diff --git a/core/lib/Thelia/Action/Coupon.php b/core/lib/Thelia/Action/Coupon.php index e3a8defbf..776041527 100755 --- a/core/lib/Thelia/Action/Coupon.php +++ b/core/lib/Thelia/Action/Coupon.php @@ -124,11 +124,17 @@ class Coupon extends BaseAction implements EventSubscriberInterface // @todo insert false product in cart with the name of the coupon and the discount as negative price // Decrement coupon quantity + // @todo move this part in after order event $couponQuery = CouponQuery::create(); $couponModel = $couponQuery->findOneByCode($coupon->getCode()); $couponManager->decrementeQuantity($couponModel); - $request->getSession()->getCart()->setDiscount($totalDiscount); + $request + ->getSession() + ->getCart() + ->setDiscount($totalDiscount) + ->save() + ; } diff --git a/core/lib/Thelia/Action/Lang.php b/core/lib/Thelia/Action/Lang.php index 1c74da3bd..3acb62b29 100644 --- a/core/lib/Thelia/Action/Lang.php +++ b/core/lib/Thelia/Action/Lang.php @@ -34,7 +34,6 @@ use Thelia\Model\ConfigQuery; use Thelia\Model\LangQuery; use Thelia\Model\Lang as LangModel; - /** * Class Lang * @package Thelia\Action @@ -105,7 +104,7 @@ class Lang extends BaseAction implements EventSubscriberInterface public function langUrl(LangUrlEvent $event) { - foreach($event->getUrl() as $id => $url){ + foreach ($event->getUrl() as $id => $url) { LangQuery::create() ->filterById($id) ->update(array('Url' => $url)); @@ -143,4 +142,4 @@ class Lang extends BaseAction implements EventSubscriberInterface TheliaEvents::LANG_URL => array('langUrl', 128) ); } -} \ No newline at end of file +} diff --git a/core/lib/Thelia/Action/Module.php b/core/lib/Thelia/Action/Module.php index ddc285960..a994288d9 100644 --- a/core/lib/Thelia/Action/Module.php +++ b/core/lib/Thelia/Action/Module.php @@ -70,7 +70,7 @@ class Module extends BaseAction implements EventSubscriberInterface $con->beginTransaction(); try { - if(null === $module->getFullNamespace()) { + if (null === $module->getFullNamespace()) { throw new \LogicException('can not instanciante this module if namespace is null. Maybe the model is not loaded ?'); } diff --git a/core/lib/Thelia/Action/Newsletter.php b/core/lib/Thelia/Action/Newsletter.php index fe489e120..aeb26f3d6 100644 --- a/core/lib/Thelia/Action/Newsletter.php +++ b/core/lib/Thelia/Action/Newsletter.php @@ -29,7 +29,6 @@ use Thelia\Action\BaseAction; use Thelia\Model\NewsletterQuery; use Thelia\Model\Newsletter as NewsletterModel; - /** * Class Newsletter * @package Thelia\Action @@ -52,14 +51,14 @@ class Newsletter extends BaseAction implements EventSubscriberInterface public function unsubscribe(NewsletterEvent $event) { - if(null !== $nl = NewsletterQuery::create()->findPk($event->getId())) { + if (null !== $nl = NewsletterQuery::create()->findPk($event->getId())) { $nl->delete(); } } public function update(NewsletterEvent $event) { - if(null !== $nl = NewsletterQuery::create()->findPk($event->getId())) { + if (null !== $nl = NewsletterQuery::create()->findPk($event->getId())) { $nl->setEmail($event->getEmail()) ->setFirstname($event->getFirstname()) ->setLastname($event->getLastname()) @@ -96,4 +95,4 @@ class Newsletter extends BaseAction implements EventSubscriberInterface TheliaEvents::NEWSLETTER_UNSUBSCRIBE => array('unsubscribe', 128) ); } -} \ No newline at end of file +} diff --git a/core/lib/Thelia/Action/Order.php b/core/lib/Thelia/Action/Order.php index 532284382..3d5d2be77 100755 --- a/core/lib/Thelia/Action/Order.php +++ b/core/lib/Thelia/Action/Order.php @@ -32,6 +32,8 @@ use Thelia\Core\Event\Order\OrderEvent; use Thelia\Core\Event\TheliaEvents; use Thelia\Exception\TheliaProcessException; use Thelia\Model\AddressQuery; +use Thelia\Model\ConfigQuery; +use Thelia\Model\MessageQuery; use Thelia\Model\OrderProductAttributeCombination; use Thelia\Model\ModuleQuery; use Thelia\Model\OrderProduct; @@ -291,7 +293,50 @@ class Order extends BaseAction implements EventSubscriberInterface */ public function sendOrderEmail(OrderEvent $event) { - /* @todo */ + $contact_email = ConfigQuery::read('contact_email'); + if($contact_email) { + $order = $event->getOrder(); + $customer = $order->getCustomer(); + + $parser = $this->container->get("thelia.parser"); + + $parser->assign('order_id', $order->getId()); + $parser->assign('order_ref', $order->getRef()); + + $message = MessageQuery::create() + ->filterByName('order_confirmation') + ->findOne(); + + $message + ->setLocale($order->getLang()->getLocale()); + + $subject = $parser->fetch(sprintf("string:%s", $message->getSubject())); + $htmlMessage = $parser->fetch(sprintf("string:%s", $message->getHtmlMessage())); + $textMessage = $parser->fetch(sprintf("string:%s", $message->getTextMessage())); + + $instance = \Swift_Message::newInstance($subject) + ->addTo($customer->getEmail(), $customer->getFirstname()." ".$customer->getLastname()) + ->addFrom(ConfigQuery::read('contact_email'), ConfigQuery::read('company_name')) + ; + $instance + ->setBody($htmlMessage, 'text/html') + ->addPart($textMessage, 'text/plain'); + + $mail = $this->getMailer()->send($instance); + } + } + + /** + * + * return an instance of \Swift_Mailer with good Transporter configured. + * + * @return \Swift_Mailer + */ + public function getMailer() + { + $mailer = $this->container->get('mailer'); + + return $mailer->getSwiftMailer(); } /** diff --git a/core/lib/Thelia/Action/Product.php b/core/lib/Thelia/Action/Product.php index e82b92bf6..e56df6523 100644 --- a/core/lib/Thelia/Action/Product.php +++ b/core/lib/Thelia/Action/Product.php @@ -52,14 +52,6 @@ use Thelia\Core\Event\Product\ProductSetTemplateEvent; use Thelia\Model\ProductSaleElementsQuery; use Thelia\Core\Event\Product\ProductDeleteCategoryEvent; use Thelia\Core\Event\Product\ProductAddCategoryEvent; -use Thelia\Model\AttributeAvQuery; -use Thelia\Model\AttributeCombination; -use Thelia\Core\Event\Product\ProductSaleElementCreateEvent; -use Propel\Runtime\Propel; -use Thelia\Model\Map\ProductTableMap; -use Thelia\Core\Event\Product\ProductSaleElementDeleteEvent; -use Thelia\Model\ProductPrice; -use Thelia\Model\ProductSaleElements; use Thelia\Core\Event\Product\ProductAddAccessoryEvent; use Thelia\Core\Event\Product\ProductDeleteAccessoryEvent; diff --git a/core/lib/Thelia/Action/ProductSaleElement.php b/core/lib/Thelia/Action/ProductSaleElement.php index 730fe0764..8349eb1bf 100644 --- a/core/lib/Thelia/Action/ProductSaleElement.php +++ b/core/lib/Thelia/Action/ProductSaleElement.php @@ -25,9 +25,6 @@ namespace Thelia\Action; use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Thelia\Model\ProductQuery; -use Thelia\Model\Product as ProductModel; - use Thelia\Core\Event\TheliaEvents; use Thelia\Core\Event\ProductSaleElement\ProductSaleElementCreateEvent; use Thelia\Model\Map\ProductSaleElementsTableMap; @@ -49,7 +46,7 @@ class ProductSaleElement extends BaseAction implements EventSubscriberInterface /** * Create a new product sale element, with or without combination * - * @param ProductSaleElementCreateEvent $event + * @param ProductSaleElementCreateEvent $event * @throws Exception */ public function create(ProductSaleElementCreateEvent $event) @@ -67,11 +64,10 @@ class ProductSaleElement extends BaseAction implements EventSubscriberInterface ->findOne($con); if ($salesElement == null) { - // Create a new product sale element + // Create a new default product sale element $salesElement = $event->getProduct()->createDefaultProductSaleElement($con, 0, 0, $event->getCurrencyId(), true); - } - else { - // This one is the default + } else { + // This (new) one is the default $salesElement->setIsDefault(true)->save($con); } @@ -98,8 +94,7 @@ class ProductSaleElement extends BaseAction implements EventSubscriberInterface // Store all the stuff ! $con->commit(); - } - catch (\Exception $ex) { + } catch (\Exception $ex) { $con->rollback(); @@ -122,6 +117,9 @@ class ProductSaleElement extends BaseAction implements EventSubscriberInterface try { + // Update the product's tax rule + $event->getProduct()->setTaxRuleId($event->getTaxRuleId())->save($con); + // If product sale element is not defined, create it. if ($salesElement == null) { $salesElement = new ProductSaleElements(); @@ -158,16 +156,28 @@ class ProductSaleElement extends BaseAction implements EventSubscriberInterface ; } - $productPrice - ->setPromoPrice($event->getSalePrice()) - ->setPrice($event->getPrice()) - ->save($con) - ; + // Check if we have to store the price + $productPrice->setFromDefaultCurrency($event->getFromDefaultCurrency()); + + if ($event->getFromDefaultCurrency() == 0) { + // Store the price + $productPrice + ->setPromoPrice($event->getSalePrice()) + ->setPrice($event->getPrice()) + ; + } else { + // Do not store the price. + $productPrice + ->setPromoPrice(0) + ->setPrice(0) + ; + } + + $productPrice->save($con); // Store all the stuff ! $con->commit(); - } - catch (\Exception $ex) { + } catch (\Exception $ex) { $con->rollback(); @@ -197,19 +207,21 @@ class ProductSaleElement extends BaseAction implements EventSubscriberInterface if ($product->countSaleElements() <= 0) { // If we just deleted the last PSE, create a default one $product->createDefaultProductSaleElement($con, 0, 0, $event->getCurrencyId(), true); - } - else if ($product->getDefaultSaleElements() == null) { + } elseif ($pse->getIsDefault()) { // If we deleted the default PSE, make the last created one the default - $pse = ProductSaleElementsQuery::create()->filterByProductId($this->id)->orderByCreatedAt(Criteria::DESC)->findOne($con); + $pse = ProductSaleElementsQuery::create() + ->filterByProductId($product->getId()) + ->orderByCreatedAt(Criteria::DESC) + ->findOne($con) + ; $pse->setIsDefault(true)->save($con); } // Store all the stuff ! $con->commit(); - } - catch (\Exception $ex) { + } catch (\Exception $ex) { $con->rollback(); diff --git a/core/lib/Thelia/Action/Profile.php b/core/lib/Thelia/Action/Profile.php index 544882700..a35a0d250 100644 --- a/core/lib/Thelia/Action/Profile.php +++ b/core/lib/Thelia/Action/Profile.php @@ -23,7 +23,6 @@ namespace Thelia\Action; -use Propel\Runtime\ActiveQuery\Criteria; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Thelia\Core\Event\Profile\ProfileEvent; use Thelia\Core\Event\TheliaEvents; @@ -90,7 +89,7 @@ class Profile extends BaseAction implements EventSubscriberInterface { if (null !== $profile = ProfileQuery::create()->findPk($event->getId())) { ProfileResourceQuery::create()->filterByProfileId($event->getId())->delete(); - foreach($event->getResourceAccess() as $resourceCode => $accesses) { + foreach ($event->getResourceAccess() as $resourceCode => $accesses) { $manager = new AccessManager(0); $manager->build($accesses); @@ -114,7 +113,7 @@ class Profile extends BaseAction implements EventSubscriberInterface { if (null !== $profile = ProfileQuery::create()->findPk($event->getId())) { ProfileModuleQuery::create()->filterByProfileId($event->getId())->delete(); - foreach($event->getModuleAccess() as $moduleCode => $accesses) { + foreach ($event->getModuleAccess() as $moduleCode => $accesses) { $manager = new AccessManager(0); $manager->build($accesses); diff --git a/core/lib/Thelia/Action/Tax.php b/core/lib/Thelia/Action/Tax.php index c35d87bbe..5189bf9db 100644 --- a/core/lib/Thelia/Action/Tax.php +++ b/core/lib/Thelia/Action/Tax.php @@ -23,7 +23,6 @@ namespace Thelia\Action; -use Propel\Runtime\ActiveQuery\Criteria; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Thelia\Core\Event\Tax\TaxEvent; use Thelia\Core\Event\TheliaEvents; diff --git a/core/lib/Thelia/Action/TaxRule.php b/core/lib/Thelia/Action/TaxRule.php index e6d42976e..a5368a400 100644 --- a/core/lib/Thelia/Action/TaxRule.php +++ b/core/lib/Thelia/Action/TaxRule.php @@ -27,7 +27,6 @@ use Propel\Runtime\ActiveQuery\Criteria; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Thelia\Core\Event\Tax\TaxRuleEvent; use Thelia\Core\Event\TheliaEvents; -use Thelia\Model\Map\TaxRuleTableMap; use Thelia\Model\TaxRuleCountry; use Thelia\Model\TaxRuleCountryQuery; use Thelia\Model\TaxRule as TaxRuleModel; diff --git a/core/lib/Thelia/Command/GenerateResources.php b/core/lib/Thelia/Command/GenerateResources.php index fcad56b41..124648b2a 100644 --- a/core/lib/Thelia/Command/GenerateResources.php +++ b/core/lib/Thelia/Command/GenerateResources.php @@ -61,19 +61,19 @@ class GenerateResources extends ContainerAwareCommand $constants = $class->getConstants(); - if(count($constants) == 0) { + if (count($constants) == 0) { $output->writeln('No resources found'); exit; } - switch($input->getOption("output")) { + switch ($input->getOption("output")) { case 'sql': $output->writeln( 'INSERT INTO ' . ResourceTableMap::TABLE_NAME . ' (`id`, `code`, `created_at`, `updated_at`) VALUES ' ); $compteur = 0; - foreach($constants as $constant => $value) { - if($constant == AdminResources::SUPERADMINISTRATOR) { + foreach ($constants as $constant => $value) { + if ($constant == AdminResources::SUPERADMINISTRATOR) { continue; } $compteur++; @@ -87,8 +87,8 @@ class GenerateResources extends ContainerAwareCommand 'INSERT INTO ' . ResourceI18nTableMap::TABLE_NAME . ' (`id`, `locale`, `title`) VALUES ' ); $compteur = 0; - foreach($constants as $constant => $value) { - if($constant == AdminResources::SUPERADMINISTRATOR) { + foreach ($constants as $constant => $value) { + if ($constant == AdminResources::SUPERADMINISTRATOR) { continue; } @@ -105,8 +105,8 @@ class GenerateResources extends ContainerAwareCommand } break; default : - foreach($constants as $constant => $value) { - if($constant == AdminResources::SUPERADMINISTRATOR) { + foreach ($constants as $constant => $value) { + if ($constant == AdminResources::SUPERADMINISTRATOR) { continue; } $output->writeln('[' . $constant . "] => " . $value); diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index df8c9e4df..afaacb85a 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -174,7 +174,7 @@ \d+ - + Thelia\Controller\Admin\OrderController::generateDeliveryPdf \d+ @@ -303,10 +303,14 @@ Thelia\Controller\Admin\ProductController::updateContentPositionAction - + Thelia\Controller\Admin\ProductController::priceCaclulator + + Thelia\Controller\Admin\ProductController::loadConvertedPrices + + @@ -360,8 +364,8 @@ Thelia\Controller\Admin\ProductController::deleteProductSaleElementAction - - Thelia\Controller\Admin\ProductController::updateProductSaleElementAction + + Thelia\Controller\Admin\ProductController::updateProductSaleElementsAction diff --git a/core/lib/Thelia/Controller/Admin/AbstractCrudController.php b/core/lib/Thelia/Controller/Admin/AbstractCrudController.php index 114bd75c1..e38e08a7a 100644 --- a/core/lib/Thelia/Controller/Admin/AbstractCrudController.php +++ b/core/lib/Thelia/Controller/Admin/AbstractCrudController.php @@ -56,7 +56,7 @@ abstract class AbstractCrudController extends BaseAdminController * @param string $defaultListOrder the default object list order, or null if list is not sortable. Example: manual * @param string $orderRequestParameterName Name of the request parameter that set the list order (null if list is not sortable) * - * @param string $resourceCode the 'resource' code. Example: "admin.configuration.message" + * @param string $resourceCode the 'resource' code. Example: "admin.configuration.message" * * @param string $createEventIdentifier the dispatched create TheliaEvent identifier. Example: TheliaEvents::MESSAGE_CREATE * @param string $updateEventIdentifier the dispatched update TheliaEvent identifier. Example: TheliaEvents::MESSAGE_UPDATE diff --git a/core/lib/Thelia/Controller/Admin/AdministratorController.php b/core/lib/Thelia/Controller/Admin/AdministratorController.php index 10780037a..214d4cd7a 100644 --- a/core/lib/Thelia/Controller/Admin/AdministratorController.php +++ b/core/lib/Thelia/Controller/Admin/AdministratorController.php @@ -23,7 +23,6 @@ namespace Thelia\Controller\Admin; -use Thelia\Core\Security\AccessManager; use Thelia\Core\Security\Resource\AdminResources; use Thelia\Core\Event\Administrator\AdministratorEvent; use Thelia\Core\Event\TheliaEvents; @@ -31,7 +30,6 @@ use Thelia\Form\AdministratorCreationForm; use Thelia\Form\AdministratorModificationForm; use Thelia\Model\AdminQuery; - class AdministratorController extends AbstractCrudController { public function __construct() @@ -158,7 +156,6 @@ class AdministratorController extends AbstractCrudController return $object->getId(); } - protected function renderListTemplate($currentOrder) { // We always return to the feature edition form @@ -198,4 +195,4 @@ class AdministratorController extends AbstractCrudController "admin.configuration.administrators.view" ); } -} \ No newline at end of file +} diff --git a/core/lib/Thelia/Controller/Admin/AttributeAvController.php b/core/lib/Thelia/Controller/Admin/AttributeAvController.php index 92d50955b..97b4cd5e6 100644 --- a/core/lib/Thelia/Controller/Admin/AttributeAvController.php +++ b/core/lib/Thelia/Controller/Admin/AttributeAvController.php @@ -47,10 +47,7 @@ class AttributeAvController extends AbstractCrudController 'manual', 'order', - AdminResources::ATTRIBUTE_VIEW, - AdminResources::ATTRIBUTE_CREATE, - AdminResources::ATTRIBUTE_UPDATE, - AdminResources::ATTRIBUTE_DELETE, + AdminResources::ATTRIBUTE, TheliaEvents::ATTRIBUTE_AV_CREATE, TheliaEvents::ATTRIBUTE_AV_UPDATE, diff --git a/core/lib/Thelia/Controller/Admin/BaseAdminController.php b/core/lib/Thelia/Controller/Admin/BaseAdminController.php index be6deca15..e4d9550d3 100755 --- a/core/lib/Thelia/Controller/Admin/BaseAdminController.php +++ b/core/lib/Thelia/Controller/Admin/BaseAdminController.php @@ -115,7 +115,7 @@ class BaseAdminController extends BaseController * Check current admin user authorisations. An ADMIN role is assumed. * * @param mixed $resources a single resource or an array of resources. - * @param mixed $accesses a single access or an array of accesses. + * @param mixed $accesses a single access or an array of accesses. * * @return mixed null if authorization is granted, or a Response object which contains the error page otherwise * @@ -369,8 +369,8 @@ class BaseAdminController extends BaseController * Render the given template, and returns the result as an Http Response. * * @param $templateName the complete template name, with extension - * @param array $args the template arguments - * @param int $status http code status + * @param array $args the template arguments + * @param int $status http code status * @return \Symfony\Component\HttpFoundation\Response */ protected function render($templateName, $args = array(), $status = 200) diff --git a/core/lib/Thelia/Controller/Admin/CouponController.php b/core/lib/Thelia/Controller/Admin/CouponController.php index 59ef312d5..da0ec200a 100755 --- a/core/lib/Thelia/Controller/Admin/CouponController.php +++ b/core/lib/Thelia/Controller/Admin/CouponController.php @@ -522,7 +522,7 @@ class CouponController extends BaseAdminController $condition = array(); $condition['serviceId'] = $availableCondition->getServiceId(); $condition['name'] = $availableCondition->getName(); - $condition['toolTip'] = $availableCondition->getToolTip(); + // $condition['toolTip'] = $availableCondition->getToolTip(); $cleanedConditions[] = $condition; } diff --git a/core/lib/Thelia/Controller/Admin/CurrencyController.php b/core/lib/Thelia/Controller/Admin/CurrencyController.php index a50a5cdd6..504877157 100644 --- a/core/lib/Thelia/Controller/Admin/CurrencyController.php +++ b/core/lib/Thelia/Controller/Admin/CurrencyController.php @@ -32,6 +32,7 @@ use Thelia\Model\CurrencyQuery; use Thelia\Form\CurrencyModificationForm; use Thelia\Form\CurrencyCreationForm; use Thelia\Core\Event\UpdatePositionEvent; +use Thelia\Core\Security\AccessManager; /** * Manages currencies diff --git a/core/lib/Thelia/Controller/Admin/CustomerController.php b/core/lib/Thelia/Controller/Admin/CustomerController.php index 7f8cd8615..df75333c8 100644 --- a/core/lib/Thelia/Controller/Admin/CustomerController.php +++ b/core/lib/Thelia/Controller/Admin/CustomerController.php @@ -25,7 +25,6 @@ namespace Thelia\Controller\Admin; use Propel\Runtime\Exception\PropelException; use Thelia\Core\Security\Resource\AdminResources; -use Thelia\Core\Event\Customer\CustomerAddressEvent; use Thelia\Core\Event\Customer\CustomerCreateOrUpdateEvent; use Thelia\Core\Event\Customer\CustomerEvent; use Thelia\Core\Event\TheliaEvents; diff --git a/core/lib/Thelia/Controller/Admin/FeatureAvController.php b/core/lib/Thelia/Controller/Admin/FeatureAvController.php index f3b80ef51..f1ac84f7b 100644 --- a/core/lib/Thelia/Controller/Admin/FeatureAvController.php +++ b/core/lib/Thelia/Controller/Admin/FeatureAvController.php @@ -47,10 +47,7 @@ class FeatureAvController extends AbstractCrudController 'manual', 'order', - AdminResources::FEATURE_VIEW, - AdminResources::FEATURE_CREATE, - AdminResources::FEATURE_UPDATE, - AdminResources::FEATURE_DELETE, + AdminResources::FEATURE, TheliaEvents::FEATURE_AV_CREATE, TheliaEvents::FEATURE_AV_UPDATE, diff --git a/core/lib/Thelia/Controller/Admin/LangController.php b/core/lib/Thelia/Controller/Admin/LangController.php index 9b6074955..8e0ca5d1c 100644 --- a/core/lib/Thelia/Controller/Admin/LangController.php +++ b/core/lib/Thelia/Controller/Admin/LangController.php @@ -41,7 +41,6 @@ use Thelia\Form\Lang\LangUrlForm; use Thelia\Model\ConfigQuery; use Thelia\Model\LangQuery; - /** * Class LangController * @package Thelia\Controller\Admin @@ -53,7 +52,6 @@ class LangController extends BaseAdminController public function defaultAction() { if (null !== $response = $this->checkAuth(AdminResources::LANGUAGE, AccessManager::VIEW)) return $response; - return $this->renderDefault(); } @@ -120,7 +118,7 @@ class LangController extends BaseAdminController $changedObject = $event->getLang(); $this->adminLogAppend(sprintf("%s %s (ID %s) modified", 'Lang', $changedObject->getTitle(), $changedObject->getId())); $this->redirectToRoute('/admin/configuration/languages'); - } catch(\Exception $e) { + } catch (\Exception $e) { $error_msg = $e->getMessage(); } @@ -162,7 +160,7 @@ class LangController extends BaseAdminController $error = $e->getMessage(); } - if($error) { + if ($error) { return $this->nullResponse(500); } else { return $this->nullResponse(); @@ -281,7 +279,7 @@ class LangController extends BaseAdminController $event = new LangUrlEvent(); foreach ($data as $key => $value) { $pos= strpos($key, LangUrlForm::LANG_PREFIX); - if(false !== strpos($key, LangUrlForm::LANG_PREFIX)) { + if (false !== strpos($key, LangUrlForm::LANG_PREFIX)) { $event->addUrl(substr($key,strlen(LangUrlForm::LANG_PREFIX)), $value); } } @@ -326,4 +324,4 @@ class LangController extends BaseAdminController $this->redirectToRoute('admin.configuration.languages'); } -} \ No newline at end of file +} diff --git a/core/lib/Thelia/Controller/Admin/LanguageController.php b/core/lib/Thelia/Controller/Admin/LanguageController.php index 834a4cbed..7559cb5cc 100644 --- a/core/lib/Thelia/Controller/Admin/LanguageController.php +++ b/core/lib/Thelia/Controller/Admin/LanguageController.php @@ -38,5 +38,5 @@ class LanguageController extends BaseAdminController if (null !== $response = $this->checkAuth(AdminResources::LANGUAGE, AccessManager::VIEW)) return $response; return $this->render("languages"); } - -} \ No newline at end of file + +} diff --git a/core/lib/Thelia/Controller/Admin/MailingSystemController.php b/core/lib/Thelia/Controller/Admin/MailingSystemController.php index dba5d2417..5bf2f4e73 100644 --- a/core/lib/Thelia/Controller/Admin/MailingSystemController.php +++ b/core/lib/Thelia/Controller/Admin/MailingSystemController.php @@ -38,5 +38,5 @@ class MailingSystemController extends BaseAdminController if (null !== $response = $this->checkAuth(AdminResources::MAILING_SYSTEM, AccessManager::VIEW)) return $response; return $this->render("mailing-system"); } - -} \ No newline at end of file + +} diff --git a/core/lib/Thelia/Controller/Admin/MessageController.php b/core/lib/Thelia/Controller/Admin/MessageController.php index c0bce7918..407578a08 100644 --- a/core/lib/Thelia/Controller/Admin/MessageController.php +++ b/core/lib/Thelia/Controller/Admin/MessageController.php @@ -45,10 +45,7 @@ class MessageController extends AbstractCrudController null, // no sort order change null, // no sort order change - AdminResources::MESSAGE_VIEW, - AdminResources::MESSAGE_CREATE, - AdminResources::MESSAGE_UPDATE, - AdminResources::MESSAGE_DELETE, + AdminResources::MESSAGE, TheliaEvents::MESSAGE_CREATE, TheliaEvents::MESSAGE_UPDATE, diff --git a/core/lib/Thelia/Controller/Admin/ModuleController.php b/core/lib/Thelia/Controller/Admin/ModuleController.php index 44a1c2a24..53322949a 100644 --- a/core/lib/Thelia/Controller/Admin/ModuleController.php +++ b/core/lib/Thelia/Controller/Admin/ModuleController.php @@ -41,7 +41,7 @@ class ModuleController extends BaseAdminController public function indexAction() { if (null !== $response = $this->checkAuth(AdminResources::MODULE, AccessManager::VIEW)) return $response; - + $modulemanagement = new ModuleManagement(); $modulemanagement->updateModules(); @@ -100,7 +100,7 @@ class ModuleController extends BaseAdminController $this->dispatch(TheliaEvents::MODULE_DELETE, $deleteEvent); - if($deleteEvent->hasModule() === false) { + if ($deleteEvent->hasModule() === false) { throw new \LogicException( $this->getTranslator()->trans("No %obj was updated.", array('%obj' => 'Module'))); } @@ -110,7 +110,7 @@ class ModuleController extends BaseAdminController $message = $e->getMessage(); } - if($message) { + if ($message) { return $this->render("modules", array( "error_message" => $message )); diff --git a/core/lib/Thelia/Controller/Admin/ProductController.php b/core/lib/Thelia/Controller/Admin/ProductController.php index d56898662..84e16815d 100644 --- a/core/lib/Thelia/Controller/Admin/ProductController.php +++ b/core/lib/Thelia/Controller/Admin/ProductController.php @@ -54,7 +54,6 @@ use Thelia\Core\Event\ProductSaleElement\ProductSaleElementCreateEvent; use Thelia\Model\AttributeQuery; use Thelia\Model\AttributeAvQuery; use Thelia\Form\ProductSaleElementUpdateForm; -use Thelia\Model\ProductSaleElements; use Thelia\Model\ProductPriceQuery; use Thelia\Form\ProductDefaultSaleElementUpdateForm; use Thelia\Model\ProductPrice; @@ -62,9 +61,9 @@ use Thelia\Model\Currency; use Symfony\Component\HttpFoundation\JsonResponse; use Thelia\TaxEngine\Calculator; use Thelia\Model\Country; -use Thelia\Model\CountryQuery; -use Thelia\Model\TaxRuleQuery; use Thelia\Tools\NumberFormat; +use Thelia\Model\Product; +use Thelia\Model\CurrencyQuery; /** * Manages products @@ -187,52 +186,115 @@ class ProductController extends AbstractCrudController return $event->hasProduct(); } + protected function updatePriceFromDefaultCurrency($productPrice, $saleElement, $defaultCurrency, $currentCurrency) + { + // Get price for default currency + $priceForDefaultCurrency = ProductPriceQuery::create() + ->filterByCurrency($defaultCurrency) + ->filterByProductSaleElements($saleElement) + ->findOne() + ; + + if ($priceForDefaultCurrency !== null) { + $productPrice + ->setPrice($priceForDefaultCurrency->getPrice() * $currentCurrency->getRate()) + ->setPromoPrice($priceForDefaultCurrency->getPromoPrice() * $currentCurrency->getRate()) + ; + } + } + + protected function appendValue(&$array, $key, $value) + { + if (! isset($array[$key])) $array[$key] = array(); + + $array[$key][] = $value; + } + protected function hydrateObjectForm($object) { - $defaultPseData = $combinationPseData = array(); - // Find product's sale elements $saleElements = ProductSaleElementsQuery::create() ->filterByProduct($object) ->find(); - foreach($saleElements as $saleElement) { + $defaultCurrency = Currency::getDefaultCurrency(); + $currentCurrency = $this->getCurrentEditionCurrency(); + + // Common parts + $defaultPseData = $combinationPseData = array( + "product_id" => $object->getId(), + "tax_rule" => $object->getTaxRuleId() + ); + + foreach ($saleElements as $saleElement) { // Get the product price for the current currency - $productPrice = ProductPriceQuery::create() - ->filterByCurrency($this->getCurrentEditionCurrency()) + ->filterByCurrency($currentCurrency) ->filterByProductSaleElements($saleElement) ->findOne() ; - if ($productPrice == null) $productPrice = new ProductPrice(); + // No one exists ? + if ($productPrice === null) { + $productPrice = new ProductPrice(); + + // If the current currency is not the default one, calculate the price + // using default currency price and current currency rate + if ($currentCurrency->getId() != $defaultCurrency->getId()) { + + $productPrice->setFromDefaultCurrency(true); + + $this->updatePriceFromDefaultCurrency($productPrice, $saleElement, $defaultCurrency, $currentCurrency); + } + } + + // Caclulate prices if we have to use the rate * defaulkt currency price + if ($productPrice->getFromDefaultCurrency() == true) { + $this->updatePriceFromDefaultCurrency($productPrice, $saleElement, $defaultCurrency, $currentCurrency); + } $isDefaultPse = count($saleElement->getAttributeCombinations()) == 0; // If this PSE has no combination -> this is the default one // affect it to the thelia.admin.product_sale_element.update form if ($isDefaultPse) { - $defaultPseData = array( - "product_id" => $object->getId(), "product_sale_element_id" => $saleElement->getId(), "reference" => $saleElement->getRef(), "price" => $productPrice->getPrice(), + "price_with_tax" => $this->computePrice($productPrice->getPrice(), 'without_tax', $object), "use_exchange_rate" => $productPrice->getFromDefaultCurrency() ? 1 : 0, - "tax_rule" => $object->getTaxRuleId(), "currency" => $productPrice->getCurrencyId(), "weight" => $saleElement->getWeight(), "quantity" => $saleElement->getQuantity(), "sale_price" => $productPrice->getPromoPrice(), + "sale_price_with_tax" => $this->computePrice($productPrice->getPromoPrice(), 'without_tax', $object), "onsale" => $saleElement->getPromo() > 0 ? 1 : 0, "isnew" => $saleElement->getNewness() > 0 ? 1 : 0, "isdefault" => $saleElement->getIsDefault() > 0 ? 1 : 0, "ean_code" => $saleElement->getEanCode() ); + } else { - } - else { + if ($saleElement->getIsDefault()) { + $combinationPseData['default_pse'] = $saleElement->getId(); + $combinationPseData['currency'] = $currentCurrency->getId(); + $combinationPseData['use_exchange_rate'] = $productPrice->getFromDefaultCurrency() ? 1 : 0; + } + + $this->appendValue($combinationPseData, "product_sale_element_id" , $saleElement->getId()); + $this->appendValue($combinationPseData, "reference" , $saleElement->getRef()); + $this->appendValue($combinationPseData, "price" , $productPrice->getPrice()); + $this->appendValue($combinationPseData, "price_with_tax" , $this->computePrice($productPrice->getPrice(), 'without_tax', $object)); + $this->appendValue($combinationPseData, "weight" , $saleElement->getWeight()); + $this->appendValue($combinationPseData, "quantity" , $saleElement->getQuantity()); + $this->appendValue($combinationPseData, "sale_price" , $productPrice->getPromoPrice()); + $this->appendValue($combinationPseData, "sale_price_with_tax" , $this->computePrice($productPrice->getPromoPrice(), 'without_tax', $object)); + $this->appendValue($combinationPseData, "onsale" , $saleElement->getPromo() > 0 ? 1 : 0); + $this->appendValue($combinationPseData, "isnew" , $saleElement->getNewness() > 0 ? 1 : 0); + $this->appendValue($combinationPseData, "isdefault" , $saleElement->getIsDefault() > 0 ? 1 : 0); + $this->appendValue($combinationPseData, "ean_code" , $saleElement->getEanCode()); } $defaultPseForm = new ProductDefaultSaleElementUpdateForm($this->getRequest(), "form", $defaultPseData); @@ -242,7 +304,7 @@ class ProductController extends AbstractCrudController $this->getParserContext()->addForm($combinationPseForm); } - // Prepare the data that will hydrate the form + // The "General" tab form $data = array( 'id' => $object->getId(), 'ref' => $object->getRef(), @@ -254,8 +316,6 @@ class ProductController extends AbstractCrudController 'visible' => $object->getVisible(), 'url' => $object->getRewrittenUrl($this->getCurrentEditionLocale()), 'default_category' => $object->getDefaultCategoryId() - - // A terminer pour les prix ); // Setup the object form @@ -808,8 +868,7 @@ class ProductController extends AbstractCrudController try { $this->dispatch(TheliaEvents::PRODUCT_ADD_PRODUCT_SALE_ELEMENT, $event); - } - catch (\Exception $ex) { + } catch (\Exception $ex) { // Any error return $this->errorPage($ex); } @@ -832,8 +891,7 @@ class ProductController extends AbstractCrudController try { $this->dispatch(TheliaEvents::PRODUCT_DELETE_PRODUCT_SALE_ELEMENT, $event); - } - catch (\Exception $ex) { + } catch (\Exception $ex) { // Any error return $this->errorPage($ex); } @@ -841,13 +899,49 @@ class ProductController extends AbstractCrudController $this->redirectToEditionTemplate(); } + /** + * Process a single PSE update, using form data array. + * + * @param array $data the form data + * @throws Exception is someting goes wrong. + */ + protected function processSingleProductSaleElementUpdate($data) + { + $event = new ProductSaleElementUpdateEvent( + $this->getExistingObject(), + $data['product_sale_element_id'] + ); + + $event + ->setReference($data['reference']) + ->setPrice($data['price']) + ->setCurrencyId($data['currency']) + ->setWeight($data['weight']) + ->setQuantity($data['quantity']) + ->setSalePrice($data['sale_price']) + ->setOnsale($data['onsale']) + ->setIsnew($data['isnew']) + ->setIsdefault($data['isdefault']) + ->setEanCode($data['ean_code']) + ->setTaxRuleId($data['tax_rule']) + ->setFromDefaultCurrency($data['use_exchange_rate']) + ; + + $this->dispatch(TheliaEvents::PRODUCT_UPDATE_PRODUCT_SALE_ELEMENT, $event); + + // Log object modification + if (null !== $changedObject = $event->getProductSaleElement()) { + $this->adminLogAppend(sprintf("Product Sale Element (ID %s) for product reference %s modified", $changedObject->getId(), $event->getProduct()->getRef())); + } + } + /** * Change a product sale element */ - protected function processProductSaleElementUpdate($changeForm) { - + protected function processProductSaleElementUpdate($changeForm) + { // Check current user authorization - if (null !== $response = $this->checkAuth("admin.products.update")) return $response; + if (null !== $response = $this->checkAuth($this->resourceCode, AccessManager::UPDATE)) return $response; $error_msg = false; @@ -859,30 +953,34 @@ class ProductController extends AbstractCrudController // Get the form field values $data = $form->getData(); - $event = new ProductSaleElementUpdateEvent( - $this->getExistingObject(), - $data['product_sale_element_id'] - ); + if (is_array($data['product_sale_element_id'])) { - $event - ->setReference($data['reference']) - ->setPrice($data['price']) - ->setCurrencyId($data['currency']) - ->setWeight($data['weight']) - ->setQuantity($data['quantity']) - ->setSalePrice($data['sale_price']) - ->setOnsale($data['onsale']) - ->setIsnew($data['isnew']) - ->setIsdefault($data['isdefault']) - ->setEanCode($data['ean_code']) - ->setTaxrule($data['tax_rule']) - ; + // Common fields + $tmp_data = array( + 'tax_rule' => $data['tax_rule'], + 'currency' => $data['currency'], + 'use_exchange_rate' => $data['use_exchange_rate'], + ); - $this->dispatch(TheliaEvents::PRODUCT_UPDATE_PRODUCT_SALE_ELEMENT, $event); + $count = count($data['product_sale_element_id']); - // Log object modification - if (null !== $changedObject = $event->getProductSaleElement()) { - $this->adminLogAppend(sprintf("Product Sale Element (ID %s) for product reference %s modified", $changedObject->getId(), $event->getProduct()->getRef())); + for ($idx = 0; $idx < $count; $idx++) { + $tmp_data['product_sale_element_id'] = $pse_id = $data['product_sale_element_id'][$idx]; + $tmp_data['reference'] = $data['reference'][$idx]; + $tmp_data['price'] = $data['price'][$idx]; + $tmp_data['weight'] = $data['weight'][$idx]; + $tmp_data['quantity'] = $data['quantity'][$idx]; + $tmp_data['sale_price'] = $data['sale_price'][$idx]; + $tmp_data['onsale'] = isset($data['onsale'][$idx]) ? 1 : 0; + $tmp_data['isnew'] = isset($data['isnew'][$idx]) ? 1 : 0; + $tmp_data['isdefault'] = $data['default_pse'] == $pse_id; + $tmp_data['ean_code'] = $data['ean_code'][$idx]; + + $this->processSingleProductSaleElementUpdate($tmp_data); + } + } else { + // No need to preprocess data + $this->processSingleProductSaleElementUpdate($data); } // If we have to stay on the same page, do not redirect to the succesUrl, just redirect to the edit page again. @@ -892,12 +990,10 @@ class ProductController extends AbstractCrudController // Redirect to the success URL $this->redirect($changeForm->getSuccessUrl()); - } - catch (FormValidationException $ex) { + } catch (FormValidationException $ex) { // Form cannot be validated $error_msg = $this->createStandardFormValidationErrorMessage($ex); - } - catch (\Exception $ex) { + } catch (\Exception $ex) { // Any other error $error_msg = $ex->getMessage(); } @@ -910,9 +1006,10 @@ class ProductController extends AbstractCrudController } /** - * Change a product sale element attached to a combination + * Process the change of product's PSE list. */ - public function updateProductSaleElementAction() { + public function updateProductSaleElementsAction() + { return $this->processProductSaleElementUpdate( new ProductSaleElementUpdateForm($this->getRequest()) ); @@ -921,44 +1018,120 @@ class ProductController extends AbstractCrudController /** * Update default product sale element (not attached to any combination) */ - public function updateProductDefaultSaleElementAction() { - + public function updateProductDefaultSaleElementAction() + { return $this->processProductSaleElementUpdate( new ProductDefaultSaleElementUpdateForm($this->getRequest()) ); } - public function priceCaclulator() { + /** + * Invoked through Ajax; this method calculates the taxed price from the unaxed price, and + * vice versa. + */ + public function priceCaclulator() + { + $return_price = 0; - $price = floatval($this->getRequest()->get('price', 0)); - $tax_rule = intval($this->getRequest()->get('tax_rule_id', 0)); // The tax rule ID - $action = $this->getRequest()->get('action', ''); // With ot without tax - $convert = intval($this->getRequest()->get('convert_from_default_currency', 0)); + $price = floatval($this->getRequest()->get('price', 0)); + $product_id = intval($this->getRequest()->get('product_id', 0)); + $action = $this->getRequest()->get('action', ''); // With ot without tax + $convert = intval($this->getRequest()->get('convert_from_default_currency', 0)); + if (null !== $product = ProductQuery::create()->findPk($product_id)) { + + if ($action == 'to_tax') { + $return_price = $this->computePrice($price, 'without_tax', $product); + } elseif ($action == 'from_tax') { + $return_price = $this->computePrice($price, 'with_tax', $product); + } else { + $return_price = $price; + } + + if ($convert != 0) { + $return_price = $prix * Currency::getDefaultCurrency()->getRate(); + } + } + + return new JsonResponse(array('result' => $return_price)); + } + + /** + * Calculate all prices + * + * @return \Symfony\Component\HttpFoundation\JsonResponse + */ + public function loadConvertedPrices() + { + $product_sale_element_id = intval($this->getRequest()->get('product_sale_element_id', 0)); + $currency_id = intval($this->getRequest()->get('currency_id', 0)); + + $price_with_tax = $price_without_tax = $sale_price_with_tax = $sale_price_without_tax = 0; + + if (null !== $pse = ProductSaleElementsQuery::create()->findPk($product_sale_element_id)) { + if ($currency_id > 0 + && + $currency_id != Currency::getDefaultCurrency()->getId() + && + null !== $currency = CurrencyQuery::create()->findPk($currency_id)) { + + // Get the default currency price + $productPrice = ProductPriceQuery::create() + ->filterByCurrency(Currency::getDefaultCurrency()) + ->filterByProductSaleElementsId($product_sale_element_id) + ->findOne() + ; + + // Calculate the converted price + if (null !== $productPrice) { + $price_without_tax = $productPrice->getPrice() * $currency->getRate(); + $sale_price_without_tax = $productPrice->getPromoPrice() * $currency->getRate(); + } + } + + if (null !== $product = $pse->getProduct()) { + $price_with_tax = $this->computePrice($price_without_tax, 'with_tax', $product); + $sale_price_with_tax = $this->computePrice($sale_price_without_tax, 'with_tax', $product); + } + } + + return new JsonResponse(array( + 'price_with_tax' => NumberFormat::getInstance($this->getRequest())->format($price_with_tax, null, '.'), + 'price_without_tax' => NumberFormat::getInstance($this->getRequest())->format($price_without_tax, null, '.'), + 'sale_price_with_tax' => NumberFormat::getInstance($this->getRequest())->format($sale_price_with_tax, null, '.'), + 'sale_price_without_tax' => NumberFormat::getInstance($this->getRequest())->format($sale_price_without_tax, null, '.') + )); + } + + /** + * Calculate taxed/untexted price for a product + * + * @param unknown $price + * @param unknown $price_type + * @param Product $product + * @return Ambigous + */ + protected function computePrice($price, $price_type, Product $product, $convert = false) + { $calc = new Calculator(); - $calc->loadTaxRule( - TaxRuleQuery::create()->findPk($tax_rule), + $calc->load( + $product, Country::getShopLocation() ); - if ($action == 'to_tax') { + if ($price_type == 'without_tax') { $return_price = $calc->getTaxedPrice($price); - } - else if ($action == 'from_tax') { + } elseif ($price_type == 'with_tax') { $return_price = $calc->getUntaxedPrice($price); - } - else { + } else { $return_price = $price; } if ($convert != 0) { $return_price = $prix * Currency::getDefaultCurrency()->getRate(); } - // Format the number using '.', to perform further calculation - $return_price = NumberFormat::getInstance($this->getRequest())->format($return_price, null, '.'); - - return new JsonResponse(array('result' => $return_price)); + return NumberFormat::getInstance($this->getRequest())->format($return_price, null, '.'); } } diff --git a/core/lib/Thelia/Controller/Admin/ProfileController.php b/core/lib/Thelia/Controller/Admin/ProfileController.php index 774570139..9db4e9315 100644 --- a/core/lib/Thelia/Controller/Admin/ProfileController.php +++ b/core/lib/Thelia/Controller/Admin/ProfileController.php @@ -29,7 +29,6 @@ use Thelia\Core\Event\Profile\ProfileEvent; use Thelia\Core\Event\TheliaEvents; use Thelia\Form\ProfileCreationForm; use Thelia\Form\ProfileModificationForm; -use Thelia\Form\ProfileProfileListUpdateForm; use Thelia\Form\ProfileUpdateModuleAccessForm; use Thelia\Form\ProfileUpdateResourceAccessForm; use Thelia\Model\ProfileQuery; @@ -201,8 +200,8 @@ class ProfileController extends AbstractCrudController /** * Put in this method post object creation processing if required. * - * @param ProfileEvent $createEvent the create event - * @return Response a response, or null to continue normal processing + * @param ProfileEvent $createEvent the create event + * @return Response a response, or null to continue normal processing */ protected function performAdditionalCreateAction($createEvent) { @@ -263,8 +262,8 @@ class ProfileController extends AbstractCrudController protected function getResourceAccess($formData) { $requirements = array(); - foreach($formData as $data => $value) { - if(!strstr($data, ':')) { + foreach ($formData as $data => $value) { + if (!strstr($data, ':')) { continue; } @@ -272,7 +271,7 @@ class ProfileController extends AbstractCrudController $prefix = array_shift ( $explosion ); - if($prefix != ProfileUpdateResourceAccessForm::RESOURCE_ACCESS_FIELD_PREFIX) { + if ($prefix != ProfileUpdateResourceAccessForm::RESOURCE_ACCESS_FIELD_PREFIX) { continue; } @@ -285,8 +284,8 @@ class ProfileController extends AbstractCrudController protected function getModuleAccess($formData) { $requirements = array(); - foreach($formData as $data => $value) { - if(!strstr($data, ':')) { + foreach ($formData as $data => $value) { + if (!strstr($data, ':')) { continue; } @@ -294,7 +293,7 @@ class ProfileController extends AbstractCrudController $prefix = array_shift ( $explosion ); - if($prefix != ProfileUpdateModuleAccessForm::MODULE_ACCESS_FIELD_PREFIX) { + if ($prefix != ProfileUpdateModuleAccessForm::MODULE_ACCESS_FIELD_PREFIX) { continue; } @@ -401,4 +400,4 @@ class ProfileController extends AbstractCrudController // At this point, the form has errors, and should be redisplayed. return $this->renderEditionTemplate(); } -} \ No newline at end of file +} diff --git a/core/lib/Thelia/Controller/Admin/TaxController.php b/core/lib/Thelia/Controller/Admin/TaxController.php index ec30dfdfa..96b6a4d5b 100644 --- a/core/lib/Thelia/Controller/Admin/TaxController.php +++ b/core/lib/Thelia/Controller/Admin/TaxController.php @@ -28,7 +28,6 @@ use Thelia\Core\Event\Tax\TaxEvent; use Thelia\Core\Event\TheliaEvents; use Thelia\Form\TaxCreationForm; use Thelia\Form\TaxModificationForm; -use Thelia\Form\TaxTaxListUpdateForm; use Thelia\Model\TaxQuery; class TaxController extends AbstractCrudController @@ -40,10 +39,7 @@ class TaxController extends AbstractCrudController 'manual', 'order', - AdminResources::TAX_VIEW, - AdminResources::TAX_CREATE, - AdminResources::TAX_UPDATE, - AdminResources::TAX_DELETE, + AdminResources::TAX, TheliaEvents::TAX_CREATE, TheliaEvents::TAX_UPDATE, @@ -180,7 +176,7 @@ class TaxController extends AbstractCrudController /** * Put in this method post object creation processing if required. * - * @param TaxEvent $createEvent the create event + * @param TaxEvent $createEvent the create event * @return Response a response, or null to continue normal processing */ protected function performAdditionalCreateAction($createEvent) @@ -203,20 +199,19 @@ class TaxController extends AbstractCrudController { $type = $formData['type']; - } protected function getRequirements($type, $formData) { $requirements = array(); - foreach($formData as $data => $value) { - if(!strstr($data, ':')) { + foreach ($formData as $data => $value) { + if (!strstr($data, ':')) { continue; } $couple = explode(':', $data); - if(count($couple) != 2 || $couple[0] != $type) { + if (count($couple) != 2 || $couple[0] != $type) { continue; } @@ -225,4 +220,4 @@ class TaxController extends AbstractCrudController return $requirements; } -} \ No newline at end of file +} diff --git a/core/lib/Thelia/Controller/Admin/TestController.php b/core/lib/Thelia/Controller/Admin/TestController.php deleted file mode 100644 index 5fbdb58e8..000000000 --- a/core/lib/Thelia/Controller/Admin/TestController.php +++ /dev/null @@ -1,93 +0,0 @@ -. */ -/* */ -/*************************************************************************************/ - -namespace Thelia\Controller\Admin; - -use Thelia\Form\TestForm; -/** - * Manages variables - * - * @author Franck Allimant - */ -class TestController extends BaseAdminController -{ - /** - * Load a object for modification, and display the edit template. - * - * @return Symfony\Component\HttpFoundation\Response the response - */ - public function updateAction() - { - // Prepare the data that will hydrate the form - $data = array( - 'title' => "test title", - 'test' => array('a', 'b', 'toto' => 'c') - ); - - // Setup the object form - $changeForm = new TestForm($this->getRequest(), "form", $data); - - // Pass it to the parser - $this->getParserContext()->addForm($changeForm); - - return $this->render('test-form'); - } - - /** - * Save changes on a modified object, and either go back to the object list, or stay on the edition page. - * - * @return Symfony\Component\HttpFoundation\Response the response - */ - public function processUpdateAction() - { - $error_msg = false; - - // Create the form from the request - $changeForm = new TestForm($this->getRequest()); - - try { - - // Check the form against constraints violations - $form = $this->validateForm($changeForm, "POST"); - - // Get the form field values - $data = $form->getData(); - - echo "data="; - - var_dump($data); - } - catch (FormValidationException $ex) { - // Form cannot be validated - $error_msg = $this->createStandardFormValidationErrorMessage($ex); - } - catch (\Exception $ex) { - // Any other error - $error_msg = $ex->getMessage(); - } - - echo "Error = $error_msg"; - - exit; - } -} \ No newline at end of file diff --git a/core/lib/Thelia/Controller/BaseController.php b/core/lib/Thelia/Controller/BaseController.php index 066958025..4bfc3c65f 100755 --- a/core/lib/Thelia/Controller/BaseController.php +++ b/core/lib/Thelia/Controller/BaseController.php @@ -57,7 +57,7 @@ class BaseController extends ContainerAware /** * Return an empty response (after an ajax request, for example) - * @param int $status + * @param int $status * @return \Symfony\Component\HttpFoundation\Response */ protected function nullResponse($status = 200) @@ -196,15 +196,13 @@ class BaseController extends ContainerAware $errorMessage = null; if ($form->get("error_message")->getData() != null) { $errorMessage = $form->get("error_message")->getData(); - } - else { + } else { $errorMessage = sprintf("Missing or invalid data: %s", $this->getErrorMessages($form)); } throw new FormValidationException($errorMessage); } - } - else { + } else { throw new FormValidationException(sprintf("Wrong form method, %s expected.", $expectedMethod)); } } @@ -229,8 +227,7 @@ class BaseController extends ContainerAware { if ($form != null) { $url = $form->getSuccessUrl(); - } - else { + } else { $url = $this->getRequest()->get("success_url"); } diff --git a/core/lib/Thelia/Controller/Front/CartController.php b/core/lib/Thelia/Controller/Front/CartController.php index 5ba8fed48..a2b92508c 100755 --- a/core/lib/Thelia/Controller/Front/CartController.php +++ b/core/lib/Thelia/Controller/Front/CartController.php @@ -67,7 +67,6 @@ class CartController extends BaseFrontController $request->attributes->set('_view', "includes/mini-cart"); } - if ($message) { $cartAdd->setErrorMessage($message); $this->getParserContext()->addForm($cartAdd); diff --git a/core/lib/Thelia/Controller/Front/ContactController.php b/core/lib/Thelia/Controller/Front/ContactController.php index da8c7efc2..7fa965921 100644 --- a/core/lib/Thelia/Controller/Front/ContactController.php +++ b/core/lib/Thelia/Controller/Front/ContactController.php @@ -26,7 +26,6 @@ use Thelia\Form\ContactForm; use Thelia\Form\Exception\FormValidationException; use Thelia\Model\ConfigQuery; - /** * Class ContactController * @package Thelia\Controller\Front @@ -53,7 +52,7 @@ class ContactController extends BaseFrontController $this->getMailer()->send($message); - } catch(FormValidationException $e) { + } catch (FormValidationException $e) { $error_message = $e->getMessage(); } @@ -70,4 +69,4 @@ class ContactController extends BaseFrontController $this->redirectToRoute('contact.success'); } } -} \ No newline at end of file +} diff --git a/core/lib/Thelia/Controller/Front/CouponController.php b/core/lib/Thelia/Controller/Front/CouponController.php index dd0e6d722..e74c14f31 100755 --- a/core/lib/Thelia/Controller/Front/CouponController.php +++ b/core/lib/Thelia/Controller/Front/CouponController.php @@ -24,21 +24,11 @@ namespace Thelia\Controller\Front; use Propel\Runtime\Exception\PropelException; use Thelia\Core\Event\Coupon\CouponConsumeEvent; -use Thelia\Exception\TheliaProcessException; use Thelia\Form\CouponCode; use Thelia\Form\Exception\FormValidationException; -use Thelia\Core\Event\Order\OrderEvent; use Thelia\Core\Event\TheliaEvents; -use Symfony\Component\HttpFoundation\Request; -use Thelia\Form\OrderDelivery; -use Thelia\Form\OrderPayment; use Thelia\Log\Tlog; -use Thelia\Model\AddressQuery; -use Thelia\Model\AreaDeliveryModuleQuery; -use Thelia\Model\Base\OrderQuery; -use Thelia\Model\ModuleQuery; use Thelia\Model\Order; -use Thelia\Tools\URL; /** * Class CouponController diff --git a/core/lib/Thelia/Controller/Front/CustomerController.php b/core/lib/Thelia/Controller/Front/CustomerController.php index 23f2e0f30..f9ebde9e6 100755 --- a/core/lib/Thelia/Controller/Front/CustomerController.php +++ b/core/lib/Thelia/Controller/Front/CustomerController.php @@ -51,7 +51,6 @@ class CustomerController extends BaseFrontController { use \Thelia\Cart\CartTrait; - public function newPasswordAction() { if (! $this->getSecurityContext()->hasCustomerUser()) { @@ -156,7 +155,6 @@ class CustomerController extends BaseFrontController $this->getParserContext()->addForm($customerProfilUpdateForm); } - public function updatePasswordAction() { if ($this->getSecurityContext()->hasCustomerUser()) { @@ -220,14 +218,14 @@ class CustomerController extends BaseFrontController $nlEvent->setFirstname($updatedCustomer->getFirstname()); $nlEvent->setLastname($updatedCustomer->getLastname()); - if(null !== $newsletter = NewsletterQuery::create()->findOneByEmail($newsletterOldEmail)) { + if (null !== $newsletter = NewsletterQuery::create()->findOneByEmail($newsletterOldEmail)) { $nlEvent->setId($newsletter->getId()); $this->dispatch(TheliaEvents::NEWSLETTER_UPDATE, $nlEvent); } else { $this->dispatch(TheliaEvents::NEWSLETTER_SUBSCRIBE, $nlEvent); } } else { - if(null !== $newsletter = NewsletterQuery::create()->findOneByEmail($newsletterOldEmail)) { + if (null !== $newsletter = NewsletterQuery::create()->findOneByEmail($newsletterOldEmail)) { $nlEvent = new NewsletterEvent($updatedCustomer->getEmail(), $this->getRequest()->getSession()->getLang()->getLocale()); $nlEvent->setId($newsletter->getId()); $this->dispatch(TheliaEvents::NEWSLETTER_UNSUBSCRIBE, $nlEvent); diff --git a/core/lib/Thelia/Controller/Front/Mail.php b/core/lib/Thelia/Controller/Front/Mail.php index dfaf2d4fa..f25024f99 100644 --- a/core/lib/Thelia/Controller/Front/Mail.php +++ b/core/lib/Thelia/Controller/Front/Mail.php @@ -23,7 +23,6 @@ namespace Thelia\Controller\Front; - /** * Class Mail * @package Thelia\Controller\Front @@ -46,4 +45,4 @@ class Mail extends BaseFrontController exit; } -} \ No newline at end of file +} diff --git a/core/lib/Thelia/Controller/Front/NewsletterController.php b/core/lib/Thelia/Controller/Front/NewsletterController.php index 0df57cd61..72c3b0878 100644 --- a/core/lib/Thelia/Controller/Front/NewsletterController.php +++ b/core/lib/Thelia/Controller/Front/NewsletterController.php @@ -27,7 +27,6 @@ use Thelia\Core\Event\Newsletter\NewsletterEvent; use Thelia\Core\Event\TheliaEvents; use Thelia\Form\NewsletterForm; - /** * Class NewsletterController * @package Thelia\Controller\Front @@ -50,15 +49,14 @@ class NewsletterController extends BaseFrontController $this->getRequest()->getSession()->getLang()->getLocale() ); - if (null !== $customer = $this->getSecurityContext()->getCustomerUser()) - { + if (null !== $customer = $this->getSecurityContext()->getCustomerUser()) { $event->setFirstname($customer->getFirstname()); $event->setLastname($customer->getLastname()); } $this->dispatch(TheliaEvents::NEWSLETTER_SUBSCRIBE, $event); - } catch(\Exception $e) { + } catch (\Exception $e) { $error_message = $e->getMessage(); } @@ -90,4 +88,4 @@ class NewsletterController extends BaseFrontController } } -} \ No newline at end of file +} diff --git a/core/lib/Thelia/Core/Event/Lang/LangCreateEvent.php b/core/lib/Thelia/Core/Event/Lang/LangCreateEvent.php index 43279b093..3e7c667dd 100644 --- a/core/lib/Thelia/Core/Event/Lang/LangCreateEvent.php +++ b/core/lib/Thelia/Core/Event/Lang/LangCreateEvent.php @@ -23,7 +23,6 @@ namespace Thelia\Core\Event\Lang; - /** * Class LangCreateEvent * @package Thelia\Core\Event\Lang @@ -137,5 +136,4 @@ class LangCreateEvent extends LangEvent return $this->title; } - -} \ No newline at end of file +} diff --git a/core/lib/Thelia/Core/Event/Lang/LangDefaultBehaviorEvent.php b/core/lib/Thelia/Core/Event/Lang/LangDefaultBehaviorEvent.php index 4c3e857e3..fff119e96 100644 --- a/core/lib/Thelia/Core/Event/Lang/LangDefaultBehaviorEvent.php +++ b/core/lib/Thelia/Core/Event/Lang/LangDefaultBehaviorEvent.php @@ -24,7 +24,6 @@ namespace Thelia\Core\Event\Lang; use Thelia\Core\Event\ActionEvent; - /** * Class LangDefaultBehaviorEvent * @package Thelia\Core\Event\Lang @@ -37,7 +36,7 @@ class LangDefaultBehaviorEvent extends ActionEvent */ protected $defaultBehavior; - function __construct($defaultBehavior) + public function __construct($defaultBehavior) { $this->defaultBehavior = $defaultBehavior; } @@ -58,7 +57,4 @@ class LangDefaultBehaviorEvent extends ActionEvent return $this->defaultBehavior; } - - - -} \ No newline at end of file +} diff --git a/core/lib/Thelia/Core/Event/Lang/LangDeleteEvent.php b/core/lib/Thelia/Core/Event/Lang/LangDeleteEvent.php index eebbe27e4..25190f857 100644 --- a/core/lib/Thelia/Core/Event/Lang/LangDeleteEvent.php +++ b/core/lib/Thelia/Core/Event/Lang/LangDeleteEvent.php @@ -23,7 +23,6 @@ namespace Thelia\Core\Event\Lang; - /** * Class LangDeleteEvent * @package Thelia\Core\Event\Lang @@ -39,7 +38,7 @@ class LangDeleteEvent extends LangEvent /** * @param int $lang_id */ - function __construct($lang_id) + public function __construct($lang_id) { $this->lang_id = $lang_id; } @@ -64,4 +63,4 @@ class LangDeleteEvent extends LangEvent return $this->lang_id; } -} \ No newline at end of file +} diff --git a/core/lib/Thelia/Core/Event/Lang/LangEvent.php b/core/lib/Thelia/Core/Event/Lang/LangEvent.php index f66b6428a..1cc7da5e6 100644 --- a/core/lib/Thelia/Core/Event/Lang/LangEvent.php +++ b/core/lib/Thelia/Core/Event/Lang/LangEvent.php @@ -25,7 +25,6 @@ namespace Thelia\Core\Event\Lang; use Thelia\Core\Event\ActionEvent; use Thelia\Model\Lang; - /** * Class LangEvent * @package Thelia\Core\Event\Lang @@ -38,7 +37,7 @@ class LangEvent extends ActionEvent */ protected $lang; - function __construct(Lang $lang = null) + public function __construct(Lang $lang = null) { $this->lang = $lang; } @@ -70,7 +69,4 @@ class LangEvent extends ActionEvent return null !== $this->lang; } - - - -} \ No newline at end of file +} diff --git a/core/lib/Thelia/Core/Event/Lang/LangToggleDefaultEvent.php b/core/lib/Thelia/Core/Event/Lang/LangToggleDefaultEvent.php index f31972f01..626396191 100644 --- a/core/lib/Thelia/Core/Event/Lang/LangToggleDefaultEvent.php +++ b/core/lib/Thelia/Core/Event/Lang/LangToggleDefaultEvent.php @@ -23,7 +23,6 @@ namespace Thelia\Core\Event\Lang; - /** * Class LangToggleDefaultEvent * @package Thelia\Core\Event\Lang @@ -39,7 +38,7 @@ class LangToggleDefaultEvent extends LangEvent /** * @param int $lang_id */ - function __construct($lang_id) + public function __construct($lang_id) { $this->lang_id = $lang_id; } @@ -64,6 +63,4 @@ class LangToggleDefaultEvent extends LangEvent return $this->lang_id; } - - -} \ No newline at end of file +} diff --git a/core/lib/Thelia/Core/Event/Lang/LangUpdateEvent.php b/core/lib/Thelia/Core/Event/Lang/LangUpdateEvent.php index f0d4b928d..cb6282395 100644 --- a/core/lib/Thelia/Core/Event/Lang/LangUpdateEvent.php +++ b/core/lib/Thelia/Core/Event/Lang/LangUpdateEvent.php @@ -23,7 +23,6 @@ namespace Thelia\Core\Event\Lang; - /** * Class LangUpdateEvent * @package Thelia\Core\Event\Lang @@ -39,12 +38,11 @@ class LangUpdateEvent extends LangCreateEvent /** * @param int $id */ - function __construct($id) + public function __construct($id) { $this->id = $id; } - /** * @param int $id * @@ -65,5 +63,4 @@ class LangUpdateEvent extends LangCreateEvent return $this->id; } - -} \ No newline at end of file +} diff --git a/core/lib/Thelia/Core/Event/Module/ModuleDeleteEvent.php b/core/lib/Thelia/Core/Event/Module/ModuleDeleteEvent.php index 5622e3931..a2950dffb 100644 --- a/core/lib/Thelia/Core/Event/Module/ModuleDeleteEvent.php +++ b/core/lib/Thelia/Core/Event/Module/ModuleDeleteEvent.php @@ -23,7 +23,6 @@ namespace Thelia\Core\Event\Module; - /** * Class ModuleDeleteEvent * @package Thelia\Core\Event\Module @@ -36,7 +35,7 @@ class ModuleDeleteEvent extends ModuleEvent */ protected $module_id; - function __construct($module_id) + public function __construct($module_id) { $this->module_id = $module_id; } @@ -57,5 +56,4 @@ class ModuleDeleteEvent extends ModuleEvent return $this->module_id; } - -} \ No newline at end of file +} diff --git a/core/lib/Thelia/Core/Event/Newsletter/NewsletterEvent.php b/core/lib/Thelia/Core/Event/Newsletter/NewsletterEvent.php index 85948a621..1dbd74c4b 100644 --- a/core/lib/Thelia/Core/Event/Newsletter/NewsletterEvent.php +++ b/core/lib/Thelia/Core/Event/Newsletter/NewsletterEvent.php @@ -24,7 +24,6 @@ namespace Thelia\Core\Event\Newsletter; use Thelia\Core\Event\ActionEvent; - /** * Class NewsletterEvent * @package Thelia\Core\Event\Newsletter @@ -57,7 +56,7 @@ class NewsletterEvent extends ActionEvent */ protected $locale; - function __construct($email, $locale) + public function __construct($email, $locale) { $this->email = $email; $this->locale = $locale; @@ -159,8 +158,4 @@ class NewsletterEvent extends ActionEvent return $this->id; } - - - - -} \ No newline at end of file +} diff --git a/core/lib/Thelia/Core/Event/ProductSaleElement/ProductSaleElementCreateEvent.php b/core/lib/Thelia/Core/Event/ProductSaleElement/ProductSaleElementCreateEvent.php index 721342bd8..bbb5d07e7 100644 --- a/core/lib/Thelia/Core/Event/ProductSaleElement/ProductSaleElementCreateEvent.php +++ b/core/lib/Thelia/Core/Event/ProductSaleElement/ProductSaleElementCreateEvent.php @@ -24,7 +24,6 @@ namespace Thelia\Core\Event\ProductSaleElement; use Thelia\Model\Product; -use Thelia\Core\Event\Product\ProductEvent; class ProductSaleElementCreateEvent extends ProductSaleElementEvent { @@ -65,15 +64,16 @@ class ProductSaleElementCreateEvent extends ProductSaleElementEvent return $this; } - public function getProduct() { + public function getProduct() + { return $this->product; } - public function setProduct($product) { + public function setProduct($product) + { $this->product = $product; return $this; } - } diff --git a/core/lib/Thelia/Core/Event/ProductSaleElement/ProductSaleElementDeleteEvent.php b/core/lib/Thelia/Core/Event/ProductSaleElement/ProductSaleElementDeleteEvent.php index 291d59ac9..811b02fca 100644 --- a/core/lib/Thelia/Core/Event/ProductSaleElement/ProductSaleElementDeleteEvent.php +++ b/core/lib/Thelia/Core/Event/ProductSaleElement/ProductSaleElementDeleteEvent.php @@ -23,7 +23,6 @@ namespace Thelia\Core\Event\ProductSaleElement; use Thelia\Model\Product; -use Thelia\Core\Event\Product\ProductEvent; class ProductSaleElementDeleteEvent extends ProductSaleElementEvent { @@ -58,6 +57,7 @@ class ProductSaleElementDeleteEvent extends ProductSaleElementEvent public function setCurrencyId($currency_id) { $this->currency_id = $currency_id; + return $this; } diff --git a/core/lib/Thelia/Core/Event/ProductSaleElement/ProductSaleElementUpdateEvent.php b/core/lib/Thelia/Core/Event/ProductSaleElement/ProductSaleElementUpdateEvent.php index a3eed8a2a..5be7156dc 100644 --- a/core/lib/Thelia/Core/Event/ProductSaleElement/ProductSaleElementUpdateEvent.php +++ b/core/lib/Thelia/Core/Event/ProductSaleElement/ProductSaleElementUpdateEvent.php @@ -22,9 +22,7 @@ /*************************************************************************************/ namespace Thelia\Core\Event\ProductSaleElement; -use Thelia\Core\Event\Product\ProductCreateEvent; use Thelia\Model\Product; -use Thelia\Core\Event\Product\ProductEvent; class ProductSaleElementUpdateEvent extends ProductSaleElementEvent { @@ -41,7 +39,8 @@ class ProductSaleElementUpdateEvent extends ProductSaleElementEvent protected $isnew; protected $isdefault; protected $ean_code; - protected $taxrule; + protected $tax_rule_id; + protected $from_default_currency; public function __construct(Product $product, $product_sale_element_id) { @@ -196,14 +195,26 @@ class ProductSaleElementUpdateEvent extends ProductSaleElementEvent return $this; } - public function getTaxrule() + public function getTaxRuleId() { - return $this->taxrule; + return $this->tax_rule_id; } - public function setTaxrule($taxrule) + public function setTaxRuleId($tax_rule_id) { - $this->taxrule = $taxrule; + $this->tax_rule_id = $tax_rule_id; + + return $this; + } + + public function getFromDefaultCurrency() + { + return $this->from_default_currency; + } + + public function setFromDefaultCurrency($from_default_currency) + { + $this->from_default_currency = $from_default_currency; return $this; } diff --git a/core/lib/Thelia/Core/Event/TheliaEvents.php b/core/lib/Thelia/Core/Event/TheliaEvents.php index e6e675c83..5bb6028a9 100755 --- a/core/lib/Thelia/Core/Event/TheliaEvents.php +++ b/core/lib/Thelia/Core/Event/TheliaEvents.php @@ -552,7 +552,6 @@ final class TheliaEvents const TAX_UPDATE = "action.updateTax"; const TAX_DELETE = "action.deleteTax"; - // -- Profile management --------------------------------------------- const PROFILE_CREATE = "action.createProfile"; diff --git a/core/lib/Thelia/Core/EventListener/ViewListener.php b/core/lib/Thelia/Core/EventListener/ViewListener.php index aefc0cf90..db036f111 100755 --- a/core/lib/Thelia/Core/EventListener/ViewListener.php +++ b/core/lib/Thelia/Core/EventListener/ViewListener.php @@ -84,13 +84,13 @@ class ViewListener implements EventSubscriberInterface $response = new Response($content, $parser->getStatus() ?: 200); } - $response->setCache(array( +/* $response->setCache(array( 'last_modified' => new \DateTime(), 'max_age' => 600, 's_maxage' => 600, 'private' => false, 'public' => true, - )); + ));*/ $event->setResponse($response); } catch (ResourceNotFoundException $e) { diff --git a/core/lib/Thelia/Core/Form/Type/TheliaType.php b/core/lib/Thelia/Core/Form/Type/TheliaType.php index 550760098..eaad895be 100644 --- a/core/lib/Thelia/Core/Form/Type/TheliaType.php +++ b/core/lib/Thelia/Core/Form/Type/TheliaType.php @@ -46,4 +46,4 @@ class TheliaType extends AbstractType { return 'thelia_type'; } -} \ No newline at end of file +} diff --git a/core/lib/Thelia/Core/Security/AccessManager.php b/core/lib/Thelia/Core/Security/AccessManager.php index 8db6c206f..07fc5bcae 100644 --- a/core/lib/Thelia/Core/Security/AccessManager.php +++ b/core/lib/Thelia/Core/Security/AccessManager.php @@ -23,13 +23,6 @@ namespace Thelia\Core\Security; -use Propel\Runtime\ActiveQuery\Criteria; -use Thelia\Core\Security\Resource\AdminResources; -use Thelia\Core\Security\User\UserInterface; -use Thelia\Core\HttpFoundation\Request; -use Thelia\Model\ProfileQuery; -use Thelia\Model\ProfileResourceQuery; - /** * A simple security manager, in charge of checking user * @@ -49,7 +42,7 @@ class AccessManager self::DELETE => false, ); - static protected $accessPows = array( + protected static $accessPows = array( self::VIEW => 3, self::CREATE => 2, self::UPDATE => 1, @@ -67,7 +60,7 @@ class AccessManager public function can($type) { - if(!array_key_exists($type, $this->accessGranted)) { + if (!array_key_exists($type, $this->accessGranted)) { return false; } @@ -75,7 +68,7 @@ class AccessManager } - static public function getMaxAccessValue() + public static function getMaxAccessValue() { return pow(2, current(array_slice( self::$accessPows, -1, 1, true ))) - 1; } @@ -83,8 +76,8 @@ class AccessManager public function build($accesses) { $this->accessValue = 0; - foreach($accesses as $access) { - if(array_key_exists($access, self::$accessPows)) { + foreach ($accesses as $access) { + if (array_key_exists($access, self::$accessPows)) { $this->accessValue += pow(2, self::$accessPows[$access]); } } @@ -95,9 +88,9 @@ class AccessManager protected function fillGrantedAccess() { $accessValue = $this->accessValue; - foreach(self::$accessPows as $type => $value) { + foreach (self::$accessPows as $type => $value) { $pow = pow(2, $value); - if($accessValue >= $pow) { + if ($accessValue >= $pow) { $accessValue -= $pow; $this->accessGranted[$type] = true; } else { @@ -106,7 +99,6 @@ class AccessManager } } - public function getAccessValue() { return $this->accessValue; diff --git a/core/lib/Thelia/Core/Security/Exception/RessourceException.php b/core/lib/Thelia/Core/Security/Exception/RessourceException.php index 27343bd16..c19bcf451 100644 --- a/core/lib/Thelia/Core/Security/Exception/RessourceException.php +++ b/core/lib/Thelia/Core/Security/Exception/RessourceException.php @@ -23,7 +23,7 @@ namespace Thelia\Core\Security\Exception; -class ResourceException extends \RuntimeException +class RessourceException extends \RuntimeException { const UNKNOWN_EXCEPTION = 0; diff --git a/core/lib/Thelia/Core/Security/Resource/AdminResources.php b/core/lib/Thelia/Core/Security/Resource/AdminResources.php index d935c64ab..6efcf89c2 100644 --- a/core/lib/Thelia/Core/Security/Resource/AdminResources.php +++ b/core/lib/Thelia/Core/Security/Resource/AdminResources.php @@ -33,17 +33,17 @@ use Thelia\Core\Security\Exception\ResourceException; */ final class AdminResources { - static private $selfReflection = null; + private static $selfReflection = null; - static public function retrieve($name) + public static function retrieve($name) { $constantName = strtoupper($name); - if(null === self::$selfReflection) { + if (null === self::$selfReflection) { self::$selfReflection = new \ReflectionClass(__CLASS__); } - if(self::$selfReflection->hasConstant($constantName)) { + if (self::$selfReflection->hasConstant($constantName)) { return self::$selfReflection->getConstant($constantName); } else { throw new ResourceException(sprintf('Resource `%s` not found', $constantName), ResourceException::RESOURCE_NOT_FOUND); diff --git a/core/lib/Thelia/Core/Security/SecurityContext.php b/core/lib/Thelia/Core/Security/SecurityContext.php index 087df8810..128feb516 100755 --- a/core/lib/Thelia/Core/Security/SecurityContext.php +++ b/core/lib/Thelia/Core/Security/SecurityContext.php @@ -23,12 +23,9 @@ namespace Thelia\Core\Security; -use Propel\Runtime\ActiveQuery\Criteria; use Thelia\Core\Security\Resource\AdminResources; use Thelia\Core\Security\User\UserInterface; use Thelia\Core\HttpFoundation\Request; -use Thelia\Model\ProfileQuery; -use Thelia\Model\ProfileResourceQuery; /** * A simple security manager, in charge of checking user @@ -147,29 +144,29 @@ class SecurityContext return true; } - if( !method_exists($user, 'getPermissions') ) { + if ( !method_exists($user, 'getPermissions') ) { return false; } $userPermissions = $user->getPermissions(); - if($userPermissions === AdminResources::SUPERADMINISTRATOR) { + if ($userPermissions === AdminResources::SUPERADMINISTRATOR) { return true; } - foreach($resources as $resource) { - if($resource === '') { + foreach ($resources as $resource) { + if ($resource === '') { continue; } $resource = strtolower($resource); - if(!array_key_exists($resource, $userPermissions)) { + if (!array_key_exists($resource, $userPermissions)) { return false; } - foreach($accesses as $access) { - if(!$userPermissions[$resource]->can($access)) { + foreach ($accesses as $access) { + if (!$userPermissions[$resource]->can($access)) { return false; } } diff --git a/core/lib/Thelia/Core/Template/Element/BaseLoop.php b/core/lib/Thelia/Core/Template/Element/BaseLoop.php index 7e803c43a..6b6f44146 100755 --- a/core/lib/Thelia/Core/Template/Element/BaseLoop.php +++ b/core/lib/Thelia/Core/Template/Element/BaseLoop.php @@ -23,12 +23,17 @@ namespace Thelia\Core\Template\Element; +use Propel\Runtime\ActiveQuery\Criteria; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Thelia\Core\Template\Loop\Argument\Argument; use Propel\Runtime\ActiveQuery\ModelCriteria; use Thelia\Core\Security\SecurityContext; +use Thelia\Type\AlphaNumStringListType; +use Thelia\Type\EnumListType; +use Thelia\Type\EnumType; +use Thelia\Type\TypeCollection; /** * @@ -84,13 +89,43 @@ abstract class BaseLoop */ protected function getDefaultArgs() { - return array( - Argument::createIntTypeArgument('offset', 0), - Argument::createIntTypeArgument('page'), - Argument::createIntTypeArgument('limit', PHP_INT_MAX), + $defaultArgs = array( Argument::createBooleanTypeArgument('backend_context', false), Argument::createBooleanTypeArgument('force_return', false), ); + + if (true === $this->countable) { + $defaultArgs = array_merge($defaultArgs, array( + Argument::createIntTypeArgument('offset', 0), + Argument::createIntTypeArgument('page'), + Argument::createIntTypeArgument('limit', PHP_INT_MAX), + )); + } + + if ($this instanceof SearchLoopInterface) { + $defaultArgs = array_merge($defaultArgs, array( + Argument::createAnyTypeArgument('search_term'), + new Argument( + 'search_in', + new TypeCollection( + new EnumListType($this->getSearchIn()) + ) + ), + new Argument( + 'search_mode', + new TypeCollection( + new EnumType(array( + SearchLoopInterface::MODE_ANY_WORD, + SearchLoopInterface::MODE_SENTENCE, + SearchLoopInterface::MODE_STRICT_SENTENCE, + )) + ), + SearchLoopInterface::MODE_STRICT_SENTENCE + ) + )); + } + + return $defaultArgs; } /** @@ -205,6 +240,30 @@ abstract class BaseLoop */ protected function search(ModelCriteria $search, &$pagination = null) { + if ($this instanceof SearchLoopInterface) { + $searchTerm = $this->getSearch_term(); + $searchIn = $this->getSearch_in(); + $searchMode = $this->getSearch_mode(); + if (null !== $searchTerm && null !== $searchIn) { + + switch ($searchMode) { + case SearchLoopInterface::MODE_ANY_WORD: + $searchCriteria = Criteria::IN; + $searchTerm = explode(' ', $searchTerm); + break; + case SearchLoopInterface::MODE_SENTENCE: + $searchCriteria = Criteria::LIKE; + $searchTerm = '%' . $searchTerm . '%'; + break; + case SearchLoopInterface::MODE_STRICT_SENTENCE: + $searchCriteria = Criteria::EQUAL; + break; + } + + $this->doSearch($search, $searchTerm, $searchIn, $searchCriteria); + } + } + if ($this->getArgValue('page') !== null) { return $this->searchWithPagination($search, $pagination); } else { diff --git a/core/lib/Thelia/Tests/Coupon/CouponBaseAdapterTest.php b/core/lib/Thelia/Core/Template/Element/Exception/SearchLoopException.php similarity index 58% rename from core/lib/Thelia/Tests/Coupon/CouponBaseAdapterTest.php rename to core/lib/Thelia/Core/Template/Element/Exception/SearchLoopException.php index 8e2d0addb..f1ce6657f 100644 --- a/core/lib/Thelia/Tests/Coupon/CouponBaseAdapterTest.php +++ b/core/lib/Thelia/Core/Template/Element/Exception/SearchLoopException.php @@ -1,47 +1,40 @@ . */ -/* */ -/**********************************************************************************/ +/*************************************************************************************/ +/* */ +/* Thelia */ +/* */ +/* Copyright (c) OpenStudio */ +/* email : info@thelia.net */ +/* web : http://www.thelia.net */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation; either version 3 of the License */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program. If not, see . */ +/* */ +/*************************************************************************************/ -namespace Thelia\Coupon; +namespace Thelia\Core\Template\Element\Exception; -/** - * Created by JetBrains PhpStorm. - * Date: 8/19/13 - * Time: 3:24 PM - * - * Unit Test BaseFacade Class - * - * @package Coupon - * @author Guillaume MOREL - * - */ -class CouponBaseAdapterTest extends \PHPUnit_Framework_TestCase +class SearchLoopException extends \RuntimeException { - public function testSomething() - { - // Stop here and mark this test as incomplete. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } + const UNKNOWN_EXCEPTION = 0; + public function __construct($message, $code = null, $arguments = array(), $previous = null) + { + if (is_array($arguments)) { + $this->arguments = $arguments; + } + if ($code === null) { + $code = self::UNKNOWN_EXCEPTION; + } + parent::__construct($message, $code, $previous); + } } diff --git a/core/lib/Thelia/Tests/Coupon/CouponManagerTest.php b/core/lib/Thelia/Core/Template/Element/SearchLoopInterface.php similarity index 59% rename from core/lib/Thelia/Tests/Coupon/CouponManagerTest.php rename to core/lib/Thelia/Core/Template/Element/SearchLoopInterface.php index 751a1ba33..26a154e15 100644 --- a/core/lib/Thelia/Tests/Coupon/CouponManagerTest.php +++ b/core/lib/Thelia/Core/Template/Element/SearchLoopInterface.php @@ -1,48 +1,42 @@ . */ -/* */ -/**********************************************************************************/ - -namespace Thelia\Coupon; - +/*************************************************************************************/ +/* */ +/* Thelia */ +/* */ +/* Copyright (c) OpenStudio */ +/* email : info@thelia.net */ +/* web : http://www.thelia.net */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation; either version 3 of the License */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program. If not, see . */ +/* */ +/*************************************************************************************/ +namespace Thelia\Core\Template\Element; /** - * Created by JetBrains PhpStorm. - * Date: 8/19/13 - * Time: 3:24 PM * - * Unit Test CouponManager Class - * - * @package Coupon - * @author Guillaume MOREL + * @author Etienne Roudeix * */ -class CouponManagerTest extends \PHPUnit_Framework_TestCase +interface SearchLoopInterface { - public function testSomething() - { - // Stop here and mark this test as incomplete. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } + const MODE_ANY_WORD = 'any_word'; + const MODE_SENTENCE = 'sentence'; + const MODE_STRICT_SENTENCE = 'strict_sentence'; + /** + * @return array of available field to search in + */ + public function getSearchIn(); + + public function doSearch(&$search, $searchTerm, $searchIn, $searchCriteria); } diff --git a/core/lib/Thelia/Core/Template/Loop/Admin.php b/core/lib/Thelia/Core/Template/Loop/Admin.php index 378bcaf31..581f6faed 100755 --- a/core/lib/Thelia/Core/Template/Loop/Admin.php +++ b/core/lib/Thelia/Core/Template/Loop/Admin.php @@ -24,7 +24,6 @@ namespace Thelia\Core\Template\Loop; use Propel\Runtime\ActiveQuery\Criteria; -use Thelia\Core\Template\Element\BaseI18nLoop; use Thelia\Core\Template\Element\BaseLoop; use Thelia\Core\Template\Element\LoopResult; use Thelia\Core\Template\Element\LoopResultRow; @@ -34,7 +33,6 @@ use Thelia\Core\Template\Loop\Argument\Argument; use Thelia\Model\AdminQuery; use Thelia\Type; -use Thelia\Type\BooleanOrBothType; /** * diff --git a/core/lib/Thelia/Core/Template/Loop/Cart.php b/core/lib/Thelia/Core/Template/Loop/Cart.php index be39371ad..e54675a29 100755 --- a/core/lib/Thelia/Core/Template/Loop/Cart.php +++ b/core/lib/Thelia/Core/Template/Loop/Cart.php @@ -16,7 +16,6 @@ use Thelia\Core\Template\Loop\Argument\Argument; use Thelia\Core\Template\Loop\Argument\ArgumentCollection; use Thelia\Model\CountryQuery; use Thelia\Type; -use Thelia\Type\TypeCollection; class Cart extends BaseLoop { @@ -90,17 +89,17 @@ class Cart extends BaseLoop $countCartItems = count($cartItems); - if($limit <= 0 || $limit >= $countCartItems){ + if ($limit <= 0 || $limit >= $countCartItems) { $limit = $countCartItems; } $position = $this->getPosition(); - if(isset($position)){ - if($position == "first"){ + if (isset($position)) { + if ($position == "first") { $limit = 1; $cartItems = array($cartItems[0]); - }else if($position == "last"){ + } elseif ($position == "last") { $limit = 1; $cartItems = array(end($cartItems)); } diff --git a/core/lib/Thelia/Core/Template/Loop/Category.php b/core/lib/Thelia/Core/Template/Loop/Category.php index 9c9ddab7d..7de04c739 100755 --- a/core/lib/Thelia/Core/Template/Loop/Category.php +++ b/core/lib/Thelia/Core/Template/Loop/Category.php @@ -128,8 +128,9 @@ class Category extends BaseI18nLoop $search->filterById($exclude, Criteria::NOT_IN); } - if ($this->getVisible() != BooleanOrBothType::ANY) - $search->filterByVisible($this->getVisible() ? 1 : 0); + $visible = $this->getVisible(); + + if ($visible !== BooleanOrBothType::ANY) $search->filterByVisible($visible ? 1 : 0); $product = $this->getProduct(); diff --git a/core/lib/Thelia/Core/Template/Loop/Content.php b/core/lib/Thelia/Core/Template/Loop/Content.php index 696d8c6cd..3770d700d 100755 --- a/core/lib/Thelia/Core/Template/Loop/Content.php +++ b/core/lib/Thelia/Core/Template/Loop/Content.php @@ -33,7 +33,6 @@ use Thelia\Core\Template\Loop\Argument\Argument; use Thelia\Model\FolderQuery; use Thelia\Model\Map\ContentTableMap; -use Thelia\Model\ContentFolderQuery; use Thelia\Model\ContentQuery; use Thelia\Type\TypeCollection; use Thelia\Type; @@ -152,7 +151,8 @@ class Content extends BaseI18nLoop $visible = $this->getVisible(); - if ($visible != BooleanOrBothType::ANY) $search->filterByVisible($visible); + if ($visible !== BooleanOrBothType::ANY) $search->filterByVisible($visible ? 1 : 0); + $orders = $this->getOrder(); diff --git a/core/lib/Thelia/Core/Template/Loop/Customer.php b/core/lib/Thelia/Core/Template/Loop/Customer.php index e811606c0..6c0a022a8 100755 --- a/core/lib/Thelia/Core/Template/Loop/Customer.php +++ b/core/lib/Thelia/Core/Template/Loop/Customer.php @@ -28,6 +28,7 @@ use Thelia\Core\Template\Element\BaseLoop; use Thelia\Core\Template\Element\LoopResult; use Thelia\Core\Template\Element\LoopResultRow; +use Thelia\Core\Template\Element\SearchLoopInterface; use Thelia\Core\Template\Loop\Argument\ArgumentCollection; use Thelia\Core\Template\Loop\Argument\Argument; @@ -44,7 +45,7 @@ use Thelia\Type; * @package Thelia\Core\Template\Loop * @author Etienne Roudeix */ -class Customer extends BaseLoop +class Customer extends BaseLoop implements SearchLoopInterface { public $timestampable = true; @@ -67,6 +68,47 @@ class Customer extends BaseLoop ); } + public function getSearchIn() + { + return array( + "ref", + "firstname", + "lastname", + "email", + ); + } + + /** + * @param CustomerQuery $search + * @param $searchTerm + * @param $searchIn + * @param $searchCriteria + */ + public function doSearch(&$search, $searchTerm, $searchIn, $searchCriteria) + { + + $search->_and(); + foreach ($searchIn as $index => $searchInElement) { + if ($index > 0) { + $search->_or(); + } + switch ($searchInElement) { + case "ref": + $search->filterByRef($searchTerm, $searchCriteria); + break; + case "firstname": + $search->filterByFirstname($searchTerm, $searchCriteria); + break; + case "lastname": + $search->filterByLastname($searchTerm, $searchCriteria); + break; + case "email": + $search->filterByEmail($searchTerm, $searchCriteria); + break; + } + } + } + /** * @param $pagination * diff --git a/core/lib/Thelia/Core/Template/Loop/Folder.php b/core/lib/Thelia/Core/Template/Loop/Folder.php index efc45030f..c59a3e95c 100755 --- a/core/lib/Thelia/Core/Template/Loop/Folder.php +++ b/core/lib/Thelia/Core/Template/Loop/Folder.php @@ -121,7 +121,8 @@ class Folder extends BaseI18nLoop $visible = $this->getVisible(); - if ($visible != BooleanOrBothType::ANY) $search->filterByVisible($visible ? 1 : 0); + if ($visible !== BooleanOrBothType::ANY) $search->filterByVisible($visible ? 1 : 0); + $orders = $this->getOrder(); diff --git a/core/lib/Thelia/Core/Template/Loop/Module.php b/core/lib/Thelia/Core/Template/Loop/Module.php index 3c046f61d..1c07d7d5f 100755 --- a/core/lib/Thelia/Core/Template/Loop/Module.php +++ b/core/lib/Thelia/Core/Template/Loop/Module.php @@ -107,7 +107,7 @@ class Module extends BaseI18nLoop $code = $this->getCode(); - if(null !== $code) { + if (null !== $code) { $search->filterByCode($code, Criteria::IN); } diff --git a/core/lib/Thelia/Core/Template/Loop/Order.php b/core/lib/Thelia/Core/Template/Loop/Order.php index 5b1e97cc1..e10b8a5cb 100755 --- a/core/lib/Thelia/Core/Template/Loop/Order.php +++ b/core/lib/Thelia/Core/Template/Loop/Order.php @@ -28,8 +28,11 @@ use Thelia\Core\Template\Element\BaseLoop; use Thelia\Core\Template\Element\LoopResult; use Thelia\Core\Template\Element\LoopResultRow; +use Thelia\Core\Template\Element\SearchLoopInterface; use Thelia\Core\Template\Loop\Argument\ArgumentCollection; use Thelia\Core\Template\Loop\Argument\Argument; +use Thelia\Model\CustomerQuery; +use Thelia\Model\OrderAddressQuery; use Thelia\Model\OrderQuery; use Thelia\Type\TypeCollection; use Thelia\Type; @@ -38,8 +41,9 @@ use Thelia\Type; * @package Thelia\Core\Template\Loop * * @author Franck Allimant + * @author Etienne Roudeix */ -class Order extends BaseLoop +class Order extends BaseLoop implements SearchLoopInterface { public $countable = true; public $timestampable = true; @@ -74,6 +78,59 @@ class Order extends BaseLoop ); } + public function getSearchIn() + { + return array( + "ref", + "customer_ref", + "customer_firstname", + "customer_lastname", + "customer_email", + ); + } + + /** + * @param OrderQuery $search + * @param $searchTerm + * @param $searchIn + * @param $searchCriteria + */ + public function doSearch(&$search, $searchTerm, $searchIn, $searchCriteria) + { + + $search->_and(); + foreach ($searchIn as $index => $searchInElement) { + if ($index > 0) { + $search->_or(); + } + switch ($searchInElement) { + case "ref": + $search->filterByRef($searchTerm, $searchCriteria); + break; + case "customer_ref": + $search->filterByCustomer( + CustomerQuery::create()->filterByRef($searchTerm, $searchCriteria)->find() + ); + break; + case "customer_firstname": + $search->filterByOrderAddressRelatedByInvoiceOrderAddressId( + OrderAddressQuery::create()->filterByFirstname($searchTerm, $searchCriteria)->find() + ); + break; + case "customer_lastname": + $search->filterByOrderAddressRelatedByInvoiceOrderAddressId( + OrderAddressQuery::create()->filterByLastname($searchTerm, $searchCriteria)->find() + ); + break; + case "customer_email": + $search->filterByCustomer( + CustomerQuery::create()->filterByEmail($searchTerm, $searchCriteria)->find() + ); + break; + } + } + } + /** * @param $pagination * diff --git a/core/lib/Thelia/Core/Template/Loop/Product.php b/core/lib/Thelia/Core/Template/Loop/Product.php index 2d6125a37..5ddc6da10 100755 --- a/core/lib/Thelia/Core/Template/Loop/Product.php +++ b/core/lib/Thelia/Core/Template/Loop/Product.php @@ -29,6 +29,7 @@ use Thelia\Core\Template\Element\BaseI18nLoop; use Thelia\Core\Template\Element\LoopResult; use Thelia\Core\Template\Element\LoopResultRow; +use Thelia\Core\Template\Element\SearchLoopInterface; use Thelia\Core\Template\Loop\Argument\ArgumentCollection; use Thelia\Core\Template\Loop\Argument\Argument; @@ -39,23 +40,19 @@ use Thelia\Model\CurrencyQuery; use Thelia\Model\Map\ProductPriceTableMap; use Thelia\Model\Map\ProductSaleElementsTableMap; use Thelia\Model\Map\ProductTableMap; -use Thelia\Model\ProductCategoryQuery; use Thelia\Model\ProductQuery; -use Thelia\Model\ConfigQuery; use Thelia\Type\TypeCollection; use Thelia\Type; -use Thelia\Type\BooleanOrBothType; /** * * Product loop * - * * Class Product * @package Thelia\Core\Template\Loop * @author Etienne Roudeix */ -class Product extends BaseI18nLoop +class Product extends BaseI18nLoop implements SearchLoopInterface { public $timestampable = true; public $versionable = true; @@ -66,6 +63,7 @@ class Product extends BaseI18nLoop protected function getArgDefinitions() { return new ArgumentCollection( + Argument::createBooleanTypeArgument('complex', false), Argument::createIntListTypeArgument('id'), new Argument( 'ref', @@ -130,6 +128,39 @@ class Product extends BaseI18nLoop ); } + public function getSearchIn() + { + return array( + "ref", + "title", + ); + } + + /** + * @param ProductQuery $search + * @param $searchTerm + * @param $searchIn + * @param $searchCriteria + */ + public function doSearch(&$search, $searchTerm, $searchIn, $searchCriteria) + { + + $search->_and(); + foreach ($searchIn as $index => $searchInElement) { + if ($index > 0) { + $search->_or(); + } + switch ($searchInElement) { + case "ref": + $search->filterByRef($searchTerm, $searchCriteria); + break; + case "title": + $search->where("CASE WHEN NOT ISNULL(`requested_locale_i18n`.ID) THEN `requested_locale_i18n`.`TITLE` ELSE `default_locale_i18n`.`TITLE` END ".$searchCriteria." ?", $searchTerm, \PDO::PARAM_STR); + break; + } + } + } + /** * @param $pagination * @@ -137,6 +168,396 @@ class Product extends BaseI18nLoop * @throws \InvalidArgumentException */ public function exec(&$pagination) + { + $complex = $this->getComplex(); + if (true === $complex) { + return $this->execComplex($pagination); + } + + $currencyId = $this->getCurrency(); + if (null !== $currencyId) { + $currency = CurrencyQuery::create()->findOneById($currencyId); + if (null === $currency) { + throw new \InvalidArgumentException('Cannot found currency id: `' . $currency . '` in product_sale_elements loop'); + } + } else { + $currency = $this->request->getSession()->getCurrency(); + } + + $defaultCurrency = CurrencyQuery::create()->findOneByByDefault(1); + $defaultCurrencySuffix = '_default_currency'; + + $search = ProductQuery::create(); + $search->innerJoinProductSaleElements('pse'); + $search->addJoinCondition('pse', '`pse`.IS_DEFAULT=1'); + + $priceJoin = new Join(); + $priceJoin->addExplicitCondition(ProductSaleElementsTableMap::TABLE_NAME, 'ID', 'pse', ProductPriceTableMap::TABLE_NAME, 'PRODUCT_SALE_ELEMENTS_ID', 'price'); + $priceJoin->setJoinType(Criteria::LEFT_JOIN); + + $search->addJoinObject($priceJoin, 'price_join') + ->addJoinCondition('price_join', '`price`.`currency_id` = ?', $currency->getId(), null, \PDO::PARAM_INT); + + if ($defaultCurrency->getId() != $currency->getId()) { + $priceJoinDefaultCurrency = new Join(); + $priceJoinDefaultCurrency->addExplicitCondition(ProductSaleElementsTableMap::TABLE_NAME, 'ID', 'pse', ProductPriceTableMap::TABLE_NAME, 'PRODUCT_SALE_ELEMENTS_ID', 'price' . $defaultCurrencySuffix); + $priceJoinDefaultCurrency->setJoinType(Criteria::LEFT_JOIN); + + $search->addJoinObject($priceJoinDefaultCurrency, 'price_join' . $defaultCurrencySuffix) + ->addJoinCondition('price_join' . $defaultCurrencySuffix, '`price' . $defaultCurrencySuffix . '`.`currency_id` = ?', $defaultCurrency->getId(), null, \PDO::PARAM_INT); + + /** + * rate value is checked as a float in overloaded getRate method. + */ + $priceToCompareAsSQL = 'CASE WHEN ISNULL(`price`.PRICE) OR `price`.FROM_DEFAULT_CURRENCY = 1 THEN + CASE WHEN `pse`.PROMO=1 THEN `price' . $defaultCurrencySuffix . '`.PROMO_PRICE ELSE `price' . $defaultCurrencySuffix . '`.PRICE END * ' . $currency->getRate() . ' + ELSE + CASE WHEN `pse`.PROMO=1 THEN `price`.PROMO_PRICE ELSE `price`.PRICE END + END'; + + $search->withColumn('ROUND(' . $priceToCompareAsSQL . ', 2)', 'real_price'); + $search->withColumn('CASE WHEN ISNULL(`price`.PRICE) OR `price`.FROM_DEFAULT_CURRENCY = 1 THEN `price' . $defaultCurrencySuffix . '`.PRICE * ' . $currency->getRate() . ' ELSE `price`.PRICE END', 'price'); + $search->withColumn('CASE WHEN ISNULL(`price`.PRICE) OR `price`.FROM_DEFAULT_CURRENCY = 1 THEN `price' . $defaultCurrencySuffix . '`.PROMO_PRICE * ' . $currency->getRate() . ' ELSE `price`.PROMO_PRICE END', 'promo_price'); + } else { + $priceToCompareAsSQL = 'CASE WHEN `pse`.PROMO=1 THEN `price`.PROMO_PRICE ELSE `price`.PRICE END'; + + $search->withColumn('ROUND(' . $priceToCompareAsSQL . ', 2)', 'real_price'); + $search->withColumn('`price`.PRICE', 'price'); + $search->withColumn('`price`.PROMO_PRICE', 'promo_price'); + } + + /* manage translations */ + $locale = $this->configureI18nProcessing($search); + + $id = $this->getId(); + + if (!is_null($id)) { + $search->filterById($id, Criteria::IN); + } + + $ref = $this->getRef(); + + if (!is_null($ref)) { + $search->filterByRef($ref, Criteria::IN); + } + + $title = $this->getTitle(); + + if (!is_null($title)) { + $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); + } + + $category = $this->getCategory(); + $categoryDefault = $this->getCategoryDefault(); + + if (!is_null($category) ||!is_null($categoryDefault)) { + + $categoryIds = array(); + if (!is_array($category)) { + $category = array(); + } + if (!is_array($categoryDefault)) { + $categoryDefault = array(); + } + + $categoryIds = array_merge($categoryIds, $category, $categoryDefault); + $categories =CategoryQuery::create()->filterById($categoryIds, Criteria::IN)->find(); + + $depth = $this->getDepth(); + + if (null !== $depth) { + foreach (CategoryQuery::findAllChild($category, $depth) as $subCategory) { + $categories->prepend($subCategory); + } + } + + $search->filterByCategory( + $categories, + Criteria::IN + ); + } + + $new = $this->getNew(); + + if ($new === true) { + $search->where('`pse`.NEWNESS' . Criteria::EQUAL . '1'); + } elseif ($new === false) { + $search->where('`pse`.NEWNESS' . Criteria::EQUAL . '0'); + } + + $promo = $this->getPromo(); + + if ($promo === true) { + $search->where('`pse`.PROMO' . Criteria::EQUAL . '1'); + } elseif ($promo === false) { + $search->where('`pse`.PROMO' . Criteria::EQUAL . '0'); + } + + $min_stock = $this->getMin_stock(); + + if (null != $min_stock) { + $search->where('`pse`.QUANTITY' . Criteria::GREATER_THAN . '?', $min_stock, \PDO::PARAM_INT); + } + + $min_weight = $this->getMin_weight(); + + if (null != $min_weight) { + $search->where('`pse`.WEIGHT' . Criteria::GREATER_THAN . '?', $min_weight, \PDO::PARAM_STR); + } + + $max_weight = $this->getMax_weight(); + + if (null != $max_weight) { + $search->where('`is_max_weight`.WEIGHT' . Criteria::LESS_THAN . '?', $max_weight, \PDO::PARAM_STR); + } + + $min_price = $this->getMin_price(); + + if (null !== $min_price) { + + if (false === ConfigQuery::useTaxFreeAmounts()) { + // @todo + } + + $search->where('ROUND(' . $priceToCompareAsSQL . ', 2)>=?', $min_price, \PDO::PARAM_STR); + } + + $max_price = $this->getMax_price(); + + if (null !== $max_price) { + if (false === ConfigQuery::useTaxFreeAmounts()) { + // @todo + } + + $search->where('ROUND(' . $priceToCompareAsSQL . ', 2)<=?', $max_price, \PDO::PARAM_STR); + } + + $current = $this->getCurrent(); + + if ($current === true) { + $search->filterById($this->request->get("product_id"), Criteria::EQUAL); + } elseif ($current === false) { + $search->filterById($this->request->get("product_id"), Criteria::NOT_IN); + } + + $current_category = $this->getCurrent_category(); + + if ($current_category === true) { + $search->filterByCategory( + CategoryQuery::create()->filterByProduct( + ProductCategoryQuery::create()->filterByProductId( + $this->request->get("product_id"), + Criteria::EQUAL + )->find(), + Criteria::IN + )->find(), + Criteria::IN + ); + } elseif ($current_category === false) { + $search->filterByCategory( + CategoryQuery::create()->filterByProduct( + ProductCategoryQuery::create()->filterByProductId( + $this->request->get("product_id"), + Criteria::EQUAL + )->find(), + Criteria::IN + )->find(), + Criteria::NOT_IN + ); + } + + $visible = $this->getVisible(); + + if ($visible !== Type\BooleanOrBothType::ANY) $search->filterByVisible($visible ? 1 : 0); + + $exclude = $this->getExclude(); + + if (!is_null($exclude)) { + $search->filterById($exclude, Criteria::NOT_IN); + } + + $exclude_category = $this->getExclude_category(); + + if (!is_null($exclude_category)) { + $search->filterByCategory( + CategoryQuery::create()->filterById($exclude_category, Criteria::IN)->find(), + Criteria::NOT_IN + ); + } + + $feature_availability = $this->getFeature_availability(); + + $this->manageFeatureAv($search, $feature_availability); + + $feature_values = $this->getFeature_values(); + + $this->manageFeatureValue($search, $feature_values); + + $search->groupBy(ProductTableMap::ID); + + $search->withColumn('`pse`.ID', 'pse_id'); + $search->withColumn('`pse`.NEWNESS', 'is_new'); + $search->withColumn('`pse`.PROMO', 'is_promo'); + $search->withColumn('`pse`.QUANTITY', 'quantity'); + $search->withColumn('`pse`.WEIGHT', 'weight'); + $search->withColumn('`pse`.EAN_CODE', 'ean_code'); + + $orders = $this->getOrder(); + + foreach ($orders as $order) { + switch ($order) { + case "id": + $search->orderById(Criteria::ASC); + break; + case "id_reverse": + $search->orderById(Criteria::DESC); + break; + case "alpha": + $search->addAscendingOrderByColumn('i18n_TITLE'); + break; + case "alpha_reverse": + $search->addDescendingOrderByColumn('i18n_TITLE'); + break; + case "min_price": + $search->addAscendingOrderByColumn('real_price'); + break; + case "max_price": + $search->addDescendingOrderByColumn('real_price'); + break; + case "manual": + if(null === $categoryIds || count($categoryIds) != 1) + throw new \InvalidArgumentException('Manual order cannot be set without single category argument'); + $search->orderByPosition(Criteria::ASC); + break; + case "manual_reverse": + if(null === $categoryIds || count($categoryIds) != 1) + throw new \InvalidArgumentException('Manual order cannot be set without single category argument'); + $search->orderByPosition(Criteria::DESC); + break; + case "ref": + $search->orderByRef(Criteria::ASC); + break; + case "promo": + $search->addDescendingOrderByColumn('is_promo'); + break; + case "new": + $search->addDescendingOrderByColumn('is_new'); + break; + case "given_id": + if(null === $id) + throw new \InvalidArgumentException('Given_id order cannot be set without `id` argument'); + foreach ($id as $singleId) { + $givenIdMatched = 'given_id_matched_' . $singleId; + $search->withColumn(ProductTableMap::ID . "='$singleId'", $givenIdMatched); + $search->orderBy($givenIdMatched, Criteria::DESC); + } + break; + case "random": + $search->clearOrderByColumns(); + $search->addAscendingOrderByColumn('RAND()'); + break(2); + } + } + + /* perform search */ + $products = $this->search($search, $pagination); + + $loopResult = new LoopResult($products); + + $taxCountry = CountryQuery::create()->findPk(64); // @TODO : make it magic + + foreach ($products as $product) { + + $loopResultRow = new LoopResultRow($loopResult, $product, $this->versionable, $this->timestampable, $this->countable); + + $price = $product->getVirtualColumn('price'); + try { + $taxedPrice = $product->getTaxedPrice( + $taxCountry, + $price + ); + } catch (TaxEngineException $e) { + $taxedPrice = null; + } + $promoPrice = $product->getVirtualColumn('promo_price'); + try { + $taxedPromoPrice = $product->getTaxedPromoPrice( + $taxCountry, + $promoPrice + ); + } catch (TaxEngineException $e) { + $taxedPromoPrice = null; + } + + // Find previous and next product, in the default category. + $default_category_id = $product->getDefaultCategoryId(); + + $previous = ProductQuery::create() + ->joinProductCategory() + ->where('ProductCategory.category_id = ?', $default_category_id) + ->filterByPosition($product->getPosition(), Criteria::LESS_THAN) + ->orderByPosition(Criteria::DESC) + ->findOne() + ; + + $next = ProductQuery::create() + ->joinProductCategory() + ->where('ProductCategory.category_id = ?', $default_category_id) + ->filterByPosition($product->getPosition(), Criteria::GREATER_THAN) + ->orderByPosition(Criteria::ASC) + ->findOne() + ; + + $loopResultRow + ->set("ID" , $product->getId()) + ->set("REF" , $product->getRef()) + ->set("IS_TRANSLATED" , $product->getVirtualColumn('IS_TRANSLATED')) + ->set("LOCALE" , $locale) + ->set("TITLE" , $product->getVirtualColumn('i18n_TITLE')) + ->set("CHAPO" , $product->getVirtualColumn('i18n_CHAPO')) + ->set("DESCRIPTION" , $product->getVirtualColumn('i18n_DESCRIPTION')) + ->set("POSTSCRIPTUM" , $product->getVirtualColumn('i18n_POSTSCRIPTUM')) + ->set("URL" , $product->getUrl($locale)) + ->set("BEST_PRICE" , $product->getVirtualColumn('is_promo') ? $promoPrice : $price) + ->set("BEST_PRICE_TAX" , $taxedPrice - $product->getVirtualColumn('is_promo') ? $taxedPromoPrice - $promoPrice : $taxedPrice - $price) + ->set("BEST_TAXED_PRICE" , $product->getVirtualColumn('is_promo') ? $taxedPromoPrice : $taxedPrice) + ->set("PRICE" , $price) + ->set("PRICE_TAX" , $taxedPrice - $price) + ->set("TAXED_PRICE" , $taxedPrice) + ->set("PROMO_PRICE" , $promoPrice) + ->set("PROMO_PRICE_TAX" , $taxedPromoPrice - $promoPrice) + ->set("TAXED_PROMO_PRICE" , $taxedPromoPrice) + ->set("PRODUCT_SALE_ELEMENT" , $product->getVirtualColumn('pse_id')) + ->set("WEIGHT" , $product->getVirtualColumn('weight')) + ->set("QUANTITY" , $product->getVirtualColumn('quantity')) + ->set("EAN_CODE" , $product->getVirtualColumn('ean_code')) + ->set("IS_PROMO" , $product->getVirtualColumn('is_promo')) + ->set("IS_NEW" , $product->getVirtualColumn('is_new')) + ->set("POSITION" , $product->getPosition()) + ->set("VISIBLE" , $product->getVisible() ? "1" : "0") + ->set("TEMPLATE" , $product->getTemplateId()) + ->set("HAS_PREVIOUS" , $previous != null ? 1 : 0) + ->set("HAS_NEXT" , $next != null ? 1 : 0) + ->set("PREVIOUS" , $previous != null ? $previous->getId() : -1) + ->set("NEXT" , $next != null ? $next->getId() : -1) + ->set("DEFAULT_CATEGORY" , $default_category_id) + ->set("TAX_RULE_ID" , $product->getTaxRuleId()) + + ; + + $loopResult->addRow($loopResultRow); + } + + return $loopResult; + } + + /** + * @param $pagination + * + * @return \Thelia\Core\Template\Element\LoopResult + * @throws \InvalidArgumentException + */ + public function execComplex(&$pagination) { $currencyId = $this->getCurrency(); if (null !== $currencyId) { @@ -175,7 +596,7 @@ class Product extends BaseI18nLoop $title = $this->getTitle(); - if(!is_null($title)){ + if (!is_null($title)) { $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); } @@ -313,7 +734,7 @@ class Product extends BaseI18nLoop * In propel we trust : $currency->getRate() always returns a float. * Or maybe not : rate value is checked as a float in overloaded getRate method. */ - $MinPriceToCompareAsSQL = 'CASE WHEN ISNULL(CASE WHEN `is_min_price`.PROMO=1 THEN `min_price_data`.PROMO_PRICE ELSE `min_price_data`.PRICE END) THEN + $MinPriceToCompareAsSQL = 'CASE WHEN ISNULL(CASE WHEN `is_min_price`.PROMO=1 THEN `min_price_data`.PROMO_PRICE ELSE `min_price_data`.PRICE END) OR `min_price_data`.FROM_DEFAULT_CURRENCY = 1 THEN CASE WHEN `is_min_price`.PROMO=1 THEN `min_price_data' . $defaultCurrencySuffix . '`.PROMO_PRICE ELSE `min_price_data' . $defaultCurrencySuffix . '`.PRICE END * ' . $currency->getRate() . ' ELSE CASE WHEN `is_min_price`.PROMO=1 THEN `min_price_data`.PROMO_PRICE ELSE `min_price_data`.PRICE END @@ -351,7 +772,7 @@ class Product extends BaseI18nLoop * In propel we trust : $currency->getRate() always returns a float. * Or maybe not : rate value is checked as a float in overloaded getRate method. */ - $MaxPriceToCompareAsSQL = 'CASE WHEN ISNULL(CASE WHEN `is_max_price`.PROMO=1 THEN `max_price_data`.PROMO_PRICE ELSE `max_price_data`.PRICE END) THEN + $MaxPriceToCompareAsSQL = 'CASE WHEN ISNULL(CASE WHEN `is_max_price`.PROMO=1 THEN `max_price_data`.PROMO_PRICE ELSE `max_price_data`.PRICE END) OR `min_price_data`.FROM_DEFAULT_CURRENCY = 1 THEN CASE WHEN `is_max_price`.PROMO=1 THEN `max_price_data' . $defaultCurrencySuffix . '`.PROMO_PRICE ELSE `max_price_data' . $defaultCurrencySuffix . '`.PRICE END * ' . $currency->getRate() . ' ELSE CASE WHEN `is_max_price`.PROMO=1 THEN `max_price_data`.PROMO_PRICE ELSE `max_price_data`.PRICE END @@ -492,59 +913,11 @@ class Product extends BaseI18nLoop $feature_availability = $this->getFeature_availability(); - if (null !== $feature_availability) { - foreach ($feature_availability as $feature => $feature_choice) { - foreach ($feature_choice['values'] as $feature_av) { - $featureAlias = 'fa_' . $feature; - if($feature_av != '*') - $featureAlias .= '_' . $feature_av; - $search->joinFeatureProduct($featureAlias, Criteria::LEFT_JOIN) - ->addJoinCondition($featureAlias, "`$featureAlias`.FEATURE_ID = ?", $feature, null, \PDO::PARAM_INT); - if($feature_av != '*') - $search->addJoinCondition($featureAlias, "`$featureAlias`.FEATURE_AV_ID = ?", $feature_av, null, \PDO::PARAM_INT); - } - - /* format for mysql */ - $sqlWhereString = $feature_choice['expression']; - if ($sqlWhereString == '*') { - $sqlWhereString = 'NOT ISNULL(`fa_' . $feature . '`.ID)'; - } else { - $sqlWhereString = preg_replace('#([0-9]+)#', 'NOT ISNULL(`fa_' . $feature . '_' . '\1`.ID)', $sqlWhereString); - $sqlWhereString = str_replace('&', ' AND ', $sqlWhereString); - $sqlWhereString = str_replace('|', ' OR ', $sqlWhereString); - } - - $search->where("(" . $sqlWhereString . ")"); - } - } + $this->manageFeatureAv($search, $feature_availability); $feature_values = $this->getFeature_values(); - if (null !== $feature_values) { - foreach ($feature_values as $feature => $feature_choice) { - foreach ($feature_choice['values'] as $feature_value) { - $featureAlias = 'fv_' . $feature; - if($feature_value != '*') - $featureAlias .= '_' . $feature_value; - $search->joinFeatureProduct($featureAlias, Criteria::LEFT_JOIN) - ->addJoinCondition($featureAlias, "`$featureAlias`.FEATURE_ID = ?", $feature, null, \PDO::PARAM_INT); - if($feature_value != '*') - $search->addJoinCondition($featureAlias, "`$featureAlias`.BY_DEFAULT = ?", $feature_value, null, \PDO::PARAM_STR); - } - - /* format for mysql */ - $sqlWhereString = $feature_choice['expression']; - if ($sqlWhereString == '*') { - $sqlWhereString = 'NOT ISNULL(`fv_' . $feature . '`.ID)'; - } else { - $sqlWhereString = preg_replace('#([a-zA-Z0-9_\-]+)#', 'NOT ISNULL(`fv_' . $feature . '_' . '\1`.ID)', $sqlWhereString); - $sqlWhereString = str_replace('&', ' AND ', $sqlWhereString); - $sqlWhereString = str_replace('|', ' OR ', $sqlWhereString); - } - - $search->where("(" . $sqlWhereString . ")"); - } - } + $this->manageFeatureValue($search, $feature_values); $search->groupBy(ProductTableMap::ID); @@ -620,7 +993,8 @@ class Product extends BaseI18nLoop try { $taxedPrice = $product->getTaxedPrice( - $taxCountry + $taxCountry, + $product->getRealLowestPrice() ); } catch (TaxEngineException $e) { $taxedPrice = null; @@ -668,12 +1042,71 @@ class Product extends BaseI18nLoop ->set("PREVIOUS" , $previous != null ? $previous->getId() : -1) ->set("NEXT" , $next != null ? $next->getId() : -1) ->set("DEFAULT_CATEGORY" , $default_category_id) + ->set("TAX_RULE_ID" , $product->getTaxRuleId()) - ; + ; $loopResult->addRow($loopResultRow); } return $loopResult; } + + protected function manageFeatureAv(&$search, $feature_availability) + { + if (null !== $feature_availability) { + foreach ($feature_availability as $feature => $feature_choice) { + foreach ($feature_choice['values'] as $feature_av) { + $featureAlias = 'fa_' . $feature; + if($feature_av != '*') + $featureAlias .= '_' . $feature_av; + $search->joinFeatureProduct($featureAlias, Criteria::LEFT_JOIN) + ->addJoinCondition($featureAlias, "`$featureAlias`.FEATURE_ID = ?", $feature, null, \PDO::PARAM_INT); + if($feature_av != '*') + $search->addJoinCondition($featureAlias, "`$featureAlias`.FEATURE_AV_ID = ?", $feature_av, null, \PDO::PARAM_INT); + } + + /* format for mysql */ + $sqlWhereString = $feature_choice['expression']; + if ($sqlWhereString == '*') { + $sqlWhereString = 'NOT ISNULL(`fa_' . $feature . '`.ID)'; + } else { + $sqlWhereString = preg_replace('#([0-9]+)#', 'NOT ISNULL(`fa_' . $feature . '_' . '\1`.ID)', $sqlWhereString); + $sqlWhereString = str_replace('&', ' AND ', $sqlWhereString); + $sqlWhereString = str_replace('|', ' OR ', $sqlWhereString); + } + + $search->where("(" . $sqlWhereString . ")"); + } + } + } + + protected function manageFeatureValue(&$search, $feature_values) + { + if (null !== $feature_values) { + foreach ($feature_values as $feature => $feature_choice) { + foreach ($feature_choice['values'] as $feature_value) { + $featureAlias = 'fv_' . $feature; + if($feature_value != '*') + $featureAlias .= '_' . $feature_value; + $search->joinFeatureProduct($featureAlias, Criteria::LEFT_JOIN) + ->addJoinCondition($featureAlias, "`$featureAlias`.FEATURE_ID = ?", $feature, null, \PDO::PARAM_INT); + if($feature_value != '*') + $search->addJoinCondition($featureAlias, "`$featureAlias`.BY_DEFAULT = ?", $feature_value, null, \PDO::PARAM_STR); + } + + /* format for mysql */ + $sqlWhereString = $feature_choice['expression']; + if ($sqlWhereString == '*') { + $sqlWhereString = 'NOT ISNULL(`fv_' . $feature . '`.ID)'; + } else { + $sqlWhereString = preg_replace('#([a-zA-Z0-9_\-]+)#', 'NOT ISNULL(`fv_' . $feature . '_' . '\1`.ID)', $sqlWhereString); + $sqlWhereString = str_replace('&', ' AND ', $sqlWhereString); + $sqlWhereString = str_replace('|', ' OR ', $sqlWhereString); + } + + $search->where("(" . $sqlWhereString . ")"); + } + } + } } diff --git a/core/lib/Thelia/Core/Template/Loop/ProductSaleElements.php b/core/lib/Thelia/Core/Template/Loop/ProductSaleElements.php index 29d56b149..b48b0359e 100755 --- a/core/lib/Thelia/Core/Template/Loop/ProductSaleElements.php +++ b/core/lib/Thelia/Core/Template/Loop/ProductSaleElements.php @@ -136,8 +136,8 @@ class ProductSaleElements extends BaseLoop /** * rate value is checked as a float in overloaded getRate method. */ - $priceSelectorAsSQL = 'ROUND(CASE WHEN ISNULL(`price`.PRICE) THEN `price_default_currency`.PRICE * ' . $currency->getRate() . ' ELSE `price`.PRICE END, 2)'; - $promoPriceSelectorAsSQL = 'ROUND(CASE WHEN ISNULL(`price`.PRICE) THEN `price_default_currency`.PROMO_PRICE * ' . $currency->getRate() . ' ELSE `price`.PROMO_PRICE END, 2)'; + $priceSelectorAsSQL = 'ROUND(CASE WHEN ISNULL(`price`.PRICE) OR `price`.FROM_DEFAULT_CURRENCY = 1 THEN `price_default_currency`.PRICE * ' . $currency->getRate() . ' ELSE `price`.PRICE END, 2)'; + $promoPriceSelectorAsSQL = 'ROUND(CASE WHEN ISNULL(`price`.PRICE) OR `price`.FROM_DEFAULT_CURRENCY = 1 THEN `price_default_currency`.PROMO_PRICE * ' . $currency->getRate() . ' ELSE `price`.PROMO_PRICE END, 2)'; $search->withColumn($priceSelectorAsSQL, 'price_PRICE') ->withColumn($promoPriceSelectorAsSQL, 'price_PROMO_PRICE') ->withColumn('CASE WHEN ' . ProductSaleElementsTableMap::PROMO . ' = 1 THEN ' . $promoPriceSelectorAsSQL . ' ELSE ' . $priceSelectorAsSQL . ' END', 'price_FINAL_PRICE'); diff --git a/core/lib/Thelia/Core/Template/Loop/Profile.php b/core/lib/Thelia/Core/Template/Loop/Profile.php index 4ac43d25a..bb2e4a7b5 100755 --- a/core/lib/Thelia/Core/Template/Loop/Profile.php +++ b/core/lib/Thelia/Core/Template/Loop/Profile.php @@ -33,7 +33,6 @@ use Thelia\Core\Template\Loop\Argument\Argument; use Thelia\Model\ProfileQuery; use Thelia\Type; -use Thelia\Type\BooleanOrBothType; /** * diff --git a/core/lib/Thelia/Core/Template/Loop/Resource.php b/core/lib/Thelia/Core/Template/Loop/Resource.php index 2b2d90f70..41400dc65 100755 --- a/core/lib/Thelia/Core/Template/Loop/Resource.php +++ b/core/lib/Thelia/Core/Template/Loop/Resource.php @@ -34,7 +34,6 @@ use Thelia\Core\Template\Loop\Argument\Argument; use Thelia\Model\ResourceQuery; use Thelia\Type; -use Thelia\Type\BooleanOrBothType; /** * @@ -87,7 +86,7 @@ class Resource extends BaseI18nLoop $code = $this->getCode(); - if(null !== $code) { + if (null !== $code) { $search->filterByCode($code, Criteria::IN); } diff --git a/core/lib/Thelia/Core/Template/Loop/TaxRuleCountry.php b/core/lib/Thelia/Core/Template/Loop/TaxRuleCountry.php index ee20a3d20..83539fef6 100644 --- a/core/lib/Thelia/Core/Template/Loop/TaxRuleCountry.php +++ b/core/lib/Thelia/Core/Template/Loop/TaxRuleCountry.php @@ -85,10 +85,10 @@ class TaxRuleCountry extends BaseI18nLoop $country = $this->getCountry(); $taxRule = $this->getTax_rule(); - if($ask === 'countries') { + if ($ask === 'countries') { $taxCountForOriginCountry = TaxRuleCountryQuery::create()->filterByCountryId($country)->count(); - if($taxCountForOriginCountry > 0) { + if ($taxCountForOriginCountry > 0) { $search->groupByCountryId(); $originalCountryJoin = new Join(); @@ -127,7 +127,7 @@ class TaxRuleCountry extends BaseI18nLoop $search->addAscendingOrderByColumn('i18n_TITLE'); } - } elseif($ask === 'taxes') { + } elseif ($ask === 'taxes') { $search->filterByCountryId($country); /* manage tax translation */ @@ -151,8 +151,8 @@ class TaxRuleCountry extends BaseI18nLoop $loopResultRow = new LoopResultRow($loopResult, $taxRuleCountry, $this->versionable, $this->timestampable, $this->countable); - if($ask === 'countries') { - if($taxCountForOriginCountry > 0) { + if ($ask === 'countries') { + if ($taxCountForOriginCountry > 0) { $loopResultRow ->set("COUNTRY" , $taxRuleCountry->getCountryId()) ->set("COUNTRY_TITLE" , $taxRuleCountry->getVirtualColumn(CountryTableMap::TABLE_NAME . '_i18n_TITLE')) @@ -167,7 +167,7 @@ class TaxRuleCountry extends BaseI18nLoop ->set("COUNTRY_DESCRIPTION" , $taxRuleCountry->getVirtualColumn('i18n_DESCRIPTION')) ->set("COUNTRY_POSTSCRIPTUM" , $taxRuleCountry->getVirtualColumn('i18n_POSTSCRIPTUM')); } - } elseif($ask === 'taxes') { + } elseif ($ask === 'taxes') { $loopResultRow ->set("TAX_RULE" , $taxRuleCountry->getTaxRuleId()) ->set("COUNTRY" , $taxRuleCountry->getCountryId()) @@ -178,8 +178,6 @@ class TaxRuleCountry extends BaseI18nLoop ; } - - $loopResult->addRow($loopResultRow); } diff --git a/core/lib/Thelia/Core/Template/ParserContext.php b/core/lib/Thelia/Core/Template/ParserContext.php index 9e3fde416..1f80f7cd5 100755 --- a/core/lib/Thelia/Core/Template/ParserContext.php +++ b/core/lib/Thelia/Core/Template/ParserContext.php @@ -23,7 +23,7 @@ namespace Thelia\Core\Template; -use Thelia\Model\ConfigQuery; +use Thelia\Core\Thelia; use Thelia\Core\HttpFoundation\Request; use Thelia\Form\BaseForm; /** @@ -39,7 +39,7 @@ class ParserContext implements \IteratorAggregate public function __construct(Request $request) { // Setup basic variables - $this->set('THELIA_VERSION' , ConfigQuery::read('thelia_version', 'undefined')) + $this->set('THELIA_VERSION' , Thelia::THELIA_VERSION) ; } diff --git a/core/lib/Thelia/Core/Template/Smarty/AbstractSmartyPlugin.php b/core/lib/Thelia/Core/Template/Smarty/AbstractSmartyPlugin.php index 8ef21f51e..b596f9d81 100755 --- a/core/lib/Thelia/Core/Template/Smarty/AbstractSmartyPlugin.php +++ b/core/lib/Thelia/Core/Template/Smarty/AbstractSmartyPlugin.php @@ -40,7 +40,7 @@ abstract class AbstractSmartyPlugin */ protected function _explode($commaSeparatedValues) { - if(null === $commaSeparatedValues) { + if (null === $commaSeparatedValues) { return array(); } diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php index 8539796b0..494e219eb 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php @@ -60,8 +60,8 @@ use Symfony\Component\Form\Extension\Core\View\ChoiceView; */ class Form extends AbstractSmartyPlugin { - static private $taggedFieldsStack = null; - static private $taggedFieldsStackPosition = null; + private static $taggedFieldsStack = null; + private static $taggedFieldsStackPosition = null; protected $request; protected $parserContext; @@ -113,13 +113,12 @@ class Form extends AbstractSmartyPlugin $template->assign("form_error", $instance->hasError() ? true : false); $template->assign("form_error_message", $instance->getErrorMessage()); - } - else { + } else { return $content; } } - protected function assignFieldValues($template, $fieldName, $fieldValue, $fieldVars) + protected function assignFieldValues($template, $fieldName, $fieldValue, $fieldVars, $total_value_count = 1) { $template->assign("name", $fieldName); @@ -127,7 +126,6 @@ class Form extends AbstractSmartyPlugin $template->assign("checked", isset($fieldVars['checked']) ? $fieldVars['checked'] : false); - //data $template->assign("data", $fieldVars['data']); @@ -136,6 +134,8 @@ class Form extends AbstractSmartyPlugin $template->assign('required', isset($fieldVars['required']) ? $fieldVars['required'] : false); + $template->assign('total_value_count', $total_value_count); + $errors = $fieldVars["errors"]; $template->assign("error", empty($errors) ? false : true); @@ -159,13 +159,13 @@ class Form extends AbstractSmartyPlugin $formFieldType = $formFieldConfig->getType()->getInnerType(); /* access to choices */ - if($formFieldType instanceof ChoiceType) { + if ($formFieldType instanceof ChoiceType) { $template->assign("choices", $formFieldView->vars['choices']); } /* access to collections */ - if($formFieldType instanceof CollectionType) { - if( true === $formFieldConfig->getOption('prototype') ) { + if ($formFieldType instanceof CollectionType) { + if ( true === $formFieldConfig->getOption('prototype') ) { } else { /* access to choices */ @@ -177,17 +177,16 @@ class Form extends AbstractSmartyPlugin } /* access to thelia type */ - if($formFieldType instanceof TheliaType) { + if ($formFieldType instanceof TheliaType) { $template->assign("formType", $formFieldView->vars['type']); - - switch($formFieldView->vars['type']) { + switch ($formFieldView->vars['type']) { case "choice": - if(!isset($formFieldView->vars['options']['choices']) || !is_array($formFieldView->vars['options']['choices'])) { + if (!isset($formFieldView->vars['options']['choices']) || !is_array($formFieldView->vars['options']['choices'])) { //throw new } $choices = array(); - foreach($formFieldView->vars['options']['choices'] as $value => $choice) { + foreach ($formFieldView->vars['options']['choices'] as $value => $choice) { $choices[] = new ChoiceView($value, $value, $choice); } $template->assign("choices", $choices); @@ -208,49 +207,42 @@ class Form extends AbstractSmartyPlugin $value = $formFieldView->vars["value"]; // We have a collection - if (count($formFieldView->children) > 0) { + if (0 < $value_count = count($formFieldView->children)) { - $key = $this->getParam($params, 'value_key'); + $key = $this->getParam($params, 'value_key', null); - if ($key != null) { + if ($key !== null) { + // If the field is not found, use an empty value + $val = array_key_exists($key, $value) ? $value[$key] : ''; - if (isset($value[$key])) { + $name = sprintf("%s[%s]", $formFieldView->vars["full_name"], $key); - $name = sprintf("%s[%s]", $formFieldView->vars["full_name"], $key); + $val = $value[$key]; - $val = $value[$key]; - - $this->assignFieldValues($template, $name, $val, $formFieldView->vars); - } - else { - throw new \LogicException(sprintf("Cannot find a value for key '%s' in field '%s'", $key, $formFieldView->vars["name"])); - } - } - else { + $this->assignFieldValues($template, $name, $val, $formFieldView->vars, $value_count); + } else { throw new \InvalidArgumentException(sprintf("Missing or empty parameter 'value_key' for field '%s'", $formFieldView->vars["name"])); } - } - else { + } else { $this->assignFieldValues($template, $formFieldView->vars["full_name"], $formFieldView->vars["value"], $formFieldView->vars); } $formFieldView->setRendered(); - } - else { + } else { return $content; } } public function renderTaggedFormFields($params, $content, \Smarty_Internal_Template $template, &$repeat) { - if(null === $content) { + if (null === $content) { self::$taggedFieldsStack = $this->getFormFieldsFromTag($params); self::$taggedFieldsStackPosition = 0; } else { self::$taggedFieldsStackPosition++; } - if(isset(self::$taggedFieldsStack[self::$taggedFieldsStackPosition])) { + if (isset(self::$taggedFieldsStack[self::$taggedFieldsStackPosition])) { $this->assignFieldValues( $template, self::$taggedFieldsStack[self::$taggedFieldsStackPosition]['view']->vars["full_name"], @@ -270,7 +262,7 @@ class Form extends AbstractSmartyPlugin self::$taggedFieldsStackPosition = null; } - if(null !== $content) { + if (null !== $content) { return $content; } } @@ -324,8 +316,7 @@ class Form extends AbstractSmartyPlugin if ($repeat) { $this->assignFieldErrorVars($template, $errors); - } - else { + } else { return $content; } } @@ -366,8 +357,8 @@ class Form extends AbstractSmartyPlugin throw new \InvalidArgumentException("'tag' parameter is missing"); $viewList = array(); - foreach($instance->getView() as $view) { - if(isset($view->vars['attr']['tag']) && $tag == $view->vars['attr']['tag']) { + foreach ($instance->getView() as $view) { + if (isset($view->vars['attr']['tag']) && $tag == $view->vars['attr']['tag']) { $fieldData = $instance->getForm()->all()[$view->vars['name']]; $viewList[] = array( 'view' => $view, diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/Format.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/Format.php index 01491e6fd..05c7bb0f6 100644 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/Format.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/Format.php @@ -73,10 +73,10 @@ class Format extends AbstractSmartyPlugin $date = $this->getParam($params, "date", false); if ($date === false) { - throw new SmartyPluginException("date is a mandatory parameter in format_date function"); + return ""; } - if (!$date instanceof \DateTime) { + if (!($date instanceof \DateTime)) { return ""; } @@ -112,7 +112,7 @@ class Format extends AbstractSmartyPlugin $number = $this->getParam($params, "number", false); if ($number === false) { - throw new SmartyPluginException("number is a mandatory parameter in format_number function"); + return ""; } if ($number == '') { diff --git a/core/lib/Thelia/Core/Template/Smarty/SmartyParser.php b/core/lib/Thelia/Core/Template/Smarty/SmartyParser.php index e9b0fef8a..68da0af12 100755 --- a/core/lib/Thelia/Core/Template/Smarty/SmartyParser.php +++ b/core/lib/Thelia/Core/Template/Smarty/SmartyParser.php @@ -8,7 +8,6 @@ use \Symfony\Component\EventDispatcher\EventDispatcherInterface; use \Smarty; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\Exception\HttpException; use Thelia\Core\Template\ParserInterface; use Thelia\Core\Template\Smarty\AbstractSmartyPlugin; diff --git a/core/lib/Thelia/Core/Thelia.php b/core/lib/Thelia/Core/Thelia.php index 690e2cd81..1bc1e7649 100755 --- a/core/lib/Thelia/Core/Thelia.php +++ b/core/lib/Thelia/Core/Thelia.php @@ -54,9 +54,7 @@ use Propel\Runtime\Connection\ConnectionManagerSingle; class Thelia extends Kernel { - const THELIA_VERSION = 0.1; - - protected $tpexConfig; + const THELIA_VERSION = '2.0.0-beta1'; public function init() { diff --git a/core/lib/Thelia/Form/AdministratorCreationForm.php b/core/lib/Thelia/Form/AdministratorCreationForm.php index afab36cac..4b5afe34c 100644 --- a/core/lib/Thelia/Form/AdministratorCreationForm.php +++ b/core/lib/Thelia/Form/AdministratorCreationForm.php @@ -25,12 +25,9 @@ namespace Thelia\Form; use Symfony\Component\Validator\Constraints; use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\ExecutionContextInterface; -use Thelia\Core\Security\AccessManager; -use Thelia\Core\Security\Resource\AdminResources; use Thelia\Core\Translation\Translator; use Thelia\Model\AdminQuery; use Thelia\Model\ProfileQuery; -use Thelia\Model\ConfigQuery; class AdministratorCreationForm extends BaseForm { @@ -110,7 +107,7 @@ class AdministratorCreationForm extends BaseForm { $data = $context->getRoot()->getData(); - if($data["password"] === '' && $data["password_confirm"] === '') { + if ($data["password"] === '' && $data["password_confirm"] === '') { $context->addViolation("password can't be empty"); } @@ -118,7 +115,7 @@ class AdministratorCreationForm extends BaseForm $context->addViolation("password confirmation is not the same as password field"); } - if(strlen($data["password"]) < 4) { + if (strlen($data["password"]) < 4) { $context->addViolation("password must be composed of at least 4 characters"); } } @@ -135,4 +132,4 @@ class AdministratorCreationForm extends BaseForm { return "thelia_admin_administrator_creation"; } -} \ No newline at end of file +} diff --git a/core/lib/Thelia/Form/AdministratorModificationForm.php b/core/lib/Thelia/Form/AdministratorModificationForm.php index 68ad228a5..7e7a4a845 100755 --- a/core/lib/Thelia/Form/AdministratorModificationForm.php +++ b/core/lib/Thelia/Form/AdministratorModificationForm.php @@ -25,7 +25,6 @@ namespace Thelia\Form; use Symfony\Component\Validator\Constraints; use Symfony\Component\Validator\ExecutionContextInterface; -use Thelia\Core\Translation\Translator; use Thelia\Model\AdminQuery; class AdministratorModificationForm extends AdministratorCreationForm @@ -90,7 +89,7 @@ class AdministratorModificationForm extends AdministratorCreationForm $context->addViolation("password confirmation is not the same as password field"); } - if($data["password"] !== '' && strlen($data["password"]) < 4) { + if ($data["password"] !== '' && strlen($data["password"]) < 4) { $context->addViolation("password must be composed of at least 4 characters"); } } diff --git a/core/lib/Thelia/Form/ContactForm.php b/core/lib/Thelia/Form/ContactForm.php index 3cc7bc737..8497a2222 100644 --- a/core/lib/Thelia/Form/ContactForm.php +++ b/core/lib/Thelia/Form/ContactForm.php @@ -27,7 +27,6 @@ use Symfony\Component\Validator\Constraints\Email; use Symfony\Component\Validator\Constraints\NotBlank; use Thelia\Core\Translation\Translator; - /** * Class ContactForm * @package Thelia\Form @@ -107,4 +106,4 @@ class ContactForm extends BaseForm { return 'thelia_contact'; } -} \ No newline at end of file +} diff --git a/core/lib/Thelia/Form/CouponCode.php b/core/lib/Thelia/Form/CouponCode.php index 06dceb177..d9b546f1f 100755 --- a/core/lib/Thelia/Form/CouponCode.php +++ b/core/lib/Thelia/Form/CouponCode.php @@ -23,8 +23,6 @@ namespace Thelia\Form; use Symfony\Component\Validator\Constraints; -use Thelia\Model\ModuleQuery; -use Thelia\Module\BaseModule; /** * Class CouponCode diff --git a/core/lib/Thelia/Form/CouponCreationForm.php b/core/lib/Thelia/Form/CouponCreationForm.php index 448f65e38..9a38b0d83 100755 --- a/core/lib/Thelia/Form/CouponCreationForm.php +++ b/core/lib/Thelia/Form/CouponCreationForm.php @@ -27,7 +27,6 @@ use Symfony\Component\Validator\Constraints\Date; use Symfony\Component\Validator\Constraints\GreaterThanOrEqual; use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Constraints\NotEqualTo; -use Symfony\Component\Validator\Constraints\Range; /** * Created by JetBrains PhpStorm. diff --git a/core/lib/Thelia/Form/CustomerPasswordUpdateForm.php b/core/lib/Thelia/Form/CustomerPasswordUpdateForm.php index 3b4cfec40..afea21f70 100755 --- a/core/lib/Thelia/Form/CustomerPasswordUpdateForm.php +++ b/core/lib/Thelia/Form/CustomerPasswordUpdateForm.php @@ -26,7 +26,6 @@ use Symfony\Component\Validator\Constraints; use Symfony\Component\Validator\ExecutionContextInterface; use Thelia\Model\ConfigQuery; use Thelia\Core\Translation\Translator; -use Thelia\Model\CustomerQuery; /** * Class CustomerPasswordUpdateForm diff --git a/core/lib/Thelia/Form/CustomerProfilUpdateForm.php b/core/lib/Thelia/Form/CustomerProfilUpdateForm.php index 210d6edbc..d1e928d0c 100755 --- a/core/lib/Thelia/Form/CustomerProfilUpdateForm.php +++ b/core/lib/Thelia/Form/CustomerProfilUpdateForm.php @@ -22,11 +22,8 @@ /*************************************************************************************/ namespace Thelia\Form; -use Symfony\Component\Validator\Constraints; use Symfony\Component\Validator\ExecutionContextInterface; use Thelia\Model\CustomerQuery; -use Thelia\Model\ConfigQuery; -use Thelia\Core\Translation\Translator; /** * Class CustomerProfilUpdateForm @@ -69,7 +66,6 @@ class CustomerProfilUpdateForm extends CustomerCreateForm )); } - /** * @param $value * @param ExecutionContextInterface $context diff --git a/core/lib/Thelia/Form/Lang/LangCreateForm.php b/core/lib/Thelia/Form/Lang/LangCreateForm.php index deef71802..ccad58320 100644 --- a/core/lib/Thelia/Form/Lang/LangCreateForm.php +++ b/core/lib/Thelia/Form/Lang/LangCreateForm.php @@ -26,7 +26,6 @@ use Symfony\Component\Validator\Constraints\NotBlank; use Thelia\Form\BaseForm; use Thelia\Core\Translation\Translator; - /** * Class LangCreateForm * @package Thelia\Form\Lang @@ -113,4 +112,4 @@ class LangCreateForm extends BaseForm { return 'thelia_language_create'; } -} \ No newline at end of file +} diff --git a/core/lib/Thelia/Form/Lang/LangDefaultBehaviorForm.php b/core/lib/Thelia/Form/Lang/LangDefaultBehaviorForm.php index 23418a392..38a48a007 100644 --- a/core/lib/Thelia/Form/Lang/LangDefaultBehaviorForm.php +++ b/core/lib/Thelia/Form/Lang/LangDefaultBehaviorForm.php @@ -24,11 +24,9 @@ namespace Thelia\Form\Lang; use Symfony\Component\Validator\Constraints\NotBlank; -use Symfony\Component\Validator\Constraints\Range; use Thelia\Form\BaseForm; use Thelia\Core\Translation\Translator; - /** * Class LangDefaultBehaviorForm * @package Thelia\Form\Lang @@ -82,4 +80,4 @@ class LangDefaultBehaviorForm extends BaseForm { return 'thelia_lang_defaultBehavior'; } -} \ No newline at end of file +} diff --git a/core/lib/Thelia/Form/Lang/LangUpdateForm.php b/core/lib/Thelia/Form/Lang/LangUpdateForm.php index 0463335f7..e0c572797 100644 --- a/core/lib/Thelia/Form/Lang/LangUpdateForm.php +++ b/core/lib/Thelia/Form/Lang/LangUpdateForm.php @@ -25,7 +25,6 @@ namespace Thelia\Form\Lang; use Symfony\Component\Validator\Constraints\GreaterThan; use Symfony\Component\Validator\Constraints\NotBlank; - /** * Class LangUpdateForm * @package Thelia\Form\Lang @@ -51,4 +50,4 @@ class LangUpdateForm extends LangCreateForm { return 'thelia_lang_update'; } -} \ No newline at end of file +} diff --git a/core/lib/Thelia/Form/Lang/LangUrlEvent.php b/core/lib/Thelia/Form/Lang/LangUrlEvent.php index de8248c81..18366f094 100644 --- a/core/lib/Thelia/Form/Lang/LangUrlEvent.php +++ b/core/lib/Thelia/Form/Lang/LangUrlEvent.php @@ -24,7 +24,6 @@ namespace Thelia\Form\Lang; use Thelia\Core\Event\ActionEvent; - /** * Class LangUrlEvent * @package Thelia\Form\Lang @@ -43,4 +42,4 @@ class LangUrlEvent extends ActionEvent { return $this->url; } -} \ No newline at end of file +} diff --git a/core/lib/Thelia/Form/Lang/LangUrlForm.php b/core/lib/Thelia/Form/Lang/LangUrlForm.php index ec9837329..784924728 100644 --- a/core/lib/Thelia/Form/Lang/LangUrlForm.php +++ b/core/lib/Thelia/Form/Lang/LangUrlForm.php @@ -26,7 +26,6 @@ use Symfony\Component\Validator\Constraints\NotBlank; use Thelia\Form\BaseForm; use Thelia\Model\LangQuery; - /** * Class LangUrlForm * @package Thelia\Form\Lang @@ -84,4 +83,4 @@ class LangUrlForm extends BaseForm { return 'thelia_language_url'; } -} \ No newline at end of file +} diff --git a/core/lib/Thelia/Form/NewsletterForm.php b/core/lib/Thelia/Form/NewsletterForm.php index 3772df71d..ad0aab5a4 100644 --- a/core/lib/Thelia/Form/NewsletterForm.php +++ b/core/lib/Thelia/Form/NewsletterForm.php @@ -30,7 +30,6 @@ use Symfony\Component\Validator\ExecutionContextInterface; use Thelia\Core\Translation\Translator; use Thelia\Model\NewsletterQuery; - /** * Class NewsletterForm * @package Thelia\Form @@ -95,4 +94,4 @@ class NewsletterForm extends BaseForm { return 'thelia_newsletter'; } -} \ No newline at end of file +} diff --git a/core/lib/Thelia/Form/ProductDefaultSaleElementUpdateForm.php b/core/lib/Thelia/Form/ProductDefaultSaleElementUpdateForm.php index 807f8ac07..2643692a2 100644 --- a/core/lib/Thelia/Form/ProductDefaultSaleElementUpdateForm.php +++ b/core/lib/Thelia/Form/ProductDefaultSaleElementUpdateForm.php @@ -22,8 +22,91 @@ /*************************************************************************************/ namespace Thelia\Form; +use Symfony\Component\Validator\Constraints\GreaterThan; +use Symfony\Component\Validator\Constraints\NotBlank; +use Thelia\Model\Currency; +use Thelia\Core\Translation\Translator; + class ProductDefaultSaleElementUpdateForm extends ProductSaleElementUpdateForm { + use StandardDescriptionFieldsTrait; + + protected function buildForm() + { + $this->formBuilder + ->add("product_id", "integer", array( + "label" => Translator::getInstance()->trans("Product ID *"), + "label_attr" => array("for" => "product_id_field"), + "constraints" => array(new GreaterThan(array('value' => 0))) + )) + ->add("product_sale_element_id", "integer", array( + "label" => Translator::getInstance()->trans("Product sale element ID *"), + "label_attr" => array("for" => "product_sale_element_id_field") + )) + ->add("reference", "text", array( + "label" => Translator::getInstance()->trans("Reference *"), + "label_attr" => array("for" => "reference_field") + )) + ->add("price", "number", array( + "constraints" => array(new NotBlank()), + "label" => Translator::getInstance()->trans("Product price excluding taxes *"), + "label_attr" => array("for" => "price_field") + )) + ->add("price_with_tax", "number", array( + "label" => Translator::getInstance()->trans("Product price including taxes"), + "label_attr" => array("for" => "price_with_tax_field") + )) + ->add("currency", "integer", array( + "constraints" => array(new NotBlank()), + "label" => Translator::getInstance()->trans("Price currency *"), + "label_attr" => array("for" => "currency_field") + )) + ->add("tax_rule", "integer", array( + "constraints" => array(new NotBlank()), + "label" => Translator::getInstance()->trans("Tax rule for this product *"), + "label_attr" => array("for" => "tax_rule_field") + )) + ->add("weight", "number", array( + "constraints" => array(new NotBlank()), + "label" => Translator::getInstance()->trans("Weight *"), + "label_attr" => array("for" => "weight_field") + )) + ->add("quantity", "number", array( + "constraints" => array(new NotBlank()), + "label" => Translator::getInstance()->trans("Available quantity *"), + "label_attr" => array("for" => "quantity_field") + )) + ->add("sale_price", "number", array( + "label" => Translator::getInstance()->trans("Sale price without taxes"), + "label_attr" => array("for" => "price_with_tax_field") + )) + ->add("sale_price_with_tax", "number", array( + "label" => Translator::getInstance()->trans("Sale price including taxes"), + "label_attr" => array("for" => "sale_price_with_tax_field") + )) + ->add("onsale", "integer", array( + "label" => Translator::getInstance()->trans("This product is on sale"), + "label_attr" => array("for" => "onsale_field") + )) + ->add("isnew", "integer", array( + "label" => Translator::getInstance()->trans("Advertise this product as new"), + "label_attr" => array("for" => "isnew_field") + )) + ->add("isdefault", "integer", array( + "label" => Translator::getInstance()->trans("Is it the default product sale element ?"), + "label_attr" => array("for" => "isdefault_field") + )) + ->add("ean_code", "text", array( + "label" => Translator::getInstance()->trans("EAN Code"), + "label_attr" => array("for" => "ean_code_field") + )) + ->add("use_exchange_rate", "integer", array( + "label" => Translator::getInstance()->trans("Apply exchange rates on price in %sym", array("%sym" => Currency::getDefaultCurrency()->getSymbol())), + "label_attr" => array("for" => "use_exchange_rate_field") + )) + ; + } + public function getName() { return "thelia_product_default_sale_element_update_form"; diff --git a/core/lib/Thelia/Form/ProductSaleElementUpdateForm.php b/core/lib/Thelia/Form/ProductSaleElementUpdateForm.php index e3a74a755..da831545a 100644 --- a/core/lib/Thelia/Form/ProductSaleElementUpdateForm.php +++ b/core/lib/Thelia/Form/ProductSaleElementUpdateForm.php @@ -23,9 +23,9 @@ namespace Thelia\Form; use Symfony\Component\Validator\Constraints\GreaterThan; -use Thelia\Core\Translation\Translator; use Symfony\Component\Validator\Constraints\NotBlank; use Thelia\Model\Currency; +use Thelia\Core\Translation\Translator; class ProductSaleElementUpdateForm extends BaseForm { @@ -34,68 +34,124 @@ class ProductSaleElementUpdateForm extends BaseForm protected function buildForm() { $this->formBuilder + ->add("tax_rule", "integer", array( + "constraints" => array(new NotBlank()), + "label" => Translator::getInstance()->trans("Tax rule for this product *"), + "label_attr" => array("for" => "tax_rule_field") + )) ->add("product_id", "integer", array( - "label" => Translator::getInstance()->trans("Product ID *"), - "label_attr" => array("for" => "product_id_field"), - "constraints" => array(new GreaterThan(array('value' => 0))) + "label" => Translator::getInstance()->trans("Product ID *"), + "label_attr" => array("for" => "product_id_field"), + "constraints" => array(new GreaterThan(array('value' => 0))) )) - ->add("product_sale_element_id", "integer", array( - "label" => Translator::getInstance()->trans("Product sale element ID *"), - "label_attr" => array("for" => "product_sale_element_id_field") - )) - ->add("reference", "text", array( - "label" => Translator::getInstance()->trans("Reference *"), - "label_attr" => array("for" => "reference_field") - )) - ->add("price", "number", array( - "constraints" => array(new NotBlank()), - "label" => Translator::getInstance()->trans("Product price excluding taxes *"), - "label_attr" => array("for" => "price_field") + ->add("default_pse", "integer", array( + "label" => Translator::getInstance()->trans("Default product sale element"), + "label_attr" => array("for" => "default_pse_field"), )) ->add("currency", "integer", array( - "constraints" => array(new NotBlank()), - "label" => Translator::getInstance()->trans("Price currency *"), - "label_attr" => array("for" => "currency_field") - )) - ->add("tax_rule", "integer", array( - "constraints" => array(new NotBlank()), - "label" => Translator::getInstance()->trans("Tax rule for this product *"), - "label_attr" => array("for" => "tax_rule_field") - )) - ->add("weight", "number", array( - "constraints" => array(new NotBlank()), - "label" => Translator::getInstance()->trans("Weight *"), - "label_attr" => array("for" => "weight_field") - )) - ->add("quantity", "number", array( - "constraints" => array(new NotBlank()), - "label" => Translator::getInstance()->trans("Available quantity *"), - "label_attr" => array("for" => "quantity_field") - )) - ->add("sale_price", "number", array( - "label" => Translator::getInstance()->trans("Sale price without taxes *"), - "label_attr" => array("for" => "price_with_tax_field") - )) - ->add("onsale", "integer", array( - "label" => Translator::getInstance()->trans("This product is on sale"), - "label_attr" => array("for" => "onsale_field") - )) - ->add("isnew", "integer", array( - "label" => Translator::getInstance()->trans("Advertise this product as new"), - "label_attr" => array("for" => "isnew_field") - )) - ->add("isdefault", "integer", array( - "label" => Translator::getInstance()->trans("Is it the default product sale element ?"), - "label_attr" => array("for" => "isdefault_field") - )) - ->add("ean_code", "integer", array( - "label" => Translator::getInstance()->trans("EAN Code"), - "label_attr" => array("for" => "ean_code_field") + "constraints" => array(new NotBlank()), + "label" => Translator::getInstance()->trans("Price currency *"), + "label_attr" => array("for" => "currency_field") )) ->add("use_exchange_rate", "integer", array( "label" => Translator::getInstance()->trans("Apply exchange rates on price in %sym", array("%sym" => Currency::getDefaultCurrency()->getSymbol())), "label_attr" => array("for" => "use_exchange_rate_field") )) + + // -- Collections + + ->add('product_sale_element_id', 'collection', array( + 'type' => 'integer', + 'label' => Translator::getInstance()->trans('Product sale element ID *'), + 'label_attr' => array('for' => 'product_sale_element_id_field'), + 'allow_add' => true, + 'allow_delete' => true, + )) + ->add('reference', 'collection', array( + 'type' => 'text', + 'label' => Translator::getInstance()->trans('Reference *'), + 'label_attr' => array('for' => 'reference_field'), + 'allow_add' => true, + 'allow_delete' => true, + )) + ->add('price', 'collection', array( + 'type' => 'number', + 'label' => Translator::getInstance()->trans('Product price excluding taxes *'), + 'label_attr' => array('for' => 'price_field'), + 'allow_add' => true, + 'allow_delete' => true, + 'options' => array( + 'constraints' => array(new NotBlank()), + ) + )) + ->add('price_with_tax', 'collection', array( + 'type' => 'number', + 'label' => Translator::getInstance()->trans('Product price including taxes'), + 'label_attr' => array('for' => 'price_with_tax_field'), + 'allow_add' => true, + 'allow_delete' => true, + )) + ->add('weight', 'collection', array( + 'type' => 'number', + 'label' => Translator::getInstance()->trans('Weight *'), + 'label_attr' => array('for' => 'weight_field'), + 'allow_add' => true, + 'allow_delete' => true, + 'options' => array( + 'constraints' => array(new NotBlank()), + ) + )) + ->add('quantity', 'collection', array( + 'type' => 'number', + 'label' => Translator::getInstance()->trans('Available quantity *'), + 'label_attr' => array('for' => 'quantity_field'), + 'allow_add' => true, + 'allow_delete' => true, + 'options' => array( + 'constraints' => array(new NotBlank()), + ) + )) + ->add('sale_price', 'collection', array( + 'label' => Translator::getInstance()->trans('Sale price without taxes'), + 'label_attr' => array('for' => 'price_with_tax_field'), + 'allow_add' => true, + 'allow_delete' => true, + )) + ->add('sale_price_with_tax', 'collection', array( + 'type' => 'number', + 'label' => Translator::getInstance()->trans('Sale price including taxes'), + 'label_attr' => array('for' => 'sale_price_with_tax_field'), + 'allow_add' => true, + 'allow_delete' => true, + )) + ->add('onsale', 'collection', array( + 'type' => 'integer', + 'label' => Translator::getInstance()->trans('This product is on sale'), + 'label_attr' => array('for' => 'onsale_field'), + 'allow_add' => true, + 'allow_delete' => true, + )) + ->add('isnew', 'collection', array( + 'type' => 'integer', + 'label' => Translator::getInstance()->trans('Advertise this product as new'), + 'label_attr' => array('for' => 'isnew_field'), + 'allow_add' => true, + 'allow_delete' => true, + )) + ->add('isdefault', 'collection', array( + 'type' => 'integer', + 'label' => Translator::getInstance()->trans('Is it the default product sale element ?'), + 'label_attr' => array('for' => 'isdefault_field'), + 'allow_add' => true, + 'allow_delete' => true, + )) + ->add('ean_code', 'collection', array( + 'type' => 'text', + 'label' => Translator::getInstance()->trans('EAN Code'), + 'label_attr' => array('for' => 'ean_code_field'), + 'allow_add' => true, + 'allow_delete' => true, + )) ; } diff --git a/core/lib/Thelia/Form/ProfileUpdateModuleAccessForm.php b/core/lib/Thelia/Form/ProfileUpdateModuleAccessForm.php index fcbee854f..488c22d42 100644 --- a/core/lib/Thelia/Form/ProfileUpdateModuleAccessForm.php +++ b/core/lib/Thelia/Form/ProfileUpdateModuleAccessForm.php @@ -26,7 +26,6 @@ use Symfony\Component\Validator\Constraints; use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\ExecutionContextInterface; use Thelia\Core\Security\AccessManager; -use Thelia\Core\Translation\Translator; use Thelia\Model\ProfileQuery; use Thelia\Model\ModuleQuery; @@ -57,7 +56,7 @@ class ProfileUpdateModuleAccessForm extends BaseForm )) ; - foreach(ModuleQuery::create()->find() as $module) { + foreach (ModuleQuery::create()->find() as $module) { $this->formBuilder->add( self::MODULE_ACCESS_FIELD_PREFIX . ':' . str_replace(".", ":", $module->getCode()), "choice", diff --git a/core/lib/Thelia/Form/ProfileUpdateResourceAccessForm.php b/core/lib/Thelia/Form/ProfileUpdateResourceAccessForm.php index 99ef2ccf3..69a982ac6 100644 --- a/core/lib/Thelia/Form/ProfileUpdateResourceAccessForm.php +++ b/core/lib/Thelia/Form/ProfileUpdateResourceAccessForm.php @@ -26,7 +26,6 @@ use Symfony\Component\Validator\Constraints; use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\ExecutionContextInterface; use Thelia\Core\Security\AccessManager; -use Thelia\Core\Translation\Translator; use Thelia\Model\ProfileQuery; use Thelia\Model\ResourceQuery; @@ -57,7 +56,7 @@ class ProfileUpdateResourceAccessForm extends BaseForm )) ; - foreach(ResourceQuery::create()->find() as $resource) { + foreach (ResourceQuery::create()->find() as $resource) { $this->formBuilder->add( self::RESOURCE_ACCESS_FIELD_PREFIX . ':' . str_replace(".", ":", $resource->getCode()), "choice", diff --git a/core/lib/Thelia/Form/TaxCreationForm.php b/core/lib/Thelia/Form/TaxCreationForm.php index abc8fa316..65617e615 100644 --- a/core/lib/Thelia/Form/TaxCreationForm.php +++ b/core/lib/Thelia/Form/TaxCreationForm.php @@ -43,7 +43,7 @@ class TaxCreationForm extends BaseForm $types = TaxEngine::getInstance()->getTaxTypeList(); $typeList = array(); $requirementList = array(); - foreach($types as $type) { + foreach ($types as $type) { $classPath = "\\Thelia\\TaxEngine\\TaxType\\$type"; $instance = new $classPath(); $typeList[$type] = $instance->getTitle(); @@ -65,8 +65,8 @@ class TaxCreationForm extends BaseForm )) ; - foreach($requirementList as $type => $requirements) { - foreach($requirements as $name => $requirementType) { + foreach ($requirementList as $type => $requirements) { + foreach ($requirements as $name => $requirementType) { $this->formBuilder ->add($type . ':' . $name, new TheliaType(), array( //"instance" => $requirementType, diff --git a/core/lib/Thelia/Model/Base/Newsletter.php b/core/lib/Thelia/Model/Base/Newsletter.php index ff7afb159..5282045d3 100644 --- a/core/lib/Thelia/Model/Base/Newsletter.php +++ b/core/lib/Thelia/Model/Base/Newsletter.php @@ -2,6 +2,7 @@ namespace Thelia\Model\Base; +use \DateTime; use \Exception; use \PDO; use Propel\Runtime\Propel; @@ -14,6 +15,8 @@ use Propel\Runtime\Exception\BadMethodCallException; use Propel\Runtime\Exception\PropelException; use Propel\Runtime\Map\TableMap; use Propel\Runtime\Parser\AbstractParser; +use Propel\Runtime\Util\PropelDateTime; +use Thelia\Model\Newsletter as ChildNewsletter; use Thelia\Model\NewsletterQuery as ChildNewsletterQuery; use Thelia\Model\Map\NewsletterTableMap; @@ -75,6 +78,24 @@ abstract class Newsletter implements ActiveRecordInterface */ protected $lastname; + /** + * The value for the locale field. + * @var string + */ + protected $locale; + + /** + * The value for the created_at field. + * @var string + */ + protected $created_at; + + /** + * The value for the updated_at field. + * @var string + */ + protected $updated_at; + /** * Flag to prevent endless save loop, if this object is referenced * by another object which falls in this transaction. @@ -385,6 +406,57 @@ abstract class Newsletter implements ActiveRecordInterface return $this->lastname; } + /** + * Get the [locale] column value. + * + * @return string + */ + public function getLocale() + { + + return $this->locale; + } + + /** + * Get the [optionally formatted] temporal [created_at] column value. + * + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the raw \DateTime object will be returned. + * + * @return mixed Formatted date/time value as string or \DateTime object (if format is NULL), NULL if column is NULL, and 0 if column value is 0000-00-00 00:00:00 + * + * @throws PropelException - if unable to parse/validate the date/time value. + */ + public function getCreatedAt($format = NULL) + { + if ($format === null) { + return $this->created_at; + } else { + return $this->created_at instanceof \DateTime ? $this->created_at->format($format) : null; + } + } + + /** + * Get the [optionally formatted] temporal [updated_at] column value. + * + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the raw \DateTime object will be returned. + * + * @return mixed Formatted date/time value as string or \DateTime object (if format is NULL), NULL if column is NULL, and 0 if column value is 0000-00-00 00:00:00 + * + * @throws PropelException - if unable to parse/validate the date/time value. + */ + public function getUpdatedAt($format = NULL) + { + if ($format === null) { + return $this->updated_at; + } else { + return $this->updated_at instanceof \DateTime ? $this->updated_at->format($format) : null; + } + } + /** * Set the value of [id] column. * @@ -469,6 +541,69 @@ abstract class Newsletter implements ActiveRecordInterface return $this; } // setLastname() + /** + * Set the value of [locale] column. + * + * @param string $v new value + * @return \Thelia\Model\Newsletter The current object (for fluent API support) + */ + public function setLocale($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->locale !== $v) { + $this->locale = $v; + $this->modifiedColumns[] = NewsletterTableMap::LOCALE; + } + + + return $this; + } // setLocale() + + /** + * Sets the value of [created_at] column to a normalized version of the date/time value specified. + * + * @param mixed $v string, integer (timestamp), or \DateTime value. + * Empty strings are treated as NULL. + * @return \Thelia\Model\Newsletter The current object (for fluent API support) + */ + public function setCreatedAt($v) + { + $dt = PropelDateTime::newInstance($v, null, '\DateTime'); + if ($this->created_at !== null || $dt !== null) { + if ($dt !== $this->created_at) { + $this->created_at = $dt; + $this->modifiedColumns[] = NewsletterTableMap::CREATED_AT; + } + } // if either are not null + + + return $this; + } // setCreatedAt() + + /** + * Sets the value of [updated_at] column to a normalized version of the date/time value specified. + * + * @param mixed $v string, integer (timestamp), or \DateTime value. + * Empty strings are treated as NULL. + * @return \Thelia\Model\Newsletter The current object (for fluent API support) + */ + public function setUpdatedAt($v) + { + $dt = PropelDateTime::newInstance($v, null, '\DateTime'); + if ($this->updated_at !== null || $dt !== null) { + if ($dt !== $this->updated_at) { + $this->updated_at = $dt; + $this->modifiedColumns[] = NewsletterTableMap::UPDATED_AT; + } + } // if either are not null + + + return $this; + } // setUpdatedAt() + /** * Indicates whether the columns in this object are only set to default values. * @@ -517,6 +652,21 @@ abstract class Newsletter implements ActiveRecordInterface $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : NewsletterTableMap::translateFieldName('Lastname', TableMap::TYPE_PHPNAME, $indexType)]; $this->lastname = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : NewsletterTableMap::translateFieldName('Locale', TableMap::TYPE_PHPNAME, $indexType)]; + $this->locale = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : NewsletterTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + if ($col === '0000-00-00 00:00:00') { + $col = null; + } + $this->created_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : NewsletterTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + if ($col === '0000-00-00 00:00:00') { + $col = null; + } + $this->updated_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; $this->resetModified(); $this->setNew(false); @@ -525,7 +675,7 @@ abstract class Newsletter implements ActiveRecordInterface $this->ensureConsistency(); } - return $startcol + 4; // 4 = NewsletterTableMap::NUM_HYDRATE_COLUMNS. + return $startcol + 7; // 7 = NewsletterTableMap::NUM_HYDRATE_COLUMNS. } catch (Exception $e) { throw new PropelException("Error populating \Thelia\Model\Newsletter object", 0, $e); @@ -656,8 +806,19 @@ abstract class Newsletter implements ActiveRecordInterface $ret = $this->preSave($con); if ($isInsert) { $ret = $ret && $this->preInsert($con); + // timestampable behavior + if (!$this->isColumnModified(NewsletterTableMap::CREATED_AT)) { + $this->setCreatedAt(time()); + } + if (!$this->isColumnModified(NewsletterTableMap::UPDATED_AT)) { + $this->setUpdatedAt(time()); + } } else { $ret = $ret && $this->preUpdate($con); + // timestampable behavior + if ($this->isModified() && !$this->isColumnModified(NewsletterTableMap::UPDATED_AT)) { + $this->setUpdatedAt(time()); + } } if ($ret) { $affectedRows = $this->doSave($con); @@ -746,6 +907,15 @@ abstract class Newsletter implements ActiveRecordInterface if ($this->isColumnModified(NewsletterTableMap::LASTNAME)) { $modifiedColumns[':p' . $index++] = 'LASTNAME'; } + if ($this->isColumnModified(NewsletterTableMap::LOCALE)) { + $modifiedColumns[':p' . $index++] = 'LOCALE'; + } + if ($this->isColumnModified(NewsletterTableMap::CREATED_AT)) { + $modifiedColumns[':p' . $index++] = 'CREATED_AT'; + } + if ($this->isColumnModified(NewsletterTableMap::UPDATED_AT)) { + $modifiedColumns[':p' . $index++] = 'UPDATED_AT'; + } $sql = sprintf( 'INSERT INTO newsletter (%s) VALUES (%s)', @@ -769,6 +939,15 @@ abstract class Newsletter implements ActiveRecordInterface case 'LASTNAME': $stmt->bindValue($identifier, $this->lastname, PDO::PARAM_STR); break; + case 'LOCALE': + $stmt->bindValue($identifier, $this->locale, PDO::PARAM_STR); + break; + case 'CREATED_AT': + $stmt->bindValue($identifier, $this->created_at ? $this->created_at->format("Y-m-d H:i:s") : null, PDO::PARAM_STR); + break; + case 'UPDATED_AT': + $stmt->bindValue($identifier, $this->updated_at ? $this->updated_at->format("Y-m-d H:i:s") : null, PDO::PARAM_STR); + break; } } $stmt->execute(); @@ -843,6 +1022,15 @@ abstract class Newsletter implements ActiveRecordInterface case 3: return $this->getLastname(); break; + case 4: + return $this->getLocale(); + break; + case 5: + return $this->getCreatedAt(); + break; + case 6: + return $this->getUpdatedAt(); + break; default: return null; break; @@ -875,6 +1063,9 @@ abstract class Newsletter implements ActiveRecordInterface $keys[1] => $this->getEmail(), $keys[2] => $this->getFirstname(), $keys[3] => $this->getLastname(), + $keys[4] => $this->getLocale(), + $keys[5] => $this->getCreatedAt(), + $keys[6] => $this->getUpdatedAt(), ); $virtualColumns = $this->virtualColumns; foreach ($virtualColumns as $key => $virtualColumn) { @@ -926,6 +1117,15 @@ abstract class Newsletter implements ActiveRecordInterface case 3: $this->setLastname($value); break; + case 4: + $this->setLocale($value); + break; + case 5: + $this->setCreatedAt($value); + break; + case 6: + $this->setUpdatedAt($value); + break; } // switch() } @@ -954,6 +1154,9 @@ abstract class Newsletter implements ActiveRecordInterface if (array_key_exists($keys[1], $arr)) $this->setEmail($arr[$keys[1]]); if (array_key_exists($keys[2], $arr)) $this->setFirstname($arr[$keys[2]]); if (array_key_exists($keys[3], $arr)) $this->setLastname($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setLocale($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setCreatedAt($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setUpdatedAt($arr[$keys[6]]); } /** @@ -969,6 +1172,9 @@ abstract class Newsletter implements ActiveRecordInterface if ($this->isColumnModified(NewsletterTableMap::EMAIL)) $criteria->add(NewsletterTableMap::EMAIL, $this->email); if ($this->isColumnModified(NewsletterTableMap::FIRSTNAME)) $criteria->add(NewsletterTableMap::FIRSTNAME, $this->firstname); if ($this->isColumnModified(NewsletterTableMap::LASTNAME)) $criteria->add(NewsletterTableMap::LASTNAME, $this->lastname); + if ($this->isColumnModified(NewsletterTableMap::LOCALE)) $criteria->add(NewsletterTableMap::LOCALE, $this->locale); + if ($this->isColumnModified(NewsletterTableMap::CREATED_AT)) $criteria->add(NewsletterTableMap::CREATED_AT, $this->created_at); + if ($this->isColumnModified(NewsletterTableMap::UPDATED_AT)) $criteria->add(NewsletterTableMap::UPDATED_AT, $this->updated_at); return $criteria; } @@ -1035,6 +1241,9 @@ abstract class Newsletter implements ActiveRecordInterface $copyObj->setEmail($this->getEmail()); $copyObj->setFirstname($this->getFirstname()); $copyObj->setLastname($this->getLastname()); + $copyObj->setLocale($this->getLocale()); + $copyObj->setCreatedAt($this->getCreatedAt()); + $copyObj->setUpdatedAt($this->getUpdatedAt()); if ($makeNew) { $copyObj->setNew(true); $copyObj->setId(NULL); // this is a auto-increment column, so set to default value @@ -1072,6 +1281,9 @@ abstract class Newsletter implements ActiveRecordInterface $this->email = null; $this->firstname = null; $this->lastname = null; + $this->locale = null; + $this->created_at = null; + $this->updated_at = null; $this->alreadyInSave = false; $this->clearAllReferences(); $this->resetModified(); @@ -1105,6 +1317,20 @@ abstract class Newsletter implements ActiveRecordInterface return (string) $this->exportTo(NewsletterTableMap::DEFAULT_STRING_FORMAT); } + // timestampable behavior + + /** + * Mark the current object so that the update date doesn't get updated during next save + * + * @return ChildNewsletter The current object (for fluent API support) + */ + public function keepUpdateDateUnchanged() + { + $this->modifiedColumns[] = NewsletterTableMap::UPDATED_AT; + + return $this; + } + /** * Code to be run before persisting the object * @param ConnectionInterface $con diff --git a/core/lib/Thelia/Model/Base/NewsletterQuery.php b/core/lib/Thelia/Model/Base/NewsletterQuery.php index 79474e629..ef9ac0a22 100644 --- a/core/lib/Thelia/Model/Base/NewsletterQuery.php +++ b/core/lib/Thelia/Model/Base/NewsletterQuery.php @@ -22,11 +22,17 @@ use Thelia\Model\Map\NewsletterTableMap; * @method ChildNewsletterQuery orderByEmail($order = Criteria::ASC) Order by the email column * @method ChildNewsletterQuery orderByFirstname($order = Criteria::ASC) Order by the firstname column * @method ChildNewsletterQuery orderByLastname($order = Criteria::ASC) Order by the lastname column + * @method ChildNewsletterQuery orderByLocale($order = Criteria::ASC) Order by the locale column + * @method ChildNewsletterQuery orderByCreatedAt($order = Criteria::ASC) Order by the created_at column + * @method ChildNewsletterQuery orderByUpdatedAt($order = Criteria::ASC) Order by the updated_at column * * @method ChildNewsletterQuery groupById() Group by the id column * @method ChildNewsletterQuery groupByEmail() Group by the email column * @method ChildNewsletterQuery groupByFirstname() Group by the firstname column * @method ChildNewsletterQuery groupByLastname() Group by the lastname column + * @method ChildNewsletterQuery groupByLocale() Group by the locale column + * @method ChildNewsletterQuery groupByCreatedAt() Group by the created_at column + * @method ChildNewsletterQuery groupByUpdatedAt() Group by the updated_at column * * @method ChildNewsletterQuery leftJoin($relation) Adds a LEFT JOIN clause to the query * @method ChildNewsletterQuery rightJoin($relation) Adds a RIGHT JOIN clause to the query @@ -39,11 +45,17 @@ use Thelia\Model\Map\NewsletterTableMap; * @method ChildNewsletter findOneByEmail(string $email) Return the first ChildNewsletter filtered by the email column * @method ChildNewsletter findOneByFirstname(string $firstname) Return the first ChildNewsletter filtered by the firstname column * @method ChildNewsletter findOneByLastname(string $lastname) Return the first ChildNewsletter filtered by the lastname column + * @method ChildNewsletter findOneByLocale(string $locale) Return the first ChildNewsletter filtered by the locale column + * @method ChildNewsletter findOneByCreatedAt(string $created_at) Return the first ChildNewsletter filtered by the created_at column + * @method ChildNewsletter findOneByUpdatedAt(string $updated_at) Return the first ChildNewsletter filtered by the updated_at column * * @method array findById(int $id) Return ChildNewsletter objects filtered by the id column * @method array findByEmail(string $email) Return ChildNewsletter objects filtered by the email column * @method array findByFirstname(string $firstname) Return ChildNewsletter objects filtered by the firstname column * @method array findByLastname(string $lastname) Return ChildNewsletter objects filtered by the lastname column + * @method array findByLocale(string $locale) Return ChildNewsletter objects filtered by the locale column + * @method array findByCreatedAt(string $created_at) Return ChildNewsletter objects filtered by the created_at column + * @method array findByUpdatedAt(string $updated_at) Return ChildNewsletter objects filtered by the updated_at column * */ abstract class NewsletterQuery extends ModelCriteria @@ -132,7 +144,7 @@ abstract class NewsletterQuery extends ModelCriteria */ protected function findPkSimple($key, $con) { - $sql = 'SELECT ID, EMAIL, FIRSTNAME, LASTNAME FROM newsletter WHERE ID = :p0'; + $sql = 'SELECT ID, EMAIL, FIRSTNAME, LASTNAME, LOCALE, CREATED_AT, UPDATED_AT FROM newsletter WHERE ID = :p0'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key, PDO::PARAM_INT); @@ -349,6 +361,121 @@ abstract class NewsletterQuery extends ModelCriteria return $this->addUsingAlias(NewsletterTableMap::LASTNAME, $lastname, $comparison); } + /** + * Filter the query on the locale column + * + * Example usage: + * + * $query->filterByLocale('fooValue'); // WHERE locale = 'fooValue' + * $query->filterByLocale('%fooValue%'); // WHERE locale LIKE '%fooValue%' + * + * + * @param string $locale The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildNewsletterQuery The current query, for fluid interface + */ + public function filterByLocale($locale = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($locale)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $locale)) { + $locale = str_replace('*', '%', $locale); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(NewsletterTableMap::LOCALE, $locale, $comparison); + } + + /** + * Filter the query on the created_at column + * + * Example usage: + * + * $query->filterByCreatedAt('2011-03-14'); // WHERE created_at = '2011-03-14' + * $query->filterByCreatedAt('now'); // WHERE created_at = '2011-03-14' + * $query->filterByCreatedAt(array('max' => 'yesterday')); // WHERE created_at > '2011-03-13' + * + * + * @param mixed $createdAt The value to use as filter. + * Values can be integers (unix timestamps), DateTime objects, or strings. + * Empty strings are treated as NULL. + * Use scalar values for equality. + * Use array values for in_array() equivalent. + * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildNewsletterQuery The current query, for fluid interface + */ + public function filterByCreatedAt($createdAt = null, $comparison = null) + { + if (is_array($createdAt)) { + $useMinMax = false; + if (isset($createdAt['min'])) { + $this->addUsingAlias(NewsletterTableMap::CREATED_AT, $createdAt['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($createdAt['max'])) { + $this->addUsingAlias(NewsletterTableMap::CREATED_AT, $createdAt['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(NewsletterTableMap::CREATED_AT, $createdAt, $comparison); + } + + /** + * Filter the query on the updated_at column + * + * Example usage: + * + * $query->filterByUpdatedAt('2011-03-14'); // WHERE updated_at = '2011-03-14' + * $query->filterByUpdatedAt('now'); // WHERE updated_at = '2011-03-14' + * $query->filterByUpdatedAt(array('max' => 'yesterday')); // WHERE updated_at > '2011-03-13' + * + * + * @param mixed $updatedAt The value to use as filter. + * Values can be integers (unix timestamps), DateTime objects, or strings. + * Empty strings are treated as NULL. + * Use scalar values for equality. + * Use array values for in_array() equivalent. + * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildNewsletterQuery The current query, for fluid interface + */ + public function filterByUpdatedAt($updatedAt = null, $comparison = null) + { + if (is_array($updatedAt)) { + $useMinMax = false; + if (isset($updatedAt['min'])) { + $this->addUsingAlias(NewsletterTableMap::UPDATED_AT, $updatedAt['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($updatedAt['max'])) { + $this->addUsingAlias(NewsletterTableMap::UPDATED_AT, $updatedAt['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(NewsletterTableMap::UPDATED_AT, $updatedAt, $comparison); + } + /** * Exclude object from result * @@ -440,4 +567,70 @@ abstract class NewsletterQuery extends ModelCriteria } } + // timestampable behavior + + /** + * Filter by the latest updated + * + * @param int $nbDays Maximum age of the latest update in days + * + * @return ChildNewsletterQuery The current query, for fluid interface + */ + public function recentlyUpdated($nbDays = 7) + { + return $this->addUsingAlias(NewsletterTableMap::UPDATED_AT, time() - $nbDays * 24 * 60 * 60, Criteria::GREATER_EQUAL); + } + + /** + * Filter by the latest created + * + * @param int $nbDays Maximum age of in days + * + * @return ChildNewsletterQuery The current query, for fluid interface + */ + public function recentlyCreated($nbDays = 7) + { + return $this->addUsingAlias(NewsletterTableMap::CREATED_AT, time() - $nbDays * 24 * 60 * 60, Criteria::GREATER_EQUAL); + } + + /** + * Order by update date desc + * + * @return ChildNewsletterQuery The current query, for fluid interface + */ + public function lastUpdatedFirst() + { + return $this->addDescendingOrderByColumn(NewsletterTableMap::UPDATED_AT); + } + + /** + * Order by update date asc + * + * @return ChildNewsletterQuery The current query, for fluid interface + */ + public function firstUpdatedFirst() + { + return $this->addAscendingOrderByColumn(NewsletterTableMap::UPDATED_AT); + } + + /** + * Order by create date desc + * + * @return ChildNewsletterQuery The current query, for fluid interface + */ + public function lastCreatedFirst() + { + return $this->addDescendingOrderByColumn(NewsletterTableMap::CREATED_AT); + } + + /** + * Order by create date asc + * + * @return ChildNewsletterQuery The current query, for fluid interface + */ + public function firstCreatedFirst() + { + return $this->addAscendingOrderByColumn(NewsletterTableMap::CREATED_AT); + } + } // NewsletterQuery diff --git a/core/lib/Thelia/Model/Base/ProductPrice.php b/core/lib/Thelia/Model/Base/ProductPrice.php index 363244e07..e5c5b3f27 100644 --- a/core/lib/Thelia/Model/Base/ProductPrice.php +++ b/core/lib/Thelia/Model/Base/ProductPrice.php @@ -72,19 +72,21 @@ abstract class ProductPrice implements ActiveRecordInterface /** * The value for the price field. + * Note: this column has a database default value of: 0 * @var double */ protected $price; /** * The value for the promo_price field. + * Note: this column has a database default value of: 0 * @var double */ protected $promo_price; /** * The value for the from_default_currency field. - * Note: this column has a database default value of: false + * Note: this column has a database default value of: true * @var boolean */ protected $from_default_currency; @@ -127,7 +129,9 @@ abstract class ProductPrice implements ActiveRecordInterface */ public function applyDefaultValues() { - $this->from_default_currency = false; + $this->price = 0; + $this->promo_price = 0; + $this->from_default_currency = true; } /** @@ -658,7 +662,15 @@ abstract class ProductPrice implements ActiveRecordInterface */ public function hasOnlyDefaultValues() { - if ($this->from_default_currency !== false) { + if ($this->price !== 0) { + return false; + } + + if ($this->promo_price !== 0) { + return false; + } + + if ($this->from_default_currency !== true) { return false; } diff --git a/core/lib/Thelia/Model/Map/NewsletterTableMap.php b/core/lib/Thelia/Model/Map/NewsletterTableMap.php index 1aed936b7..26f02e61e 100644 --- a/core/lib/Thelia/Model/Map/NewsletterTableMap.php +++ b/core/lib/Thelia/Model/Map/NewsletterTableMap.php @@ -57,7 +57,7 @@ class NewsletterTableMap extends TableMap /** * The total number of columns */ - const NUM_COLUMNS = 4; + const NUM_COLUMNS = 7; /** * The number of lazy-loaded columns @@ -67,7 +67,7 @@ class NewsletterTableMap extends TableMap /** * The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */ - const NUM_HYDRATE_COLUMNS = 4; + const NUM_HYDRATE_COLUMNS = 7; /** * the column name for the ID field @@ -89,6 +89,21 @@ class NewsletterTableMap extends TableMap */ const LASTNAME = 'newsletter.LASTNAME'; + /** + * the column name for the LOCALE field + */ + const LOCALE = 'newsletter.LOCALE'; + + /** + * the column name for the CREATED_AT field + */ + const CREATED_AT = 'newsletter.CREATED_AT'; + + /** + * the column name for the UPDATED_AT field + */ + const UPDATED_AT = 'newsletter.UPDATED_AT'; + /** * The default string format for model objects of the related table */ @@ -101,12 +116,12 @@ class NewsletterTableMap extends TableMap * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ protected static $fieldNames = array ( - self::TYPE_PHPNAME => array('Id', 'Email', 'Firstname', 'Lastname', ), - self::TYPE_STUDLYPHPNAME => array('id', 'email', 'firstname', 'lastname', ), - self::TYPE_COLNAME => array(NewsletterTableMap::ID, NewsletterTableMap::EMAIL, NewsletterTableMap::FIRSTNAME, NewsletterTableMap::LASTNAME, ), - self::TYPE_RAW_COLNAME => array('ID', 'EMAIL', 'FIRSTNAME', 'LASTNAME', ), - self::TYPE_FIELDNAME => array('id', 'email', 'firstname', 'lastname', ), - self::TYPE_NUM => array(0, 1, 2, 3, ) + self::TYPE_PHPNAME => array('Id', 'Email', 'Firstname', 'Lastname', 'Locale', 'CreatedAt', 'UpdatedAt', ), + self::TYPE_STUDLYPHPNAME => array('id', 'email', 'firstname', 'lastname', 'locale', 'createdAt', 'updatedAt', ), + self::TYPE_COLNAME => array(NewsletterTableMap::ID, NewsletterTableMap::EMAIL, NewsletterTableMap::FIRSTNAME, NewsletterTableMap::LASTNAME, NewsletterTableMap::LOCALE, NewsletterTableMap::CREATED_AT, NewsletterTableMap::UPDATED_AT, ), + self::TYPE_RAW_COLNAME => array('ID', 'EMAIL', 'FIRSTNAME', 'LASTNAME', 'LOCALE', 'CREATED_AT', 'UPDATED_AT', ), + self::TYPE_FIELDNAME => array('id', 'email', 'firstname', 'lastname', 'locale', 'created_at', 'updated_at', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, ) ); /** @@ -116,12 +131,12 @@ class NewsletterTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'Email' => 1, 'Firstname' => 2, 'Lastname' => 3, ), - self::TYPE_STUDLYPHPNAME => array('id' => 0, 'email' => 1, 'firstname' => 2, 'lastname' => 3, ), - self::TYPE_COLNAME => array(NewsletterTableMap::ID => 0, NewsletterTableMap::EMAIL => 1, NewsletterTableMap::FIRSTNAME => 2, NewsletterTableMap::LASTNAME => 3, ), - self::TYPE_RAW_COLNAME => array('ID' => 0, 'EMAIL' => 1, 'FIRSTNAME' => 2, 'LASTNAME' => 3, ), - self::TYPE_FIELDNAME => array('id' => 0, 'email' => 1, 'firstname' => 2, 'lastname' => 3, ), - self::TYPE_NUM => array(0, 1, 2, 3, ) + self::TYPE_PHPNAME => array('Id' => 0, 'Email' => 1, 'Firstname' => 2, 'Lastname' => 3, 'Locale' => 4, 'CreatedAt' => 5, 'UpdatedAt' => 6, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'email' => 1, 'firstname' => 2, 'lastname' => 3, 'locale' => 4, 'createdAt' => 5, 'updatedAt' => 6, ), + self::TYPE_COLNAME => array(NewsletterTableMap::ID => 0, NewsletterTableMap::EMAIL => 1, NewsletterTableMap::FIRSTNAME => 2, NewsletterTableMap::LASTNAME => 3, NewsletterTableMap::LOCALE => 4, NewsletterTableMap::CREATED_AT => 5, NewsletterTableMap::UPDATED_AT => 6, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'EMAIL' => 1, 'FIRSTNAME' => 2, 'LASTNAME' => 3, 'LOCALE' => 4, 'CREATED_AT' => 5, 'UPDATED_AT' => 6, ), + self::TYPE_FIELDNAME => array('id' => 0, 'email' => 1, 'firstname' => 2, 'lastname' => 3, 'locale' => 4, 'created_at' => 5, 'updated_at' => 6, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, ) ); /** @@ -144,6 +159,9 @@ class NewsletterTableMap extends TableMap $this->addColumn('EMAIL', 'Email', 'VARCHAR', true, 255, null); $this->addColumn('FIRSTNAME', 'Firstname', 'VARCHAR', false, 255, null); $this->addColumn('LASTNAME', 'Lastname', 'VARCHAR', false, 255, null); + $this->addColumn('LOCALE', 'Locale', 'VARCHAR', false, 5, null); + $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); + $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); } // initialize() /** @@ -153,6 +171,19 @@ class NewsletterTableMap extends TableMap { } // buildRelations() + /** + * + * Gets the list of behaviors registered for this table + * + * @return array Associative array (name => parameters) of behaviors + */ + public function getBehaviors() + { + return array( + 'timestampable' => array('create_column' => 'created_at', 'update_column' => 'updated_at', ), + ); + } // getBehaviors() + /** * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. * @@ -295,11 +326,17 @@ class NewsletterTableMap extends TableMap $criteria->addSelectColumn(NewsletterTableMap::EMAIL); $criteria->addSelectColumn(NewsletterTableMap::FIRSTNAME); $criteria->addSelectColumn(NewsletterTableMap::LASTNAME); + $criteria->addSelectColumn(NewsletterTableMap::LOCALE); + $criteria->addSelectColumn(NewsletterTableMap::CREATED_AT); + $criteria->addSelectColumn(NewsletterTableMap::UPDATED_AT); } else { $criteria->addSelectColumn($alias . '.ID'); $criteria->addSelectColumn($alias . '.EMAIL'); $criteria->addSelectColumn($alias . '.FIRSTNAME'); $criteria->addSelectColumn($alias . '.LASTNAME'); + $criteria->addSelectColumn($alias . '.LOCALE'); + $criteria->addSelectColumn($alias . '.CREATED_AT'); + $criteria->addSelectColumn($alias . '.UPDATED_AT'); } } diff --git a/core/lib/Thelia/Model/Map/ProductPriceTableMap.php b/core/lib/Thelia/Model/Map/ProductPriceTableMap.php index 7a80d2e12..81eed9609 100644 --- a/core/lib/Thelia/Model/Map/ProductPriceTableMap.php +++ b/core/lib/Thelia/Model/Map/ProductPriceTableMap.php @@ -157,9 +157,9 @@ class ProductPriceTableMap extends TableMap // columns $this->addForeignPrimaryKey('PRODUCT_SALE_ELEMENTS_ID', 'ProductSaleElementsId', 'INTEGER' , 'product_sale_elements', 'ID', true, null, null); $this->addForeignPrimaryKey('CURRENCY_ID', 'CurrencyId', 'INTEGER' , 'currency', 'ID', true, null, null); - $this->addColumn('PRICE', 'Price', 'FLOAT', true, null, null); - $this->addColumn('PROMO_PRICE', 'PromoPrice', 'FLOAT', false, null, null); - $this->addColumn('FROM_DEFAULT_CURRENCY', 'FromDefaultCurrency', 'BOOLEAN', true, 1, false); + $this->addColumn('PRICE', 'Price', 'FLOAT', true, null, 0); + $this->addColumn('PROMO_PRICE', 'PromoPrice', 'FLOAT', true, null, 0); + $this->addColumn('FROM_DEFAULT_CURRENCY', 'FromDefaultCurrency', 'BOOLEAN', true, 1, true); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); } // initialize() diff --git a/core/lib/Thelia/Model/OrderQuery.php b/core/lib/Thelia/Model/OrderQuery.php index 8d5e4c085..0fff5dba1 100755 --- a/core/lib/Thelia/Model/OrderQuery.php +++ b/core/lib/Thelia/Model/OrderQuery.php @@ -2,6 +2,7 @@ namespace Thelia\Model; +use Propel\Runtime\ActiveQuery\Criteria; use Propel\Runtime\Exception\PropelException; use Propel\Runtime\Propel; use Thelia\Model\Base\OrderQuery as BaseOrderQuery; @@ -52,4 +53,5 @@ class OrderQuery extends BaseOrderQuery return $obj; } + } // OrderQuery diff --git a/core/lib/Thelia/Model/Product.php b/core/lib/Thelia/Model/Product.php index 5ec2abf4c..f16a8a776 100755 --- a/core/lib/Thelia/Model/Product.php +++ b/core/lib/Thelia/Model/Product.php @@ -41,11 +41,16 @@ class Product extends BaseProduct return $amount; } - public function getTaxedPrice(Country $country) + public function getTaxedPrice(Country $country, $price) { $taxCalculator = new Calculator(); + return round($taxCalculator->load($this, $country)->getTaxedPrice($price), 2); + } - return $taxCalculator->load($this, $country)->getTaxedPrice($this->getRealLowestPrice()); + public function getTaxedPromoPrice(Country $country, $price) + { + $taxCalculator = new Calculator(); + return round($taxCalculator->load($this, $country)->getTaxedPrice($price), 2); } /** @@ -192,6 +197,7 @@ class Product extends BaseProduct ->setNewness(0) ->setWeight($weight) ->setIsDefault($isDefault) + ->setEanCode('') ->save($con) ; diff --git a/core/lib/Thelia/Module/BaseModule.php b/core/lib/Thelia/Module/BaseModule.php index 79acdd4b3..15853a398 100755 --- a/core/lib/Thelia/Module/BaseModule.php +++ b/core/lib/Thelia/Module/BaseModule.php @@ -142,13 +142,12 @@ abstract class BaseModule extends ContainerAware } catch (\UnexpectedValueException $e) { throw $e; } - if(null === $con) { + if (null === $con) { $con = \Propel\Runtime\Propel::getConnection( ModuleImageTableMap::DATABASE_NAME ); } - /* browse the directory */ $imagePosition = 1; foreach ($directoryBrowser as $directoryContent) { diff --git a/core/lib/Thelia/Tests/Core/Template/Smarty/Plugins/FormatTest.php b/core/lib/Thelia/Tests/Core/Template/Smarty/Plugins/FormatTest.php index e8d5ff0fc..979642677 100644 --- a/core/lib/Thelia/Tests/Core/Template/Smarty/Plugins/FormatTest.php +++ b/core/lib/Thelia/Tests/Core/Template/Smarty/Plugins/FormatTest.php @@ -155,7 +155,6 @@ class FormatTest extends \PHPUnit_Framework_TestCase * test formatDate without mandatory parameters * * @covers ::formatDate - * @expectedException \Thelia\Core\Template\Smarty\Exception\SmartyPluginException */ public function testFormatDateWithoutDate() { @@ -165,20 +164,21 @@ class FormatTest extends \PHPUnit_Framework_TestCase $render = $formatClass->formatDate(array()); - $this->assertEquals($dateTime->format("Y-m-d H:i:s"), $render); + $this->assertEmpty($render); } /** * test formatNumber without mandatory parameters * * @covers ::formatNumber - * @expectedException \Thelia\Core\Template\Smarty\Exception\SmartyPluginException */ public function testFormatNumberWithoutParams() { $formatClass = new Format($this->request); $render = $formatClass->formatNumber(array()); + + $this->assertEmpty($render); } /** diff --git a/core/lib/Thelia/Tests/Coupon/CouponFactoryTest.php b/core/lib/Thelia/Tests/Coupon/CouponFactoryTest.php deleted file mode 100644 index 648dbcd19..000000000 --- a/core/lib/Thelia/Tests/Coupon/CouponFactoryTest.php +++ /dev/null @@ -1,48 +0,0 @@ -. */ -/* */ -/**********************************************************************************/ - -namespace Thelia\Coupon; - -require_once 'CouponManagerTest.php'; - -/** - * Created by JetBrains PhpStorm. - * Date: 8/19/13 - * Time: 3:24 PM - * - * Unit Test CouponFactory Class - * - * @package Coupon - * @author Guillaume MOREL - * - */ -class CouponFactoryTest extends \PHPUnit_Framework_TestCase -{ - public function testSomething() - { - // Stop here and mark this test as incomplete. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } -} diff --git a/core/lib/Thelia/Tests/Coupon/CouponRuleCollectionTest.php b/core/lib/Thelia/Tests/Coupon/CouponRuleCollectionTest.php deleted file mode 100644 index 0745e9b98..000000000 --- a/core/lib/Thelia/Tests/Coupon/CouponRuleCollectionTest.php +++ /dev/null @@ -1,46 +0,0 @@ -. */ -/* */ -/**********************************************************************************/ - -namespace Thelia\Coupon; - -/** - * Created by JetBrains PhpStorm. - * Date: 8/19/13 - * Time: 3:24 PM - * - * Unit Test ConditionCollection Class - * - * @package Coupon - * @author Guillaume MOREL - * - */ -class CouponRuleCollectionTest extends \PHPUnit_Framework_TestCase -{ - public function testSomething() - { - // Stop here and mark this test as incomplete. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } -} diff --git a/core/lib/Thelia/Tests/Coupon/RuleOrganizerTest.php b/core/lib/Thelia/Tests/Coupon/RuleOrganizerTest.php deleted file mode 100644 index d13184a8c..000000000 --- a/core/lib/Thelia/Tests/Coupon/RuleOrganizerTest.php +++ /dev/null @@ -1,73 +0,0 @@ -. */ -/* */ -/**********************************************************************************/ - -namespace Thelia\Coupon; - -use Thelia\Coupon\RuleOrganizer; -/** - * Created by JetBrains PhpStorm. - * Date: 8/19/13 - * Time: 3:24 PM - * - * Unit Test RuleOrganizer Class - * - * @package Coupon - * @author Guillaume MOREL - * - */ -class RuleOrganizerTest extends \PHPUnit_Framework_TestCase -{ - /** - * @var RuleOrganizer - */ - protected $object; - - /** - * Sets up the fixture, for example, opens a network connection. - * This method is called before a test is executed. - */ - protected function setUp() - { - $this->object = new RuleOrganizer(); - } - - /** - * Tears down the fixture, for example, closes a network connection. - * This method is called after a test is executed. - */ - protected function tearDown() - { - } - - /** - * @covers Thelia\Coupon\RuleOrganizer::organize - * @todo Implement testOrganize(). - */ - public function testOrganize() - { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet.' - ); - } -} diff --git a/core/lib/Thelia/Tests/Coupon/Type/RemoveXAmountTest.php b/core/lib/Thelia/Tests/Coupon/Type/RemoveXAmountTest.php deleted file mode 100644 index ee8ed3068..000000000 --- a/core/lib/Thelia/Tests/Coupon/Type/RemoveXAmountTest.php +++ /dev/null @@ -1,65 +0,0 @@ -. */ -/* */ -/**********************************************************************************/ - -namespace Thelia\Coupon; - - -//require_once '../CouponManagerTest.php'; - -/** - * Created by JetBrains PhpStorm. - * Date: 8/19/13 - * Time: 3:24 PM - * - * Unit Test RemoveXAmount Class - * - * @package Coupon - * @author Guillaume MOREL - * - */ -class RemoveXAmountTest extends \PHPUnit_Framework_TestCase -{ - /** - * Sets up the fixture, for example, opens a network connection. - * This method is called before a test is executed. - */ - protected function setUp() - { - } - - public function testSomething() - { - // Stop here and mark this test as incomplete. - $this->markTestIncomplete( - 'This coupon has not been implemented yet.' - ); - } - - /** - * Tears down the fixture, for example, closes a network connection. - * This method is called after a test is executed. - */ - protected function tearDown() - { - } -} diff --git a/core/lib/Thelia/Tests/Coupon/Type/RemoveXPercentTest.php b/core/lib/Thelia/Tests/Coupon/Type/RemoveXPercentTest.php deleted file mode 100644 index bbb0c24a3..000000000 --- a/core/lib/Thelia/Tests/Coupon/Type/RemoveXPercentTest.php +++ /dev/null @@ -1,67 +0,0 @@ -. */ -/* */ -/**********************************************************************************/ - -namespace Thelia\Coupon; - -use PHPUnit_Framework_TestCase; - -//require_once '../CouponManagerTest.php'; - -/** - * Created by JetBrains PhpStorm. - * Date: 8/19/13 - * Time: 3:24 PM - * - * Unit Test RemoveXPercent Class - * - * @package Coupon - * @author Guillaume MOREL - * - */ -class RemoveXPercentTest extends \PHPUnit_Framework_TestCase -{ - - /** - * Sets up the fixture, for example, opens a network connection. - * This method is called before a test is executed. - */ - protected function setUp() - { - } - - public function testSomething() - { - $this->markTestIncomplete( - 'This coupon has not been implemented yet.' - ); - } - - /** - * Tears down the fixture, for example, closes a network connection. - * This method is called after a test is executed. - */ - protected function tearDown() - { - } - -} diff --git a/core/lib/Thelia/Tests/Tools/FileManagerTest.php b/core/lib/Thelia/Tests/Tools/FileManagerTest.php index 3ad898ef2..ea8588b19 100644 --- a/core/lib/Thelia/Tests/Tools/FileManagerTest.php +++ b/core/lib/Thelia/Tests/Tools/FileManagerTest.php @@ -30,7 +30,7 @@ class FileManagerTest extends \PHPUnit_Framework_TestCase /** * @covers Thelia\Tools\FileManager::copyUploadedFile */ - public function testCopyUploadedFile() +/* public function testCopyUploadedFile() { $this->markTestIncomplete( 'This test has not been implemented yet : Mock issue' @@ -103,13 +103,13 @@ class FileManagerTest extends \PHPUnit_Framework_TestCase $actual = $fileManager->copyUploadedFile(24, FileManager::TYPE_PRODUCT, $stubProductImage, $stubUploadedFile, $newUploadedFiles, FileManager::FILE_TYPE_IMAGES); $this->assertCount(1, $actual); - } + }*/ /** * @covers Thelia\Tools\FileManager::copyUploadedFile * @expectedException \Thelia\Exception\ImageException */ - public function testCopyUploadedFileExceptionImageException() + /*public function testCopyUploadedFileExceptionImageException() { $this->markTestIncomplete( 'This test has not been implemented yet : Mock issue' @@ -181,7 +181,7 @@ class FileManagerTest extends \PHPUnit_Framework_TestCase $actual = $fileManager->copyUploadedFile(24, FileManager::TYPE_PRODUCT, $stubProductImage, $stubUploadedFile, $newUploadedFiles, FileManager::FILE_TYPE_DOCUMENTS); - } + }*/ /** * @covers Thelia\Tools\FileManager::saveImage @@ -650,23 +650,23 @@ class FileManagerTest extends \PHPUnit_Framework_TestCase /** * @covers Thelia\Tools\FileManager::getImageForm */ - public function testGetImageForm() +/* public function testGetImageForm() { // Mock issue $this->markTestIncomplete( 'This test has not been implemented yet.' ); - } + }*/ /** * @covers Thelia\Tools\FileManager::getDocumentForm */ - public function testGetDocumentForm() +/* public function testGetDocumentForm() { // Mock issue $this->markTestIncomplete( 'This test has not been implemented yet.' ); - } + }*/ /** * @covers Thelia\Tools\FileManager::getUploadDir @@ -879,21 +879,21 @@ class FileManagerTest extends \PHPUnit_Framework_TestCase /** * @covers Thelia\Tools\FileManager::adminLogAppend */ - public function testAdminLogAppend() +/* public function testAdminLogAppend() { $this->markTestIncomplete( 'This test has not been implemented yet.' ); - } + }*/ /** * @covers Thelia\Tools\FileManager::deleteFile */ - public function testDeleteFile() + /* public function testDeleteFile() { // @todo see http://tech.vg.no/2011/03/09/mocking-the-file-system-using-phpunit-and-vfsstream/ $this->markTestIncomplete( 'This test has not been implemented yet.' ); - } + }*/ } diff --git a/core/lib/Thelia/Tools/NumberFormat.php b/core/lib/Thelia/Tools/NumberFormat.php index 2c49a2751..ae25404d7 100644 --- a/core/lib/Thelia/Tools/NumberFormat.php +++ b/core/lib/Thelia/Tools/NumberFormat.php @@ -46,7 +46,6 @@ class NumberFormat if ($decimals == null) $decimals = $lang->getDecimals(); if ($decPoint == null) $decPoint = $lang->getDecimalSeparator(); if ($thousandsSep == null) $thousandsSep = $lang->getThousandsSeparator(); - return number_format($number, $decimals, $decPoint, $thousandsSep); } -} \ No newline at end of file +} diff --git a/core/lib/Thelia/Type/BaseType.php b/core/lib/Thelia/Type/BaseType.php index 9beb180e7..79a859632 100644 --- a/core/lib/Thelia/Type/BaseType.php +++ b/core/lib/Thelia/Type/BaseType.php @@ -39,7 +39,7 @@ abstract class BaseType implements TypeInterface public function verifyForm($value, ExecutionContextInterface $context) { - if( ! $this->isValid($value) ) { + if ( ! $this->isValid($value) ) { $context->addViolation(sprintf("received value `%s` does not match `%s` type", $value, $this->getType())); } } diff --git a/core/lib/Thelia/Type/ModelValidIdType.php b/core/lib/Thelia/Type/ModelValidIdType.php index a9bfec7b5..b3579a51a 100755 --- a/core/lib/Thelia/Type/ModelValidIdType.php +++ b/core/lib/Thelia/Type/ModelValidIdType.php @@ -78,7 +78,7 @@ class ModelValidIdType extends BaseType $queryClass = $this->expectedModelActiveRecordQuery; $choices = array(); - foreach($queryClass::create()->find() as $item) { + foreach ($queryClass::create()->find() as $item) { $choices[$item->getId()] = method_exists($item, "getTitle") ? $item->getTitle() : $item->getId(); } diff --git a/install/faker.php b/install/faker.php index 60bc2bb81..d834e294c 100755 --- a/install/faker.php +++ b/install/faker.php @@ -426,6 +426,7 @@ try { $stock->setNewness($faker->randomNumber(0,1)); $stock->setWeight($faker->randomFloat(2, 100,10000)); $stock->setIsDefault($i == 0); + $stock->setEanCode(substr(str_shuffle("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 13)); $stock->save(); $productPrice = new \Thelia\Model\ProductPrice(); diff --git a/install/insert.sql b/install/insert.sql index bf9022df4..63eb5829e 100755 --- a/install/insert.sql +++ b/install/insert.sql @@ -30,7 +30,13 @@ INSERT INTO `config` (`name`, `value`, `secured`, `hidden`, `created_at`, `updat ('session_config.handlers', 'Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NativeFileSessionHandler', 0, 0, NOW(), NOW()), ('company_name','', 0, 0, NOW(), NOW()), ('contact_email','', 0, 0, NOW(), NOW()), +('url_site','', 0, 0, NOW(), NOW()), ('one_domain_foreach_lang','0', 1, 1, NOW(), NOW()) +('thelia_version','2.0.0-beta1', 1, 1, NOW(), NOW()) +('thelia_major_version','2', 1, 1, NOW(), NOW()) +('thelia_minus_version','0', 1, 1, NOW(), NOW()) +('thelia_release_version','0', 1, 1, NOW(), NOW()) +('thelia_extra_version','beta1', 1, 1, NOW(), NOW()) ; @@ -1273,3 +1279,12 @@ INSERT INTO resource_i18n (`id`, `locale`, `title`) VALUES (22, 'fr_FR', 'Configuration / Tax'), (23, 'en_US', 'Configuration / Template'), (23, 'fr_FR', 'Configuration / Template'); + + +INSERT INTO `message` (`id`, `name`, `secured`, `created_at`, `updated_at`, `version`, `version_created_at`, `version_created_by`) VALUES +(1, 'order_confirmation', NULL, NOW(), NOW(), 2, NOW(), NULL); + +INSERT INTO `message_i18n` (`id`, `locale`, `title`, `subject`, `text_message`, `html_message`) VALUES +(1, 'en_US', 'order confirmation', 'Commande : Commande : {$order_ref}', '{assign var="order_id" value=1}\r\n\r\n{loop name="order.invoice" type="order" id=$order_id customer="*"}\r\n {loop name="currency.order" type="currency" id=$CURRENCY}\r\n {assign "orderCurrency" $CODE}\r\n {/loop}\r\n{loop type="order_address" name="delivery_address" id=$INVOICE_ADDRESS}\r\n{loop type="title" name="order-invoice-address-title" id=$TITLE}{$LONG}{/loop}{$FIRSTNAME} {$LASTNAME}\\r\\n\r\n{$ADDRESS1} {$ADDRESS2} {$ADDRESS3}\\r\\n\r\n{$ZIPCODE} {$CITY}\\r\\n\r\n{loop type="country" name="country_delivery" id=$COUNTRY}{$TITLE}{/loop}\\r\\n\r\n{/loop}\r\nConfirmation de commande {$REF} du {format_date date=$INVOICE_DATE}\\r\\n\\r\\n\r\nLes articles commandés:\\r\\n\r\n{loop type="order_product" name="order-products" order=$ID}\r\n{if $WAS_IN_PROMO == 1}\r\n {assign "realPrice" $PROMO_PRICE}\r\n {assign "realTax" $PROMO_PRICE_TAX}\r\n {assign "realTaxedPrice" $TAXED_PROMO_PRICE}\r\n{else}\r\n {assign "realPrice" $PRICE}\r\n {assign "realTax" $PRICE_TAX}\r\n {assign "realTaxedPrice" $TAXED_PRICE}\r\n{/if}\r\n \\r\\n\r\n Article : {$TITLE}\r\n{ifloop rel="combinations"}\r\n {loop type="order_product_attribute_combination" name="combinations" order_product=$ID}\r\n {$ATTRIBUTE_TITLE} - {$ATTRIBUTE_AVAILABILITY_TITLE}\\r\\n\r\n{/loop}\r\n{/ifloop}\\r\\n\r\n Quantité : {$QUANTITY}\\r\\n\r\n Prix unitaire TTC : {$realTaxedPrice} {$orderCurrency}\\r\\n\r\n{/loop}\r\n\\r\\n-----------------------------------------\\r\\n\r\nMontant total TTC : {$TOTAL_TAXED_AMOUNT - $POSTAGE} {$orderCurrency} \\r\\n\r\nFrais de port TTC : {$POSTAGE} {$orderCurrency} \\r\\n\r\nSomme totale: {$TOTAL_TAXED_AMOUNT} {$orderCurrency} \\r\\n\r\n==================================\\r\\n\\r\\n\r\nVotre facture est disponible dans la rubrique mon compte sur {config key="url_site"}\r\n{/loop}', '{loop name="order.invoice" type="order" id=$order_id customer="*"}\r\n {loop name="currency.order" type="currency" id=$CURRENCY}\r\n {assign "orderCurrency" $SYMBOL}\r\n {/loop}\r\n{loop type="customer" name="customer.invoice" id=$CUSTOMER current="0"}\r\n {assign var="customer_ref" value=$REF}\r\n{/loop}\r\n\r\n\r\n\r\n \r\n courriel de confirmation de commande de {config key="url_site"} \r\n {literal}\r\n \r\n {/literal}\r\n\r\n\r\n
\r\n

{config key="company_name"}

\r\n

Confirmation de commande

\r\n

N° {$REF} du {format_date date=$INVOICE_DATE output="date"}

\r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {loop type="order_product" name="order-products" order=$ID}\r\n {if $WAS_IN_PROMO == 1}\r\n {assign "realPrice" $PROMO_PRICE}\r\n {assign "realTax" $PROMO_PRICE_TAX}\r\n {assign "realTaxedPrice" $TAXED_PROMO_PRICE}\r\n {else}\r\n {assign "realPrice" $PRICE}\r\n {assign "realTax" $PRICE_TAX}\r\n {assign "realTaxedPrice" $TAXED_PRICE}\r\n {/if}\r\n \r\n \r\n \r\n \r\n \r\n \r\n {/loop}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
RéférenceDésignationP.U. €Qté
{$REF}{$TITLE}\r\n {ifloop rel="combinations"}\r\n {loop type="order_product_attribute_combination" name="combinations" order_product=$ID}\r\n {$ATTRIBUTE_TITLE} - {$ATTRIBUTE_AVAILABILITY_TITLE}
\r\n {/loop}\r\n {/ifloop}\r\n
{$orderCurrency} {$realTaxedPrice}{$QUANTITY}
 
Montant total avant remise €{$orderCurrency} {$TOTAL_TAXED_AMOUNT - $POSTAGE}
Port €{$orderCurrency} {$POSTAGE}
Montant total de la commande €{$orderCurrency} {$TOTAL_TAXED_AMOUNT}
\r\n
\r\n

LIVRAISON : {loop name="delivery-module" type="module" id=$DELIVERY_MODULE}{$TITLE}{/loop}

\r\n {loop type="order_address" name="delivery_address" id=$INVOICE_ADDRESS}\r\n

N° de client : {$customer_ref}

\r\n

Nom :\r\n {loop type="title" name="order-invoice-address-title" id=$TITLE}{$LONG}{/loop} {$FIRSTNAME} {$LASTNAME}

\r\n

N° et rue :\r\n {$ADDRESS1}

\r\n

Complément : {$ADDRESS2}\r\n {$ADDRESS3}

\r\n

Code postal : {$ZIPCODE}

\r\n

Ville : {$CITY}

\r\n

Pays : {loop type="country" name="country_delivery" id=$COUNTRY}{$TITLE}{/loop}

\r\n
\r\n {/loop}\r\n
\r\n

FACTURATION : paiement par {loop name="payment-module" type="module" id=$PAYMENT_MODULE}{$TITLE}{/loop}

\r\n {loop type="order_address" name="delivery_address" id=$DELIVERY_ADDRESS}\r\n

N° de client : {$customer_ref}

\r\n

Nom :\r\n {loop type="title" name="order-invoice-address-title" id=$TITLE}{$LONG}{/loop} {$FIRSTNAME} {$LASTNAME}

\r\n

N° et rue :\r\n {$ADDRESS1}

\r\n

Complément : {$ADDRESS2}\r\n {$ADDRESS3}

\r\n

Code postal : {$ZIPCODE}

\r\n

Ville : {$CITY}

\r\n

Pays : {loop type="country" name="country_delivery" id=$COUNTRY}{$TITLE}{/loop}

\r\n
\r\n {/loop}\r\n

Le suivi de votre commande est disponible dans la rubrique mon compte sur {config key="url_site"}

\r\n
\r\n\r\n\r\n{/loop}'), +(1, 'fr_FR', 'order confirmation', 'Commande : {$order_ref}', '{assign var="order_id" value=1}\r\n\r\n{loop name="order.invoice" type="order" id=$order_id customer="*"}\r\n {loop name="currency.order" type="currency" id=$CURRENCY}\r\n {assign "orderCurrency" $CODE}\r\n {/loop}\r\n{loop type="order_address" name="delivery_address" id=$INVOICE_ADDRESS}\r\n{loop type="title" name="order-invoice-address-title" id=$TITLE}{$LONG}{/loop}{$FIRSTNAME} {$LASTNAME}\\r\\n\r\n{$ADDRESS1} {$ADDRESS2} {$ADDRESS3}\\r\\n\r\n{$ZIPCODE} {$CITY}\\r\\n\r\n{loop type="country" name="country_delivery" id=$COUNTRY}{$TITLE}{/loop}\\r\\n\r\n{/loop}\r\nConfirmation de commande {$REF} du {format_date date=$INVOICE_DATE}\\r\\n\\r\\n\r\nLes articles commandés:\\r\\n\r\n{loop type="order_product" name="order-products" order=$ID}\r\n{if $WAS_IN_PROMO == 1}\r\n {assign "realPrice" $PROMO_PRICE}\r\n {assign "realTax" $PROMO_PRICE_TAX}\r\n {assign "realTaxedPrice" $TAXED_PROMO_PRICE}\r\n{else}\r\n {assign "realPrice" $PRICE}\r\n {assign "realTax" $PRICE_TAX}\r\n {assign "realTaxedPrice" $TAXED_PRICE}\r\n{/if}\r\n \\r\\n\r\n Article : {$TITLE}\r\n{ifloop rel="combinations"}\r\n {loop type="order_product_attribute_combination" name="combinations" order_product=$ID}\r\n {$ATTRIBUTE_TITLE} - {$ATTRIBUTE_AVAILABILITY_TITLE}\\r\\n\r\n{/loop}\r\n{/ifloop}\\r\\n\r\n Quantité : {$QUANTITY}\\r\\n\r\n Prix unitaire TTC : {$realTaxedPrice} {$orderCurrency}\\r\\n\r\n{/loop}\r\n\\r\\n-----------------------------------------\\r\\n\r\nMontant total TTC : {$TOTAL_TAXED_AMOUNT - $POSTAGE} {$orderCurrency} \\r\\n\r\nFrais de port TTC : {$POSTAGE} {$orderCurrency} \\r\\n\r\nSomme totale: {$TOTAL_TAXED_AMOUNT} {$orderCurrency} \\r\\n\r\n==================================\\r\\n\\r\\n\r\nVotre facture est disponible dans la rubrique mon compte sur {config key="url_site"}\r\n{/loop}', '{loop name="order.invoice" type="order" id=$order_id customer="*"}\r\n {loop name="currency.order" type="currency" id=$CURRENCY}\r\n {assign "orderCurrency" $SYMBOL}\r\n {/loop}\r\n{loop type="customer" name="customer.invoice" id=$CUSTOMER current="0"}\r\n {assign var="customer_ref" value=$REF}\r\n{/loop}\r\n\r\n\r\n\r\n \r\n courriel de confirmation de commande de {config key="url_site"} \r\n {literal}\r\n \r\n {/literal}\r\n\r\n\r\n
\r\n

{config key="company_name"}

\r\n

Confirmation de commande

\r\n

N° {$REF} du {format_date date=$INVOICE_DATE output="date"}

\r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {loop type="order_product" name="order-products" order=$ID}\r\n {if $WAS_IN_PROMO == 1}\r\n {assign "realPrice" $PROMO_PRICE}\r\n {assign "realTax" $PROMO_PRICE_TAX}\r\n {assign "realTaxedPrice" $TAXED_PROMO_PRICE}\r\n {else}\r\n {assign "realPrice" $PRICE}\r\n {assign "realTax" $PRICE_TAX}\r\n {assign "realTaxedPrice" $TAXED_PRICE}\r\n {/if}\r\n \r\n \r\n \r\n \r\n \r\n \r\n {/loop}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
RéférenceDésignationP.U. €Qté
{$REF}{$TITLE}\r\n {ifloop rel="combinations"}\r\n {loop type="order_product_attribute_combination" name="combinations" order_product=$ID}\r\n {$ATTRIBUTE_TITLE} - {$ATTRIBUTE_AVAILABILITY_TITLE}
\r\n {/loop}\r\n {/ifloop}\r\n
{$orderCurrency} {$realTaxedPrice}{$QUANTITY}
 
Montant total avant remise €{$orderCurrency} {$TOTAL_TAXED_AMOUNT - $POSTAGE}
Port €{$orderCurrency} {$POSTAGE}
Montant total de la commande €{$orderCurrency} {$TOTAL_TAXED_AMOUNT}
\r\n
\r\n

LIVRAISON : {loop name="delivery-module" type="module" id=$DELIVERY_MODULE}{$TITLE}{/loop}

\r\n {loop type="order_address" name="delivery_address" id=$INVOICE_ADDRESS}\r\n

N° de client : {$customer_ref}

\r\n

Nom :\r\n {loop type="title" name="order-invoice-address-title" id=$TITLE}{$LONG}{/loop} {$FIRSTNAME} {$LASTNAME}

\r\n

N° et rue :\r\n {$ADDRESS1}

\r\n

Complément : {$ADDRESS2}\r\n {$ADDRESS3}

\r\n

Code postal : {$ZIPCODE}

\r\n

Ville : {$CITY}

\r\n

Pays : {loop type="country" name="country_delivery" id=$COUNTRY}{$TITLE}{/loop}

\r\n
\r\n {/loop}\r\n
\r\n

FACTURATION : paiement par {loop name="payment-module" type="module" id=$PAYMENT_MODULE}{$TITLE}{/loop}

\r\n {loop type="order_address" name="delivery_address" id=$DELIVERY_ADDRESS}\r\n

N° de client : {$customer_ref}

\r\n

Nom :\r\n {loop type="title" name="order-invoice-address-title" id=$TITLE}{$LONG}{/loop} {$FIRSTNAME} {$LASTNAME}

\r\n

N° et rue :\r\n {$ADDRESS1}

\r\n

Complément : {$ADDRESS2}\r\n {$ADDRESS3}

\r\n

Code postal : {$ZIPCODE}

\r\n

Ville : {$CITY}

\r\n

Pays : {loop type="country" name="country_delivery" id=$COUNTRY}{$TITLE}{/loop}

\r\n
\r\n {/loop}\r\n

Le suivi de votre commande est disponible dans la rubrique mon compte sur {config key="url_site"}

\r\n
\r\n\r\n\r\n{/loop}'); + diff --git a/install/thelia.sql b/install/thelia.sql index 32f6e5e6f..79163345b 100755 --- a/install/thelia.sql +++ b/install/thelia.sql @@ -1270,9 +1270,9 @@ CREATE TABLE `product_price` ( `product_sale_elements_id` INTEGER NOT NULL, `currency_id` INTEGER NOT NULL, - `price` FLOAT NOT NULL, - `promo_price` FLOAT, - `from_default_currency` TINYINT(1) DEFAULT 0 NOT NULL, + `price` FLOAT DEFAULT 0 NOT NULL, + `promo_price` FLOAT DEFAULT 0 NOT NULL, + `from_default_currency` TINYINT(1) DEFAULT 1 NOT NULL, `created_at` DATETIME, `updated_at` DATETIME, PRIMARY KEY (`product_sale_elements_id`,`currency_id`), @@ -1607,7 +1607,11 @@ CREATE TABLE `newsletter` `email` VARCHAR(255) NOT NULL, `firstname` VARCHAR(255), `lastname` VARCHAR(255), - PRIMARY KEY (`id`) + `locale` VARCHAR(5), + `created_at` DATETIME, + `updated_at` DATETIME, + PRIMARY KEY (`id`), + UNIQUE INDEX `email_UNIQUE` (`email`) ) ENGINE=InnoDB; -- --------------------------------------------------------------------- diff --git a/local/config/schema.xml b/local/config/schema.xml index 5f81a7ba0..ba19efee0 100755 --- a/local/config/schema.xml +++ b/local/config/schema.xml @@ -1,1254 +1,1259 @@ - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - -
- - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - -
- - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - -
- - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - -
- - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
- - - - - - - - -
- - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
- - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - -
- - - - - -
-
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + +
+ + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
diff --git a/templates/admin/default/configuration.html b/templates/admin/default/configuration.html index 14f195270..4c6acd1db 100644 --- a/templates/admin/default/configuration.html +++ b/templates/admin/default/configuration.html @@ -151,7 +151,7 @@ {/loop} - {loop type="auth" name="pcc6" role="ADMIN" resource="admin.configuration.mailing-system" access="VIEW"} +{* {loop type="auth" name="pcc6" role="ADMIN" resource="admin.configuration.mailing-system" access="VIEW"} {intl l='Mailing system'} @@ -170,7 +170,7 @@ {intl l='System logs'} - {/loop} + {/loop}*} {module_include location='system_configuration_bottom'} diff --git a/templates/admin/default/coupon/form.html b/templates/admin/default/coupon/form.html index 5e132b5cc..d2642657f 100644 --- a/templates/admin/default/coupon/form.html +++ b/templates/admin/default/coupon/form.html @@ -107,7 +107,7 @@ {loop name="tax" type="tax-rule" backend_context="1"} - + {/loop} @@ -115,7 +115,7 @@
@@ -129,19 +129,21 @@
- + {$currency_symbol}
{/form_field} -
- -
- - {$currency_symbol} -
-
+ {form_field form=$form field='price_with_tax'} +
+ +
+ + {$currency_symbol} +
+
+ {/form_field} {module_include location='product_details_pricing_form'} @@ -203,19 +205,21 @@
- + {$currency_symbol}
{/form_field} + {form_field form=$form field='sale_price_with_tax'}
- +
- + {$currency_symbol}
+ {/form_field} {form_field form=$form field='onsale'}
@@ -253,37 +257,79 @@ {form name="thelia.admin.product_sale_element.update"}
+
+
-
-
+ {include + file = "includes/inner-form-toolbar.html" + hide_submit_buttons = false + show_currencies = true + page_url = "{url path='/admin/products/update' product_id=$ID}" + close_url = "{url path='/admin/categories' category_id=$DEFAULT_CATEGORY}" + } - {include - file = "includes/inner-form-toolbar.html" - hide_submit_buttons = false - show_currencies = true - page_url = "{url path='/admin/products/update' product_id=$ID}" - close_url = "{url path='/admin/categories' category_id=$DEFAULT_CATEGORY}" - } + {* Be sure to get the product ID, even if the form could not be validated *} + - {if $form_error}
{$form_error_message}
{/if} + -
-
- {form_field form=$form field='tax_rule'} -
- -
- -
-
- {/form_field} -
-
+ {form_hidden_fields form=$form} + + {form_field form=$form field='product_id'} + + {/form_field} + + {form_field form=$form field='success_url'} + + {/form_field} + + {if $form_error}
{$form_error_message}
{/if} + + {loop type="currency" name="get-currency-symbol" id=$edit_currency_id backend_context="1"} + {$currency_symbol = $SYMBOL} + {$current_currency_is_default = $IS_DEFAULT} + + {form_field form=$form field='currency'} + + {/form_field} + {/loop} + +
+
+ {form_field form=$form field='tax_rule'} +
+ +
+ +
+
+ {/form_field} +
+
+ {form_field form=$form field='use_exchange_rate'} + {if $current_currency_is_default} + + {$show_pricing_fields = true} + {else} +
+ +
+ +
+
+ {$show_pricing_fields = ($value == 0)} + {/if} + {/form_field} +
+
{module_include location='product_before_combinations'} @@ -294,6 +340,9 @@ {module_include location='product_combinations_list_caption'} {loop type="auth" name="can_create" role="ADMIN" resource="admin.product" access="UPDATE"} + + {intl l='Combination builder'} + @@ -318,43 +367,91 @@ - {loop name="product.sales.elements" type="product_sale_elements" product=$product_id currency=$edit_currency_id backend_context="1"} + {* Get number of PSE defined, assumin the form have the same number of values for each fields *} + + {form_field form=$form field='product_sale_element_id' value_key=0} + {$pse_count = $total_value_count} + {/form_field} + + {for $idx = 0 to $total_value_count-1} - {$ID}: {loop name="product.sales.elements.combinations" type="attribute_combination" product_sale_elements=$ID backend_context="1"} - {if $LOOP_COUNT > 1} - {/if}{$ATTRIBUTE_TITLE} - {/loop} + + {form_field form=$form field='product_sale_element_id' value_key=$idx} + + + {$current_pse_id = $value} + + {$current_pse_id}: {loop name="product.sales.elements.combinations" type="attribute_combination" product_sale_elements=$current_pse_id backend_context="1"} + {if $LOOP_COUNT > 1} - {/if}{$ATTRIBUTE_TITLE} + {/loop} + {/form_field} - - - - - - - + + {form_field form=$form field='reference' value_key=$idx} + + {/form_field} - - + {form_field form=$form field='ean_code' value_key=$idx} + + {/form_field} + + {form_field form=$form field='quantity' value_key=$idx} + + + {/form_field} - - - + {form_field form=$form field='price' value_key=$idx} + + {/form_field} - - - + {form_field form=$form field='price_with_tax' value_key=$idx} + + {/form_field} - - + {form_field form=$form field='weight' value_key=$idx} + + {/form_field} - - - - - {/loop} + + {form_field form=$form field='default_pse'} + + + + {/form_field} + + {form_field form=$form field='onsale' value_key=$idx} + + + + {/form_field} + + {form_field form=$form field='isnew' value_key=$idx} + + + + {/form_field} + + {form_field form=$form field='sale_price' value_key=$idx} + + + + {/form_field} + + {form_field form=$form field='sale_price_with_tax' value_key=$idx} + + + + {/form_field} + + + + + + {/for} diff --git a/templates/admin/default/modules.html b/templates/admin/default/modules.html index e6c6eb669..ca94be812 100644 --- a/templates/admin/default/modules.html +++ b/templates/admin/default/modules.html @@ -15,11 +15,11 @@
  • {intl l="Home"}
  • {intl l="Modules"}
  • - {loop type="auth" name="can_create" role="ADMIN" resource="admin.module" access="UPDATE"} +{* {loop type="auth" name="can_create" role="ADMIN" resource="admin.module" access="UPDATE"} {intl l="Install a new module"} - {/loop} + {/loop}*}
    {module_include location='modules_top'} diff --git a/templates/admin/default/product-edit.html b/templates/admin/default/product-edit.html index 2a2d94ca8..446e1fd7f 100644 --- a/templates/admin/default/product-edit.html +++ b/templates/admin/default/product-edit.html @@ -275,48 +275,84 @@ $(function() { }); // In details tab, process exchange rate usage checkbox changes - $('use_exchange_rate_box').change(function(ev) { - $('.') + $('.use_exchange_rate_box').change(function(ev) { + + if ($(this).is(':checked')) { + + var pse_id = $(this).data('pse-id'); + + $('.price_field').prop('readonly', true); + + // Reload prices + $.ajax({ + url : '{url path="/admin/product/load-converted-prices"}', + data : { + product_sale_element_id : pse_id, + currency_id : {$edit_currency_id} + }, + type : 'get', + dataType : 'json', + success : function(json) { + console.log(json); + + $('input[data-pse-id="'+pse_id+'"][data-price-type="price-with-tax"]').val(json.price_with_tax); + $('input[data-pse-id="'+pse_id+'"][data-price-type="price-without-tax"]').val(json.price_without_tax); + $('input[data-pse-id="'+pse_id+'"][data-price-type="sale-price-with-tax"]').val(json.sale_price_with_tax); + $('input[data-pse-id="'+pse_id+'"][data-price-type="sale-price-without-tax"]').val(json.sale_price_without_tax); + }, + error : function(jqXHR, textStatus, errorThrown) { + alert("{intl l='Failed to get converted prices. Please try again.'} (" +errorThrown+ ")"); + } + }); + + } + else { + $('.price_field').prop('readonly', false) + } }); + function update_price(price, price_type, dest_field_id) { + var tax_rule_id = $('#tax_rule_field').val(); + + if (tax_rule_id != "") { + + var operation; + + if (price_type.indexOf('with-tax') != -1) + operation = 'from_tax'; + else if (price_type.indexOf('without-tax') != -1) + operation = 'to_tax'; + else + operation = ''; + + $.ajax({ + url : '{url path="/admin/product/calculate-price"}', + data : { + price : price, + action : operation, + product_id : {$product_id} + }, + type : 'get', + dataType : 'json', + success : function(json) { + $('#' + dest_field_id).val(json.result); + }, + error : function(jqXHR, textStatus, errorThrown) { + alert("{intl l='Failed to get prices. Please try again.'} (" +errorThrown+ ")"); + } + }); + } + } + // Automatic update of price fields: any change in the taxed (resp. untaxed) price // will update the untaxed (resp. taxed) one $('.automatic_price_field').typeWatch({ captureLength: 1, - callback: function () { - - var tax_rule_id = $('#tax_rule_field').val(); - - if (tax_rule_id != "") { - var priceType = $(this).data('price-type'); - var dest_field_id = $(this).data('rel-price'); - - var operation; - - if (priceType == 'with-tax') - operation = 'from_tax'; - else if (priceType == 'without-tax') - operation = 'to_tax'; - else - operation = ''; - - $.ajax({ - url : '{url path="/admin/product/calculate-price"}', - data : { - price : $(this).val(), - action : operation, - tax_rule_id : $('#tax_rule_field').val() - }, - type : 'get', - dataType : 'json', - success : function(json) { - $('#' + dest_field_id).val(json.result); - } - }); - } + wait : 300, + callback : function () { + update_price($(this).val(), $(this).data('price-type'), $(this).data('rel-price')); } }); - }); diff --git a/templates/admin/default/search.html b/templates/admin/default/search.html new file mode 100644 index 000000000..a39eda982 --- /dev/null +++ b/templates/admin/default/search.html @@ -0,0 +1,238 @@ +{extends file="admin-layout.tpl"} + +{block name="page-title"}{intl l='Modules'}{/block} + +{block name="check-resource"}admin.configuration.search{/block} +{block name="check-access"}view{/block} + +{block name="main-content"} +
    + +
    + + + + {module_include location='modules_top'} + +
    +
    + + {* customer search *} +
    +
    + + + + + + + + + + + + + + + + + + + + {loop name="customer_list" type="customer" current="false" visible="*" backend_context="1" search_term=$smarty.get.search_term search_in="ref,firstname,lastname,email"} + {assign "lastOrderDate" ''} + {assign "lastOrderAmount" ''} + {assign "lastOrderCurrency" ''} + + {loop type="order" name="last-order" customer=$ID order="create-date-reverse" limit="1"} + {assign "lastOrderDate" "{format_date date=$CREATE_DATE}"} + {assign "lastOrderAmount" "{format_number number=$TOTAL_TAXED_AMOUNT}"} + {loop type="currency" name="order-currency" id=$CURRENCY} + {assign "lastOrderCurrency" $SYMBOL} + {/loop} + {/loop} + + + + + + + + + {module_include location='customer_list_row'} + + + + + + + + {/loop} + +
    + {intl l='Customer'} +
    + {intl l="customer ref"} + + {intl l="company"} + + {intl l="firstname & lastname"} + + {intl l="last order"} + {intl l='order amount'}{intl l="Actions"}
    {$REF} + {$COMPANY} + + {$FIRSTNAME} {$LASTNAME} + + {$lastOrderDate} + + {$lastOrderCurrency} {$lastOrderAmount} + +
    + + {loop type="auth" name="can_change" role="ADMIN" resource="admin.customer" access="UPDATE"} + + {/loop} + {loop type="auth" name="can_send_mail" role="ADMIN" resource="admin.customer" access="VIEW"} + + {/loop} + {loop type="auth" name="can_delete" role="ADMIN" resource="admin.customer" access="DELETE"} + + {/loop} +
    +
    +
    +
    + {* end customer search *} + + {* order search *} +
    +
    + + + + + + + + + + + + + + + + + {loop type="order" name="order-search" backend_context=1 customer="*" search_term=$smarty.get.search_term search_in="ref,customer_ref,customer_firstname,customer_lastname,customer_email"} + {loop type="order_address" name="order-invoice-address" id=$INVOICE_ADDRESS} + {assign "orderInvoiceFirstName" $FIRSTNAME} + {assign "orderInvoiceLastName" $LASTNAME} + {assign "orderInvoiceCompany" $COMPANY} + {/loop} + + {loop type="order-status" name="order-status" id=$STATUS} + {assign "orderStatus" $TITLE} + {assign "orderStatusLabel" "order_$CODE"} + {/loop} + + + + + + + + + + + + + {/loop} + +
    + {intl l='Orders'} +
    {intl l="Order n°"}{intl l="Date & Hour"}{intl l="Company"}{intl l="Name"}{intl l="Amount"}{intl l="Status"}{intl l="Actions"}
    {$REF}{format_date date=$CREATE_DATE}{$orderInvoiceCompany}{$orderInvoiceFirstName|ucwords} {$orderInvoiceLastName|upper}{$TOTAL_TAXED_AMOUNT}{$orderStatus} +
    + + {loop type="auth" name="can_change" role="ADMIN" resource="admin.order" access="UPDATE"} + + {/loop} +
    +
    +
    +
    + {* end order search *} + + {* product search *} +
    +
    + + + + + + + + + + + + + + + {loop type="product" name="product-search" visible="*" search_mode="sentence" search_term=$smarty.get.search_term search_in="ref,title"} + + + + + + + + + + + + + {/loop} + +
    + {intl l='Product'} +
    {intl l="ID"}{intl l="Reference"}{intl l="Product title"}{intl l="Actions"}
    {$ID} + {loop type="image" name="cat_image" source="product" source_id="$ID" limit="1" width="50" height="50" resize_mode="crop" backend_context="1"} + + {$TITLE} + + {/loop} + + {$REF}{$TITLE} +
    + {loop type="auth" name="can_change" role="ADMIN" resource="admin.product" access="UPDATE"} + + {/loop} +
    +
    +
    +
    + {* end product search *} + +
    +
    + + {module_include location='modules_bottom'} + +
    +
    + +{/block} + +{block name="javascript-initialization"} + + + +{/block} \ No newline at end of file diff --git a/templates/default/account.html b/templates/default/account.html index 100080768..9e9c82369 100644 --- a/templates/default/account.html +++ b/templates/default/account.html @@ -25,7 +25,7 @@ @@ -118,7 +118,7 @@ @@ -154,9 +154,9 @@ {loop type="order" name="customer.orders"} {$REF} - {format_date date=$CREATED_AT} - {loop type="currency" name="order.currency" id={$CURRENCY}}{$SYMBOL}{/loop} {format_number number=$TOTAL} - {$STATUS} + {format_date date=$CREATE_DATE} + {loop type="currency" name="order.currency" id={$CURRENCY}}{$SYMBOL}{/loop} {format_number number=$TOTAL_TAXED_AMOUNT} + {loop type="order-status" name="order.status" id={$STATUS}}{$TITLE}{/loop} {intl l="Order details"} {/loop} diff --git a/templates/default/cart.html b/templates/default/cart.html index d1bbee0a8..00689bd3e 100644 --- a/templates/default/cart.html +++ b/templates/default/cart.html @@ -70,7 +70,7 @@ {/elseloop} -

    +

    {$TITLE}

    diff --git a/templates/default/includes/single-product.html b/templates/default/includes/single-product.html index bbc9b9d68..dd4137a69 100644 --- a/templates/default/includes/single-product.html +++ b/templates/default/includes/single-product.html @@ -17,9 +17,7 @@ {loop name="product_thumbnail" type="image" product=$ID width="{$width}" height="{$height}" resize_mode="borders" limit="1"} Product #{$LOOP_COUNT} {/loop} - {elseloop rel="product_thumbnail"} - {images file="../assets/img/{$width}x{$height}.png"}Product #{$LOOP_COUNT}{/images} - {/elseloop} + diff --git a/templates/default/layout.tpl b/templates/default/layout.tpl index a2d8904fd..2c485b0a2 100644 --- a/templates/default/layout.tpl +++ b/templates/default/layout.tpl @@ -24,6 +24,7 @@ GNU General Public License : http://www.gnu.org/licenses/ + {* Test if javascript is enabled *} @@ -160,7 +161,7 @@ GNU General Public License : http://www.gnu.org/licenses/ {lang attr="title"}
    @@ -170,7 +171,7 @@ GNU General Public License : http://www.gnu.org/licenses/ {currency attr="code"}

    diff --git a/templates/default/order-invoice.html b/templates/default/order-invoice.html index 68868b0cb..f3bb5d36d 100644 --- a/templates/default/order-invoice.html +++ b/templates/default/order-invoice.html @@ -72,12 +72,11 @@ {loop type="cart" name="cartloop"} - {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"} - Product #{$cart_count} + Product #{$cart_count} {/loop} {/ifloop} {elseloop rel="product-image"} diff --git a/templates/default/search.html b/templates/default/search.html index 179396b2c..7c8e212b4 100644 --- a/templates/default/search.html +++ b/templates/default/search.html @@ -26,7 +26,7 @@ {ifloop rel="product_list"}
      {loop type="product" name="product_list" title="{$smarty.get.q}" limit=$limit page=$product_page order=$product_order} - {include file="includes/single-product.html" product_id=$ID hasBtn=true hasDescription=true width="218" height="146"} + {include file="includes/single-product.html" product_id=$ID hasBtn=true hasDescription=true width="369" height="247"} {assign "products_count" $LOOP_TOTAL} {/loop}
    diff --git a/templates/pdf/invoice.html b/templates/pdf/invoice.html index 22e6d2760..828b5786c 100644 --- a/templates/pdf/invoice.html +++ b/templates/pdf/invoice.html @@ -91,7 +91,7 @@ {loop type="order_address" name="delivery_address" id=$DELIVERY_ADDRESS} {loop type="title" name="order-invoice-address-title" id=$TITLE}{$LONG}{/loop}{$FIRSTNAME} {$LASTNAME}
    {$ADDRESS1} {$ADDRESS2} {$ADDRESS3}
    - {$ZIPCODE} {$COUNTRY}
    + {$ZIPCODE} {$CITY}
    {loop type="country" name="country_delivery" id=$COUNTRY}{$TITLE}{/loop} {/loop} @@ -108,7 +108,7 @@ {loop type="order_address" name="delivery_address" id=$INVOICE_ADDRESS} {loop type="title" name="order-invoice-address-title" id=$TITLE}{$LONG}{/loop}{$FIRSTNAME} {$LASTNAME}
    {$ADDRESS1} {$ADDRESS2} {$ADDRESS3}
    - {$ZIPCODE} {$COUNTRY}
    + {$ZIPCODE} {$CITY}
    {loop type="country" name="country_delivery" id=$COUNTRY}{$TITLE}{/loop} {/loop} diff --git a/web/install/config.php b/web/install/config.php index ca937286c..f4e3c9896 100755 --- a/web/install/config.php +++ b/web/install/config.php @@ -96,6 +96,10 @@ $_SESSION['install']['step'] = $step;
    +
    + + +
    diff --git a/web/install/end.php b/web/install/end.php index 9113a8786..e10a18cb6 100755 --- a/web/install/end.php +++ b/web/install/end.php @@ -43,6 +43,10 @@ if($_SESSION['install']['step'] == 5) { \Thelia\Model\ConfigQuery::create() ->filterByName('company_name') ->update(array('Value' => $_POST['company_name'])); + + \Thelia\Model\ConfigQuery::create() + ->filterByName('url_site') + ->update(array('Value' => $_POST['url_site'])); } //clean up cache directories diff --git a/web/phpinfo.php b/web/phpinfo.php deleted file mode 100644 index e657e53d7..000000000 --- a/web/phpinfo.php +++ /dev/null @@ -1,10 +0,0 @@ - - */ - -phpinfo(); \ No newline at end of file