From 3e301a9fc15ca63ea7c06f8b75a21470d24bd847 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Wed, 11 Sep 2013 18:57:49 +0200 Subject: [PATCH 01/45] creating account page --- .../Thelia/Config/Resources/routing/front.xml | 32 ++-- templates/default/account.html | 175 ++++++++++++++++++ .../pictures/screenshot-category-rule.png | Bin 0 -> 582 bytes 3 files changed, 195 insertions(+), 12 deletions(-) create mode 100644 templates/default/account.html create mode 100644 tests/functionnal/casperjs/pictures/screenshot-category-rule.png diff --git a/core/lib/Thelia/Config/Resources/routing/front.xml b/core/lib/Thelia/Config/Resources/routing/front.xml index e83dd7f07..49713b938 100755 --- a/core/lib/Thelia/Config/Resources/routing/front.xml +++ b/core/lib/Thelia/Config/Resources/routing/front.xml @@ -10,15 +10,31 @@ + + Thelia\Controller\Front\DefaultController::noAction + register + + + + + Thelia\Controller\Front\DefaultController::noAction + login + + + + Thelia\Controller\Front\CustomerController::logoutAction + + + + Thelia\Controller\Front\DefaultController::noAction + account + + Thelia\Controller\Front\CustomerController::createAction register - - Thelia\Controller\Front\DefaultController::noAction - register - Thelia\Controller\Front\CustomerController::updateAction @@ -29,14 +45,6 @@ login - - Thelia\Controller\Front\DefaultController::noAction - login - - - - Thelia\Controller\Front\CustomerController::logoutAction - Thelia\Controller\Front\DefaultController::noAction diff --git a/templates/default/account.html b/templates/default/account.html new file mode 100644 index 000000000..c7edeb449 --- /dev/null +++ b/templates/default/account.html @@ -0,0 +1,175 @@ +{extends file="layout.tpl"} + +{block name="breadcrumb"} + +{/block} + +{block name="main-content"} +
+ +
+ +

{intl l="My Account"}

+ +
+ + + +
+
+ +
+ +{/block} \ No newline at end of file diff --git a/tests/functionnal/casperjs/pictures/screenshot-category-rule.png b/tests/functionnal/casperjs/pictures/screenshot-category-rule.png new file mode 100644 index 0000000000000000000000000000000000000000..0c25491786ee26b02396f8b7e13e75950829169a GIT binary patch literal 582 zcmeAS@N?(olHy`uVBq!ia0y~yV4MKNIvi|3k+<8Q9s*J<#ZI0f96(URkl Date: Wed, 11 Sep 2013 19:01:23 +0200 Subject: [PATCH 02/45] tax engine --- core/lib/Thelia/Model/Tax.php | 6 +- core/lib/Thelia/TaxEngine/Calculator.php | 26 ++-- .../TaxEngine/TaxType/FixAmountTaxType.php | 45 +++++++ install/tax_faker.php | 116 ++++++++++++++++++ 4 files changed, 183 insertions(+), 10 deletions(-) create mode 100755 core/lib/Thelia/TaxEngine/TaxType/FixAmountTaxType.php create mode 100755 install/tax_faker.php diff --git a/core/lib/Thelia/Model/Tax.php b/core/lib/Thelia/Model/Tax.php index 738f16508..7b9b22b6f 100755 --- a/core/lib/Thelia/Model/Tax.php +++ b/core/lib/Thelia/Model/Tax.php @@ -40,13 +40,13 @@ class Tax extends BaseTax /* test type */ if(!class_exists($class)) { - throw new TaxEngineException('Recorded type does not exists', TaxEngineException::BAD_RECORDED_TYPE); + throw new TaxEngineException('Recorded type `' . $class . '` does not exists', TaxEngineException::BAD_RECORDED_TYPE); } $instance = new $class; if(!$instance instanceof BaseTaxType) { - throw new TaxEngineException('Recorded type does not extends BaseTaxType', TaxEngineException::BAD_RECORDED_TYPE); + throw new TaxEngineException('Recorded type `' . $class . '` does not extends BaseTaxType', TaxEngineException::BAD_RECORDED_TYPE); } return $instance; @@ -54,7 +54,7 @@ class Tax extends BaseTax public function setRequirements($requirements) { - parent::setSerializedRequirements(base64_encode(json_encode($requirements))); + return parent::setSerializedRequirements(base64_encode(json_encode($requirements))); } public function getRequirements() diff --git a/core/lib/Thelia/TaxEngine/Calculator.php b/core/lib/Thelia/TaxEngine/Calculator.php index 2708e88c6..f49498263 100755 --- a/core/lib/Thelia/TaxEngine/Calculator.php +++ b/core/lib/Thelia/TaxEngine/Calculator.php @@ -39,6 +39,9 @@ class Calculator */ protected $taxRuleQuery = null; + /** + * @var null|\Propel\Runtime\Collection\ObjectCollection + */ protected $taxRulesCollection = null; protected $product = null; @@ -80,19 +83,28 @@ class Calculator throw new TaxEngineException('BAD AMOUNT FORMAT', TaxEngineException::BAD_AMOUNT_FORMAT); } - $totalTaxAmount = 0; + $taxedPrice = $untaxedPrice; + $currentPosition = 1; + $currentTax = 0; + foreach($this->taxRulesCollection as $taxRule) { + $position = (int)$taxRule->getTaxRuleCountryPosition(); + $taxType = $taxRule->getTypeInstance(); + $taxType->loadRequirements( $taxRule->getRequirements() ); - $taxType->loadRequirements($taxRule->getRequirements()); + if($currentPosition !== $position) { + $taxedPrice += $currentTax; + $currentTax = 0; + $currentPosition = $position; + } - $taxAmount = $taxType->calculate($untaxedPrice); - - $totalTaxAmount += $taxAmount; - $untaxedPrice += $taxAmount; + $currentTax += $taxType->calculate($taxedPrice); } - return $totalTaxAmount; + $taxedPrice += $currentTax; + + return $taxedPrice; } public function getTaxedPrice($untaxedPrice) diff --git a/core/lib/Thelia/TaxEngine/TaxType/FixAmountTaxType.php b/core/lib/Thelia/TaxEngine/TaxType/FixAmountTaxType.php new file mode 100755 index 000000000..c533d0ec3 --- /dev/null +++ b/core/lib/Thelia/TaxEngine/TaxType/FixAmountTaxType.php @@ -0,0 +1,45 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\TaxEngine\TaxType; + +use Thelia\Type\FloatType; + +/** + * + * @author Etienne Roudeix + * + */ +class FixAmountTaxType extends BaseTaxType +{ + public function calculate($untaxedPrice) + { + return $this->getRequirement("amount"); + } + + public function getRequirementsList() + { + return array( + 'amount' => new FloatType(), + ); + } +} diff --git a/install/tax_faker.php b/install/tax_faker.php new file mode 100755 index 000000000..5d534e2ef --- /dev/null +++ b/install/tax_faker.php @@ -0,0 +1,116 @@ +boot(); + +$faker = Faker\Factory::create(); + +$con = \Propel\Runtime\Propel::getConnection( + Thelia\Model\Map\ProductTableMap::DATABASE_NAME +); +$con->beginTransaction(); + +$currency = \Thelia\Model\CurrencyQuery::create()->filterByCode('EUR')->findOne(); + +try { + $stmt = $con->prepare("SET foreign_key_checks = 0"); + $stmt->execute(); + + \Thelia\Model\TaxQuery::create() + ->find() + ->delete(); + + \Thelia\Model\Base\TaxRuleQuery::create() + ->find() + ->delete(); + + \Thelia\Model\Base\TaxRuleCountryQuery::create() + ->find() + ->delete(); + + $stmt = $con->prepare("SET foreign_key_checks = 1"); + $stmt->execute(); + + /* 10% tax */ + $tax10p = new \Thelia\Model\Tax(); + $tax10p->setType('PricePercentTaxType') + ->setRequirements(array('percent' => 10)) + ->save(); + + /* 8% tax */ + $tax8p = new \Thelia\Model\Tax(); + $tax8p->setType('PricePercentTaxType') + ->setRequirements(array('percent' => 8)) + ->save(); + + /* fix 5 tax */ + $tax5 = new \Thelia\Model\Tax(); + $tax5->setType('FixAmountTaxType') + ->setRequirements(array('amount' => 5)) + ->save(); + + /* 1% tax */ + $tax1p = new \Thelia\Model\Tax(); + $tax1p->setType('PricePercentTaxType') + ->setRequirements(array('percent' => 1)) + ->save(); + + /* tax rule */ + $taxRule = new \Thelia\Model\TaxRule(); + $taxRule->save(); + + /* add 4 taxes to the rule for France (64) */ + $taxRuleCountry = new \Thelia\Model\TaxRuleCountry(); + $taxRuleCountry->setTaxRule($taxRule) + ->setCountryId(64) + ->setTax($tax10p) + ->setPosition(1) + ->save(); + + $taxRuleCountry = new \Thelia\Model\TaxRuleCountry(); + $taxRuleCountry->setTaxRule($taxRule) + ->setCountryId(64) + ->setTax($tax8p) + ->setPosition(1) + ->save(); + + $taxRuleCountry = new \Thelia\Model\TaxRuleCountry(); + $taxRuleCountry->setTaxRule($taxRule) + ->setCountryId(64) + ->setTax($tax5) + ->setPosition(2) + ->save(); + + $taxRuleCountry = new \Thelia\Model\TaxRuleCountry(); + $taxRuleCountry->setTaxRule($taxRule) + ->setCountryId(64) + ->setTax($tax1p) + ->setPosition(3) + ->save(); + + foreach(\Thelia\Model\ProductQuery::create()->find() as $productActiveRecord) { + $productActiveRecord->setTaxRule($taxRule) + ->save(); + } + + $con->commit(); + +} catch (Exception $e) { + echo "error : ".$e->getMessage()."\n"; + $con->rollBack(); +} From c35de47f10a649601974739d6e4f1d5ad592ded3 Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Wed, 11 Sep 2013 20:18:34 +0200 Subject: [PATCH 03/45] fix taxengine tests --- core/lib/Thelia/TaxEngine/Calculator.php | 10 ++--- .../Thelia/Tests/TaxEngine/CalculatorTest.php | 42 ++++++++++++++++++- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/core/lib/Thelia/TaxEngine/Calculator.php b/core/lib/Thelia/TaxEngine/Calculator.php index f49498263..f8c527cd1 100755 --- a/core/lib/Thelia/TaxEngine/Calculator.php +++ b/core/lib/Thelia/TaxEngine/Calculator.php @@ -74,6 +74,11 @@ class Calculator } public function getTaxAmount($untaxedPrice) + { + return $this->getTaxedPrice($untaxedPrice) - $untaxedPrice; + } + + public function getTaxedPrice($untaxedPrice) { if(null === $this->taxRulesCollection) { throw new TaxEngineException('Tax rules collection is empty in Calculator::getTaxAmount', TaxEngineException::UNDEFINED_TAX_RULES_COLLECTION); @@ -106,9 +111,4 @@ class Calculator return $taxedPrice; } - - public function getTaxedPrice($untaxedPrice) - { - return $untaxedPrice + $this->getTaxAmount($untaxedPrice); - } } diff --git a/core/lib/Thelia/Tests/TaxEngine/CalculatorTest.php b/core/lib/Thelia/Tests/TaxEngine/CalculatorTest.php index 719d90835..165d5d517 100755 --- a/core/lib/Thelia/Tests/TaxEngine/CalculatorTest.php +++ b/core/lib/Thelia/Tests/TaxEngine/CalculatorTest.php @@ -136,18 +136,21 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase public function testGetTaxAmountAndGetTaxedPrice() { + /* consecutives taxes */ $taxRulesCollection = new ObjectCollection(); $taxRulesCollection->setModel('\Thelia\Model\Tax'); $tax = new Tax(); $tax->setType('PricePercentTaxType') - ->setRequirements(array('percent' => 10)); + ->setRequirements(array('percent' => 10)) + ->setVirtualColumn('taxRuleCountryPosition', 1); $taxRulesCollection->append($tax); $tax = new Tax(); $tax->setType('PricePercentTaxType') - ->setRequirements(array('percent' => 8)); + ->setRequirements(array('percent' => 8)) + ->setVirtualColumn('taxRuleCountryPosition', 2); $taxRulesCollection->append($tax); @@ -167,5 +170,40 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase */ $this->assertEquals(94, $taxAmount); $this->assertEquals(594, $taxedPrice); + + /* same position taxes */ + $taxRulesCollection = new ObjectCollection(); + $taxRulesCollection->setModel('\Thelia\Model\Tax'); + + $tax = new Tax(); + $tax->setType('PricePercentTaxType') + ->setRequirements(array('percent' => 10)) + ->setVirtualColumn('taxRuleCountryPosition', 1); + + $taxRulesCollection->append($tax); + + $tax = new Tax(); + $tax->setType('PricePercentTaxType') + ->setRequirements(array('percent' => 8)) + ->setVirtualColumn('taxRuleCountryPosition', 1); + + $taxRulesCollection->append($tax); + + $calculator = new Calculator(); + + $rewritingUrlQuery = $this->getProperty('taxRulesCollection'); + $rewritingUrlQuery->setValue($calculator, $taxRulesCollection); + + $taxAmount = $calculator->getTaxAmount(500); + $taxedPrice = $calculator->getTaxedPrice(500); + + /* + * expect : + * tax 1 = 500*0.10 = 50 // amout with tax 1 : 550 + * tax 2 = 500*0.08 = 40 // amout with tax 2 : 590 + * total tax amount = 90 + */ + $this->assertEquals(90, $taxAmount); + $this->assertEquals(590, $taxedPrice); } } From e8ced10dbb68f1c416ee14bf05629c2b48599c8a Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Wed, 11 Sep 2013 20:22:29 +0200 Subject: [PATCH 04/45] fix template --- templates/default_save/product.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/default_save/product.html b/templates/default_save/product.html index cde8b61eb..eec6f770b 100755 --- a/templates/default_save/product.html +++ b/templates/default_save/product.html @@ -68,7 +68,7 @@ Index : {navigate to="index"}
{$ATTRIBUTE_TITLE} = {$ATTRIBUTE_AVAILABILITY_TITLE}
{/loop}
{$WEIGHT} g -
{if $IS_PROMO == 1} {$PROMO_PRICE} {currency attr="symbol"} HT // TAX : {$PROMO_PRICE_TAX} ; {$TAXED_PROMO_PRICE} {currency attr="symbol"} TTC (instead of {$PRICE_HT} // TAX : {$PRICE_TAX} ; {$TAXED_PRICE} {currency attr="symbol"} TTC){else} {$PRICE} {currency attr="symbol"} HT // TAX : {$PRICE_TAX} ; {$TAXED_PRICE} {currency attr="symbol"} TTC{/if} +
{if $IS_PROMO == 1} {$PROMO_PRICE} {currency attr="symbol"} HT // TAX : {$PROMO_PRICE_TAX} ; {$TAXED_PROMO_PRICE} {currency attr="symbol"} TTC (instead of {$PRICE} HT // TAX : {$PRICE_TAX} ; {$TAXED_PRICE} {currency attr="symbol"} TTC){else} {$PRICE} {currency attr="symbol"} HT // TAX : {$PRICE_TAX} ; {$TAXED_PRICE} {currency attr="symbol"} TTC{/if}

Add - {loop type="title" name="title1"} - + {loop type="title" name="title1" backend_context="1"} + {/loop} @@ -143,67 +143,20 @@ + {loop name="address" type="address" customer="$customer_id" backend_context="1" default="0"}
- Twitter, Inc.
- 795 Folsom Ave, Suite 600
- San Francisco, CA 94107
- P: (123) 456-7890 -
- - -
- - - - - - - - - - - - - -
- - - - -
- Twitter, Inc.
- 795 Folsom Ave, Suite 600
- San Francisco, CA 94107
- P: (123) 456-7890 -
- - -
- - - - - - - - - - - - - -
- - - - -
- Twitter, Inc.
- 795 Folsom Ave, Suite 600
- San Francisco, CA 94107
- P: (123) 456-7890 + {loop name="address.title" type="title" id=$TITLE}{$SHORT}{/loop} {$FIRSTNAME} {$LASTNAME}
+ {$ADDRESS1}
+ {$ADDRESS2}
+ {$ADDRESS3}
+ {if $PHONE} + P: {$PHONE}
+ {/if} + {if $CELLPHONE} + P: {$CELLPHONE} + {/if}
@@ -224,6 +177,7 @@ + {/loop} From 6b9db1a162b07338f1109caa9d33378aa01042d3 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Thu, 12 Sep 2013 09:23:50 +0200 Subject: [PATCH 07/45] create test for customer creation --- core/lib/Thelia/Action/Customer.php | 3 +- .../Controller/Front/CustomerController.php | 3 +- .../Event/CustomerCreateOrUpdateEvent.php | 20 +++- core/lib/Thelia/Model/Customer.php | 4 +- core/lib/Thelia/Tests/Action/CustomerTest.php | 102 ++++++++++++++++++ 5 files changed, 124 insertions(+), 8 deletions(-) create mode 100644 core/lib/Thelia/Tests/Action/CustomerTest.php diff --git a/core/lib/Thelia/Action/Customer.php b/core/lib/Thelia/Action/Customer.php index 1b3ac6909..8dd2eebee 100755 --- a/core/lib/Thelia/Action/Customer.php +++ b/core/lib/Thelia/Action/Customer.php @@ -80,7 +80,8 @@ class Customer extends BaseAction implements EventSubscriberInterface $event->getLang(), $event->getReseller(), $event->getSponsor(), - $event->getDiscount() + $event->getDiscount(), + $event->getCompany() ); $event->setCustomer($customer); diff --git a/core/lib/Thelia/Controller/Front/CustomerController.php b/core/lib/Thelia/Controller/Front/CustomerController.php index a0fd74abc..3b8c2ccff 100755 --- a/core/lib/Thelia/Controller/Front/CustomerController.php +++ b/core/lib/Thelia/Controller/Front/CustomerController.php @@ -278,7 +278,8 @@ class CustomerController extends BaseFrontController $this->getRequest()->getSession()->getLang()->getId(), isset($data["reseller"])?$data["reseller"]:null, isset($data["sponsor"])?$data["sponsor"]:null, - isset($data["discount"])?$data["discount"]:null + isset($data["discount"])?$data["discount"]:null, + isset($data["company"])?$data["company"]:null ); return $customerCreateEvent; diff --git a/core/lib/Thelia/Core/Event/CustomerCreateOrUpdateEvent.php b/core/lib/Thelia/Core/Event/CustomerCreateOrUpdateEvent.php index 3a57d53a4..c0de9075f 100755 --- a/core/lib/Thelia/Core/Event/CustomerCreateOrUpdateEvent.php +++ b/core/lib/Thelia/Core/Event/CustomerCreateOrUpdateEvent.php @@ -32,6 +32,7 @@ class CustomerCreateOrUpdateEvent extends ActionEvent protected $reseller; protected $sponsor; protected $discount; + protected $company; /** * @var \Thelia\Model\Customer @@ -39,7 +40,7 @@ class CustomerCreateOrUpdateEvent extends ActionEvent protected $customer; /** - * @param int $title the title customer id + * @param int $title the title customer id * @param string $firstname * @param string $lastname * @param string $address1 @@ -49,15 +50,16 @@ class CustomerCreateOrUpdateEvent extends ActionEvent * @param string $cellphone * @param string $zipcode * @param string $city - * @param int $country the country id + * @param int $country the country id * @param string $email * @param string $password plain password, don't put hash password, it will hashes again * @param $lang - * @param int $reseller if customer is a reseller - * @param int $sponsor customer's id sponsor + * @param int $reseller if customer is a reseller + * @param int $sponsor customer's id sponsor * @param float $discount + * @param string $company */ - public function __construct($title, $firstname, $lastname, $address1, $address2, $address3, $phone, $cellphone, $zipcode, $city, $country, $email, $password, $lang, $reseller, $sponsor, $discount) + public function __construct($title, $firstname, $lastname, $address1, $address2, $address3, $phone, $cellphone, $zipcode, $city, $country, $email, $password, $lang, $reseller, $sponsor, $discount, $company) { $this->address1 = $address1; $this->address2 = $address2; @@ -75,6 +77,14 @@ class CustomerCreateOrUpdateEvent extends ActionEvent $this->reseller = $reseller; $this->sponsor = $sponsor; $this->discount = $discount; + $this->company = $company; + } + /** + * @return mixed + */ + public function getCompany() + { + return $this->company; } /** diff --git a/core/lib/Thelia/Model/Customer.php b/core/lib/Thelia/Model/Customer.php index 965b2176d..bb30d18e2 100755 --- a/core/lib/Thelia/Model/Customer.php +++ b/core/lib/Thelia/Model/Customer.php @@ -54,7 +54,7 @@ class Customer extends BaseCustomer implements UserInterface * @param int $discount * @throws \Exception|\Symfony\Component\Config\Definition\Exception\Exception */ - public function createOrUpdate($titleId, $firstname, $lastname, $address1, $address2, $address3, $phone, $cellphone, $zipcode, $city, $countryId, $email = null, $plainPassword = null, $lang = null, $reseller = 0, $sponsor = null, $discount = 0) + public function createOrUpdate($titleId, $firstname, $lastname, $address1, $address2, $address3, $phone, $cellphone, $zipcode, $city, $countryId, $email = null, $plainPassword = null, $lang = null, $reseller = 0, $sponsor = null, $discount = 0, $company = null) { $this ->setTitleId($titleId) @@ -79,6 +79,7 @@ class Customer extends BaseCustomer implements UserInterface $address = new Address(); $address + ->setCompany($company) ->setTitleId($titleId) ->setFirstname($firstname) ->setLastname($lastname) @@ -99,6 +100,7 @@ class Customer extends BaseCustomer implements UserInterface $address = $this->getDefaultAddress(); $address + ->setCompany($company) ->setTitleId($titleId) ->setFirstname($firstname) ->setLastname($lastname) diff --git a/core/lib/Thelia/Tests/Action/CustomerTest.php b/core/lib/Thelia/Tests/Action/CustomerTest.php new file mode 100644 index 000000000..b70d39428 --- /dev/null +++ b/core/lib/Thelia/Tests/Action/CustomerTest.php @@ -0,0 +1,102 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Tests\Action\ImageTest; +use Thelia\Action\Customer; +use Thelia\Core\Event\CustomerCreateOrUpdateEvent; + + +/** + * Class CustomerTest + * @package Thelia\Tests\Action\ImageTest + * @author Manuel Raynaud + */ +class CustomerTest extends \PHPUnit_Framework_TestCase +{ + public function getContainer() + { + $container = new \Symfony\Component\DependencyInjection\ContainerBuilder(); + + $dispatcher = $this->getMock("Symfony\Component\EventDispatcher\EventDispatcherInterface"); + + $container->set("event_dispatcher", $dispatcher); + + return $container; + } + + public function testCreatedCustomer() + { + $customerCreateEvent = new CustomerCreateOrUpdateEvent( + 1, + "thelia", + "thelia", + "street address 1", + "street address 2", + "street address 3", + "0102030405", + "0607080910", + "63000", + "clermont-ferrand", + 64, + sprintf("%s@thelia.fr", uniqid()), + uniqid(), + 1, + 0, + 0, + 0, + 'My super company' + ); + + $customerAction = new Customer($this->getContainer()); + + $customerAction->create($customerCreateEvent); + + $customerCreated = $customerCreateEvent->getCustomer(); + + $this->assertInstanceOf("Thelia\Model\Customer", $customerCreated, "new customer created must be an instance of Thelia\Model\Customer"); + $this->assertFalse($customerCreated->isNew()); + + $this->assertEquals($customerCreateEvent->getFirstname(), $customerCreated->getFirstname()); + $this->assertEquals($customerCreateEvent->getLastname(), $customerCreated->getLastname()); + $this->assertEquals($customerCreateEvent->getTitle(), $customerCreated->getTitleId()); + $this->assertEquals($customerCreateEvent->getEmail(), $customerCreated->getEmail()); + $this->assertEquals($customerCreated->getReseller(), $customerCreated->getReseller()); + $this->assertEquals($customerCreated->getSponsor(), $customerCreated->getSponsor()); + $this->assertEquals($customerCreated->getDiscount(), $customerCreated->getDiscount()); + + $addressCreated = $customerCreated->getDefaultAddress(); + + $this->assertEquals($customerCreateEvent->getFirstname(), $addressCreated->getFirstname()); + $this->assertEquals($customerCreateEvent->getLastname(), $addressCreated->getLastname()); + $this->assertEquals($customerCreateEvent->getTitle(), $addressCreated->getTitleId()); + $this->assertEquals($customerCreateEvent->getAddress1(), $addressCreated->getAddress1()); + $this->assertEquals($customerCreateEvent->getAddress2(), $addressCreated->getAddress2()); + $this->assertEquals($customerCreateEvent->getAddress3(), $addressCreated->getAddress3()); + $this->assertEquals($customerCreateEvent->getZipcode(), $addressCreated->getZipcode()); + $this->assertEquals($customerCreateEvent->getCity(), $addressCreated->getCity()); + $this->assertEquals($customerCreateEvent->getCountry(), $addressCreated->getCountryId()); + $this->assertEquals($customerCreateEvent->getPhone(), $addressCreated->getPhone()); + $this->assertEquals($customerCreateEvent->getCellphone(), $addressCreated->getCellphone()); + $this->assertEquals($customerCreateEvent->getCompany(), $addressCreated->getCompany()); + } +} \ No newline at end of file From 6fea7ef44117aa28273ac6079bdf34cd34ff3941 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Thu, 12 Sep 2013 09:48:24 +0200 Subject: [PATCH 08/45] change method to retrieve data in customer create process --- .../Controller/Front/CustomerController.php | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/core/lib/Thelia/Controller/Front/CustomerController.php b/core/lib/Thelia/Controller/Front/CustomerController.php index 3b8c2ccff..56ac47f67 100755 --- a/core/lib/Thelia/Controller/Front/CustomerController.php +++ b/core/lib/Thelia/Controller/Front/CustomerController.php @@ -22,6 +22,7 @@ /*************************************************************************************/ namespace Thelia\Controller\Front; +use Symfony\Component\Form\Form; use Thelia\Core\Event\CustomerCreateOrUpdateEvent; use Thelia\Core\Event\CustomerLoginEvent; use Thelia\Core\Event\LostPasswordEvent; @@ -97,7 +98,7 @@ class CustomerController extends BaseFrontController try { $form = $this->validateForm($customerCreation, "post"); - $customerCreateEvent = $this->createEventInstance($form->getData()); + $customerCreateEvent = $this->createEventInstance($form); $this->dispatch(TheliaEvents::CUSTOMER_CREATEACCOUNT, $customerCreateEvent); @@ -146,7 +147,7 @@ class CustomerController extends BaseFrontController $form = $this->validateForm($customerModification, "post"); - $customerChangeEvent = $this->createEventInstance($form->getData()); + $customerChangeEvent = $this->createEventInstance($form); $customerChangeEvent->setCustomer($customer); $this->dispatch(TheliaEvents::CUSTOMER_UPDATEACCOUNT, $customerChangeEvent); @@ -259,27 +260,27 @@ class CustomerController extends BaseFrontController * @param $data * @return CustomerCreateOrUpdateEvent */ - private function createEventInstance($data) + private function createEventInstance(Form $form) { $customerCreateEvent = new CustomerCreateOrUpdateEvent( - $data["title"], - $data["firstname"], - $data["lastname"], - $data["address1"], - $data["address2"], - $data["address3"], - $data["phone"], - $data["cellphone"], - $data["zipcode"], - $data["city"], - $data["country"], - isset($data["email"])?$data["email"]:null, - isset($data["password"]) ? $data["password"]:null, + $form->get("title")->getData(), + $form->get("firstname")->getData(), + $form->get("lastname")->getData(), + $form->get("address1")->getData(), + $form->get("address2")->getData(), + $form->get("address3")->getData(), + $form->get("phone")->getData(), + $form->get("cellphone")->getData(), + $form->get("zipcode")->getData(), + $form->get("city")->getData(), + $form->get("country")->getData(), + $form->get("email")->getData(), + $form->get("password")->getData(), $this->getRequest()->getSession()->getLang()->getId(), - isset($data["reseller"])?$data["reseller"]:null, - isset($data["sponsor"])?$data["sponsor"]:null, - isset($data["discount"])?$data["discount"]:null, - isset($data["company"])?$data["company"]:null + $form->get("reseller")->getData(), + $form->get("sponsor")->getData(), + $form->get("discount")->getData(), + $form->get("company")->getData() ); return $customerCreateEvent; From 4b643a7a9ed1063fd4312d0c0eedf5ddcb1f673b Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Thu, 12 Sep 2013 10:12:22 +0200 Subject: [PATCH 09/45] remove not needed flag in customer part --- core/lib/Thelia/Config/Resources/routing/admin.xml | 7 ++++++- templates/admin/default/customer-edit.html | 11 +++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index 5e34aec39..6feb39185 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -37,7 +37,12 @@ Thelia\Controller\Admin\CustomerController::indexAction
- + + Thelia\Controller\Admin\CustomerController::viewAction + \d+ + + + Thelia\Controller\Admin\CustomerController::viewAction \d+ diff --git a/templates/admin/default/customer-edit.html b/templates/admin/default/customer-edit.html index 216337927..48ccb3dc3 100644 --- a/templates/admin/default/customer-edit.html +++ b/templates/admin/default/customer-edit.html @@ -29,12 +29,15 @@
{form name="thelia.customer.modification"} -
+ - {* Be sure to get the customer ID, even if the form could not be validated *} - +
+
+ + +
+
- {include file="includes/inner-form-toolbar.html"} {form_hidden_fields form=$form} From d61f3a6a1ec29c5d352757b4440377593808865f Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Thu, 12 Sep 2013 10:48:27 +0200 Subject: [PATCH 10/45] product loop test --- .../Core/Template/Element/BaseLoopTestor.php | 24 +++++++++++++++++++ .../Tests/Core/Template/Loop/ProductTest.php | 20 ++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/core/lib/Thelia/Tests/Core/Template/Element/BaseLoopTestor.php b/core/lib/Thelia/Tests/Core/Template/Element/BaseLoopTestor.php index 4a9cb4158..544e06bb0 100755 --- a/core/lib/Thelia/Tests/Core/Template/Element/BaseLoopTestor.php +++ b/core/lib/Thelia/Tests/Core/Template/Element/BaseLoopTestor.php @@ -29,6 +29,7 @@ use Thelia\Core\HttpFoundation\Request; use Thelia\Core\Security\SecurityContext; use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage; use Thelia\Core\HttpFoundation\Session\Session; +use Thelia\Tools\URL; /** * @@ -82,9 +83,32 @@ abstract class BaseLoopTestor extends \PHPUnit_Framework_TestCase $this->securityContext = new SecurityContext($this->request);*/ + $stubRouterAdmin = $this->getMockBuilder('\Symfony\Component\Routing\Router') + ->disableOriginalConstructor() + ->setMethods(array('getContext')) + ->getMock(); + + $stubRequestContext = $this->getMockBuilder('\Symfony\Component\Routing\RequestContext') + ->disableOriginalConstructor() + ->setMethods(array('getHost')) + ->getMock(); + + $stubRequestContext->expects($this->any()) + ->method('getHost') + ->will($this->returnValue('localhost')); + + $stubRouterAdmin->expects($this->any()) + ->method('getContext') + ->will($this->returnValue( + $stubRequestContext + )); + + $this->container->set('request', $request); $this->container->set('event_dispatcher', new EventDispatcher()); $this->container->set('thelia.securityContext', new SecurityContext($request)); + $this->container->set('router.admin', $stubRouterAdmin); + $this->container->set('thelia.url.manager', new URL($this->container)); $this->instance = $this->getTestedInstance(); $this->instance->initializeArgs($this->getMandatoryArguments()); diff --git a/core/lib/Thelia/Tests/Core/Template/Loop/ProductTest.php b/core/lib/Thelia/Tests/Core/Template/Loop/ProductTest.php index 8fc7d5ae5..4fb6e7874 100755 --- a/core/lib/Thelia/Tests/Core/Template/Loop/ProductTest.php +++ b/core/lib/Thelia/Tests/Core/Template/Loop/ProductTest.php @@ -23,6 +23,7 @@ namespace Thelia\Tests\Core\Template\Loop; +use Thelia\Model\ProductQuery; use Thelia\Tests\Core\Template\Element\BaseLoopTestor; use Thelia\Core\Template\Loop\Product; @@ -48,4 +49,23 @@ class ProductTest extends BaseLoopTestor { return array(); } + + public function testSearchById() + { + $product = ProductQuery::create()->findOne(); + + $loop = new Product($this->container); + $loop->initializeArgs(array( + "type" => "product", + "name" => "product", + "id" => $product->getId(), + )); + $loopResults = $loop->exec($pagination); + + $this->assertEquals(1, $loopResults->getCount()); + + $substitutions = $loopResults->current()->getVarVal(); + + $this->assertEquals($product->getId(), $substitutions['ID']); + } } From e81b8948168cfac59d40109f9fe604bfa7a1964a Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Thu, 12 Sep 2013 10:58:12 +0200 Subject: [PATCH 11/45] fix tests --- .../Rewriting/RewritingRetrieverTest.php | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/core/lib/Thelia/Tests/Rewriting/RewritingRetrieverTest.php b/core/lib/Thelia/Tests/Rewriting/RewritingRetrieverTest.php index 8723e0096..1a47dc10a 100755 --- a/core/lib/Thelia/Tests/Rewriting/RewritingRetrieverTest.php +++ b/core/lib/Thelia/Tests/Rewriting/RewritingRetrieverTest.php @@ -23,6 +23,7 @@ namespace Thelia\Tests\Rewriting; +use Symfony\Component\DependencyInjection\ContainerBuilder; use Thelia\Model\RewritingUrl; use Thelia\Rewriting\RewritingRetriever; use Thelia\Tools\URL; @@ -34,6 +35,36 @@ use Thelia\Tools\URL; */ class RewritingRetrieverTest extends \PHPUnit_Framework_TestCase { + protected $container = null; + + public function setUp() + { + $this->container = new ContainerBuilder(); + + $stubRouterAdmin = $this->getMockBuilder('\Symfony\Component\Routing\Router') + ->disableOriginalConstructor() + ->setMethods(array('getContext')) + ->getMock(); + + $stubRequestContext = $this->getMockBuilder('\Symfony\Component\Routing\RequestContext') + ->disableOriginalConstructor() + ->setMethods(array('getHost')) + ->getMock(); + + $stubRequestContext->expects($this->any()) + ->method('getHost') + ->will($this->returnValue('localhost')); + + $stubRouterAdmin->expects($this->any()) + ->method('getContext') + ->will($this->returnValue( + $stubRequestContext + )); + + $this->container->set('router.admin', $stubRouterAdmin); + $this->container->set('thelia.url.manager', new URL($this->container)); + } + protected function getMethod($name) { $class = new \ReflectionClass('\Thelia\Rewriting\RewritingRetriever'); From 5d87e48ba0e2b3e0d6483dae3ce6da2ace7311d7 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Thu, 12 Sep 2013 11:24:24 +0200 Subject: [PATCH 12/45] update customer general info --- .../Thelia/Config/Resources/routing/admin.xml | 2 +- .../Controller/Admin/CustomerController.php | 94 +++++++++++++++++++ .../Controller/Front/CustomerController.php | 41 ++++---- .../Event/CustomerCreateOrUpdateEvent.php | 1 + core/lib/Thelia/Form/CustomerModification.php | 6 ++ templates/admin/default/customer-edit.html | 11 ++- 6 files changed, 131 insertions(+), 24 deletions(-) diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index 6feb39185..60150b3fa 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -43,7 +43,7 @@ - Thelia\Controller\Admin\CustomerController::viewAction + Thelia\Controller\Admin\CustomerController::updateAction \d+ diff --git a/core/lib/Thelia/Controller/Admin/CustomerController.php b/core/lib/Thelia/Controller/Admin/CustomerController.php index ddf4681b9..ab897d24b 100644 --- a/core/lib/Thelia/Controller/Admin/CustomerController.php +++ b/core/lib/Thelia/Controller/Admin/CustomerController.php @@ -22,6 +22,13 @@ /*************************************************************************************/ namespace Thelia\Controller\Admin; +use Propel\Runtime\Exception\PropelException; +use Symfony\Component\Form\Form; +use Thelia\Core\Event\CustomerCreateOrUpdateEvent; +use Thelia\Core\Event\TheliaEvents; +use Thelia\Form\CustomerModification; +use Thelia\Form\Exception\FormValidationException; +use Thelia\Model\CustomerQuery; /** * Class CustomerController @@ -38,9 +45,96 @@ class CustomerController extends BaseAdminController public function viewAction($customer_id) { + if (null !== $response = $this->checkAuth("admin.customers.view")) return $response; return $this->render("customer-edit", array( "customer_id" => $customer_id )); } + + public function updateAction($customer_id) + { + if (null !== $response = $this->checkAuth("admin.customers.update")) return $response; + + $message = false; + + $customerModification = new CustomerModification($this->getRequest()); + + try { + $customer = CustomerQuery::create()->findPk($customer_id); + + if(null === $customer) { + throw new \InvalidArgumentException(sprintf("%d customer id does not exists", $customer_id)); + } + + $form = $this->validateForm($customerModification); + + $event = $this->createEventInstance($form->getData()); + $event->setCustomer($customer); + + $this->dispatch(TheliaEvents::CUSTOMER_UPDATEACCOUNT, $event); + + $customerUpdated = $event->getCustomer(); + + $this->adminLogAppend(sprintf("Customer with Ref %s (ID %d) modified", $customerUpdated->getRef() , $customerUpdated->getId())); + + if($this->getRequest()->get("save_mode") == "close") { + $this->redirectToRoute("admin.customers"); + } else { + $this->redirectSuccess($customerModification); + } + + } catch (FormValidationException $e) { + $message = sprintf("Please check your input: %s", $e->getMessage()); + } catch (PropelException $e) { + $message = $e->getMessage(); + } catch (\Exception $e) { + $message = sprintf("Sorry, an error occured: %s", $e->getMessage()." ".$e->getFile()); + } + + if ($message !== false) { + \Thelia\Log\Tlog::getInstance()->error(sprintf("Error during customer login process : %s.", $message)); + + $customerModification->setErrorMessage($message); + + $this->getParserContext() + ->addForm($customerModification) + ->setGeneralError($message) + ; + } + + return $this->render("customer-edit", array( + "customer_id" => $customer_id + )); + } + + /** + * @param $data + * @return CustomerCreateOrUpdateEvent + */ + private function createEventInstance($data) + { + $customerCreateEvent = new CustomerCreateOrUpdateEvent( + $data["title"], + $data["firstname"], + $data["lastname"], + $data["address1"], + $data["address2"], + $data["address3"], + $data["phone"], + $data["cellphone"], + $data["zipcode"], + $data["city"], + $data["country"], + isset($data["email"])?$data["email"]:null, + isset($data["password"]) ? $data["password"]:null, + $this->getRequest()->getSession()->getLang()->getId(), + isset($data["reseller"])?$data["reseller"]:null, + isset($data["sponsor"])?$data["sponsor"]:null, + isset($data["discount"])?$data["discount"]:null, + isset($data["company"])?$data["company"]:null + ); + + return $customerCreateEvent; + } } \ No newline at end of file diff --git a/core/lib/Thelia/Controller/Front/CustomerController.php b/core/lib/Thelia/Controller/Front/CustomerController.php index 56ac47f67..3b8c2ccff 100755 --- a/core/lib/Thelia/Controller/Front/CustomerController.php +++ b/core/lib/Thelia/Controller/Front/CustomerController.php @@ -22,7 +22,6 @@ /*************************************************************************************/ namespace Thelia\Controller\Front; -use Symfony\Component\Form\Form; use Thelia\Core\Event\CustomerCreateOrUpdateEvent; use Thelia\Core\Event\CustomerLoginEvent; use Thelia\Core\Event\LostPasswordEvent; @@ -98,7 +97,7 @@ class CustomerController extends BaseFrontController try { $form = $this->validateForm($customerCreation, "post"); - $customerCreateEvent = $this->createEventInstance($form); + $customerCreateEvent = $this->createEventInstance($form->getData()); $this->dispatch(TheliaEvents::CUSTOMER_CREATEACCOUNT, $customerCreateEvent); @@ -147,7 +146,7 @@ class CustomerController extends BaseFrontController $form = $this->validateForm($customerModification, "post"); - $customerChangeEvent = $this->createEventInstance($form); + $customerChangeEvent = $this->createEventInstance($form->getData()); $customerChangeEvent->setCustomer($customer); $this->dispatch(TheliaEvents::CUSTOMER_UPDATEACCOUNT, $customerChangeEvent); @@ -260,27 +259,27 @@ class CustomerController extends BaseFrontController * @param $data * @return CustomerCreateOrUpdateEvent */ - private function createEventInstance(Form $form) + private function createEventInstance($data) { $customerCreateEvent = new CustomerCreateOrUpdateEvent( - $form->get("title")->getData(), - $form->get("firstname")->getData(), - $form->get("lastname")->getData(), - $form->get("address1")->getData(), - $form->get("address2")->getData(), - $form->get("address3")->getData(), - $form->get("phone")->getData(), - $form->get("cellphone")->getData(), - $form->get("zipcode")->getData(), - $form->get("city")->getData(), - $form->get("country")->getData(), - $form->get("email")->getData(), - $form->get("password")->getData(), + $data["title"], + $data["firstname"], + $data["lastname"], + $data["address1"], + $data["address2"], + $data["address3"], + $data["phone"], + $data["cellphone"], + $data["zipcode"], + $data["city"], + $data["country"], + isset($data["email"])?$data["email"]:null, + isset($data["password"]) ? $data["password"]:null, $this->getRequest()->getSession()->getLang()->getId(), - $form->get("reseller")->getData(), - $form->get("sponsor")->getData(), - $form->get("discount")->getData(), - $form->get("company")->getData() + isset($data["reseller"])?$data["reseller"]:null, + isset($data["sponsor"])?$data["sponsor"]:null, + isset($data["discount"])?$data["discount"]:null, + isset($data["company"])?$data["company"]:null ); return $customerCreateEvent; diff --git a/core/lib/Thelia/Core/Event/CustomerCreateOrUpdateEvent.php b/core/lib/Thelia/Core/Event/CustomerCreateOrUpdateEvent.php index c0de9075f..8269cecf3 100755 --- a/core/lib/Thelia/Core/Event/CustomerCreateOrUpdateEvent.php +++ b/core/lib/Thelia/Core/Event/CustomerCreateOrUpdateEvent.php @@ -74,6 +74,7 @@ class CustomerCreateOrUpdateEvent extends ActionEvent $this->cellphone = $cellphone; $this->title = $title; $this->zipcode = $zipcode; + $this->city = $city; $this->reseller = $reseller; $this->sponsor = $sponsor; $this->discount = $discount; diff --git a/core/lib/Thelia/Form/CustomerModification.php b/core/lib/Thelia/Form/CustomerModification.php index 358154a18..4f12c6013 100755 --- a/core/lib/Thelia/Form/CustomerModification.php +++ b/core/lib/Thelia/Form/CustomerModification.php @@ -58,6 +58,12 @@ class CustomerModification extends BaseForm $this->formBuilder ->add('update_logged_in_user', 'integer') // In a front office context, update the in-memory logged-in user data + ->add("company", "text", array( + "label" => Translator::getInstance()->trans("Company"), + "label_attr" => array( + "for" => "company" + ) + )) ->add("firstname", "text", array( "constraints" => array( new Constraints\NotBlank() diff --git a/templates/admin/default/customer-edit.html b/templates/admin/default/customer-edit.html index 48ccb3dc3..fef3b1d4f 100644 --- a/templates/admin/default/customer-edit.html +++ b/templates/admin/default/customer-edit.html @@ -29,7 +29,7 @@
{form name="thelia.customer.modification"} - +
@@ -42,7 +42,7 @@ {form_hidden_fields form=$form} {form_field form=$form field='success_url'} - + {/form_field} {if $form_error}
{$form_error_message}
{/if} @@ -80,6 +80,13 @@

{intl l="Default address"}

+ {form_field form=$form field='company'} +
+ + +
+ {/form_field} + {form_field form=$form field='address1'}
From f75b6e876c8ee87cf71992f851d1650785c9b749 Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Thu, 12 Sep 2013 11:28:32 +0200 Subject: [PATCH 13/45] test product loop limit --- .../Thelia/Core/Template/Element/BaseLoop.php | 1 + .../Tests/Core/Template/Loop/ProductTest.php | 30 +++++++++++++++---- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/core/lib/Thelia/Core/Template/Element/BaseLoop.php b/core/lib/Thelia/Core/Template/Element/BaseLoop.php index 254560453..b684d06e2 100755 --- a/core/lib/Thelia/Core/Template/Element/BaseLoop.php +++ b/core/lib/Thelia/Core/Template/Element/BaseLoop.php @@ -129,6 +129,7 @@ abstract class BaseLoop $loopType = isset($nameValuePairs['type']) ? $nameValuePairs['type'] : "undefined"; $loopName = isset($nameValuePairs['name']) ? $nameValuePairs['name'] : "undefined"; + $this->args->rewind(); while (($argument = $this->args->current()) !== false) { $this->args->next(); diff --git a/core/lib/Thelia/Tests/Core/Template/Loop/ProductTest.php b/core/lib/Thelia/Tests/Core/Template/Loop/ProductTest.php index 4fb6e7874..acd3f9043 100755 --- a/core/lib/Thelia/Tests/Core/Template/Loop/ProductTest.php +++ b/core/lib/Thelia/Tests/Core/Template/Loop/ProductTest.php @@ -54,13 +54,17 @@ class ProductTest extends BaseLoopTestor { $product = ProductQuery::create()->findOne(); - $loop = new Product($this->container); - $loop->initializeArgs(array( - "type" => "product", - "name" => "product", - "id" => $product->getId(), + $this->instance->initializeArgs(array_merge( + $this->getMandatoryArguments(), + array( + "type" => "product", + "name" => "product", + "id" => $product->getId(), + ) )); - $loopResults = $loop->exec($pagination); + + $dummy = null; + $loopResults = $this->instance->exec($dummy); $this->assertEquals(1, $loopResults->getCount()); @@ -68,4 +72,18 @@ class ProductTest extends BaseLoopTestor $this->assertEquals($product->getId(), $substitutions['ID']); } + + public function testSearchLimit() + { + $this->instance->initializeArgs(array( + "type" => "product", + "name" => "product", + "limit" => 3, + )); + + $dummy = null; + $loopResults = $this->instance->exec($dummy); + + $this->assertEquals(3, $loopResults->getCount()); + } } From b698d1aada0a69b1ffba717ef1ab1971528cbabe Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Thu, 12 Sep 2013 11:35:27 +0200 Subject: [PATCH 14/45] loop tests --- .../Core/Template/Element/BaseLoopTestor.php | 38 +++++++++++++++++++ .../Tests/Core/Template/Loop/CategoryTest.php | 13 +++++++ .../Tests/Core/Template/Loop/ContentTest.php | 13 +++++++ .../Tests/Core/Template/Loop/FolderTest.php | 13 +++++++ .../Tests/Core/Template/Loop/ProductTest.php | 29 +------------- 5 files changed, 79 insertions(+), 27 deletions(-) diff --git a/core/lib/Thelia/Tests/Core/Template/Element/BaseLoopTestor.php b/core/lib/Thelia/Tests/Core/Template/Element/BaseLoopTestor.php index 544e06bb0..2b31d265a 100755 --- a/core/lib/Thelia/Tests/Core/Template/Element/BaseLoopTestor.php +++ b/core/lib/Thelia/Tests/Core/Template/Element/BaseLoopTestor.php @@ -131,4 +131,42 @@ abstract class BaseLoopTestor extends \PHPUnit_Framework_TestCase $this->assertInstanceOf('\Thelia\Core\Template\Element\LoopResult', $methodReturn); } + + public function baseTestSearchById($id) + { + $this->instance->initializeArgs(array_merge( + $this->getMandatoryArguments(), + array( + "type" => "foo", + "name" => "foo", + "id" => $id, + ) + )); + + $dummy = null; + $loopResults = $this->instance->exec($dummy); + + $this->assertEquals(1, $loopResults->getCount()); + + $substitutions = $loopResults->current()->getVarVal(); + + $this->assertEquals($id, $substitutions['ID']); + } + + public function baseTestSearchWithLimit($limit) + { + $this->instance->initializeArgs(array_merge( + $this->getMandatoryArguments(), + array( + "type" => "foo", + "name" => "foo", + "limit" => $limit, + ) + )); + + $dummy = null; + $loopResults = $this->instance->exec($dummy); + + $this->assertEquals($limit, $loopResults->getCount()); + } } diff --git a/core/lib/Thelia/Tests/Core/Template/Loop/CategoryTest.php b/core/lib/Thelia/Tests/Core/Template/Loop/CategoryTest.php index a2a320693..ce5f56747 100755 --- a/core/lib/Thelia/Tests/Core/Template/Loop/CategoryTest.php +++ b/core/lib/Thelia/Tests/Core/Template/Loop/CategoryTest.php @@ -23,6 +23,7 @@ namespace Thelia\Tests\Core\Template\Loop; +use Thelia\Model\CategoryQuery; use Thelia\Tests\Core\Template\Element\BaseLoopTestor; use Thelia\Core\Template\Loop\Category; @@ -48,4 +49,16 @@ class CategoryTest extends BaseLoopTestor { return array(); } + + public function testSearchById() + { + $category = CategoryQuery::create()->findOne(); + + $this->baseTestSearchById($category->getId()); + } + + public function testSearchLimit() + { + $this->baseTestSearchWithLimit(3); + } } diff --git a/core/lib/Thelia/Tests/Core/Template/Loop/ContentTest.php b/core/lib/Thelia/Tests/Core/Template/Loop/ContentTest.php index b6f9d0e3d..3a286200a 100755 --- a/core/lib/Thelia/Tests/Core/Template/Loop/ContentTest.php +++ b/core/lib/Thelia/Tests/Core/Template/Loop/ContentTest.php @@ -23,6 +23,7 @@ namespace Thelia\Tests\Core\Template\Loop; +use Thelia\Model\ContentQuery; use Thelia\Tests\Core\Template\Element\BaseLoopTestor; use Thelia\Core\Template\Loop\Content; @@ -48,4 +49,16 @@ class ContentTest extends BaseLoopTestor { return array(); } + + public function testSearchById() + { + $content = ContentQuery::create()->findOne(); + + $this->baseTestSearchById($content->getId()); + } + + public function testSearchLimit() + { + $this->baseTestSearchWithLimit(3); + } } diff --git a/core/lib/Thelia/Tests/Core/Template/Loop/FolderTest.php b/core/lib/Thelia/Tests/Core/Template/Loop/FolderTest.php index 2388a86c0..15ea3968c 100755 --- a/core/lib/Thelia/Tests/Core/Template/Loop/FolderTest.php +++ b/core/lib/Thelia/Tests/Core/Template/Loop/FolderTest.php @@ -23,6 +23,7 @@ namespace Thelia\Tests\Core\Template\Loop; +use Thelia\Model\FolderQuery; use Thelia\Tests\Core\Template\Element\BaseLoopTestor; use Thelia\Core\Template\Loop\Folder; @@ -48,4 +49,16 @@ class FolderTest extends BaseLoopTestor { return array(); } + + public function testSearchById() + { + $folder = FolderQuery::create()->findOne(); + + $this->baseTestSearchById($folder->getId()); + } + + public function testSearchLimit() + { + $this->baseTestSearchWithLimit(3); + } } diff --git a/core/lib/Thelia/Tests/Core/Template/Loop/ProductTest.php b/core/lib/Thelia/Tests/Core/Template/Loop/ProductTest.php index acd3f9043..1b307c5b5 100755 --- a/core/lib/Thelia/Tests/Core/Template/Loop/ProductTest.php +++ b/core/lib/Thelia/Tests/Core/Template/Loop/ProductTest.php @@ -54,36 +54,11 @@ class ProductTest extends BaseLoopTestor { $product = ProductQuery::create()->findOne(); - $this->instance->initializeArgs(array_merge( - $this->getMandatoryArguments(), - array( - "type" => "product", - "name" => "product", - "id" => $product->getId(), - ) - )); - - $dummy = null; - $loopResults = $this->instance->exec($dummy); - - $this->assertEquals(1, $loopResults->getCount()); - - $substitutions = $loopResults->current()->getVarVal(); - - $this->assertEquals($product->getId(), $substitutions['ID']); + $this->baseTestSearchById($product->getId()); } public function testSearchLimit() { - $this->instance->initializeArgs(array( - "type" => "product", - "name" => "product", - "limit" => 3, - )); - - $dummy = null; - $loopResults = $this->instance->exec($dummy); - - $this->assertEquals(3, $loopResults->getCount()); + $this->baseTestSearchWithLimit(3); } } From d5004071c9010ee9e59f0cfd3289a7b38392756a Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Thu, 12 Sep 2013 11:56:00 +0200 Subject: [PATCH 15/45] pse ref --- .../Thelia/Model/Base/ProductSaleElements.php | 116 +++++++++++++----- .../Model/Base/ProductSaleElementsQuery.php | 35 +++++- .../Model/Map/ProductSaleElementsTableMap.php | 36 +++--- install/thelia.sql | 2 + local/config/schema.xml | 4 + 5 files changed, 149 insertions(+), 44 deletions(-) diff --git a/core/lib/Thelia/Model/Base/ProductSaleElements.php b/core/lib/Thelia/Model/Base/ProductSaleElements.php index 4c14580ff..fa887dc8a 100644 --- a/core/lib/Thelia/Model/Base/ProductSaleElements.php +++ b/core/lib/Thelia/Model/Base/ProductSaleElements.php @@ -75,6 +75,12 @@ abstract class ProductSaleElements implements ActiveRecordInterface */ protected $product_id; + /** + * The value for the ref field. + * @var string + */ + protected $ref; + /** * The value for the quantity field. * @var double @@ -452,6 +458,17 @@ abstract class ProductSaleElements implements ActiveRecordInterface return $this->product_id; } + /** + * Get the [ref] column value. + * + * @return string + */ + public function getRef() + { + + return $this->ref; + } + /** * Get the [quantity] column value. * @@ -582,6 +599,27 @@ abstract class ProductSaleElements implements ActiveRecordInterface return $this; } // setProductId() + /** + * Set the value of [ref] column. + * + * @param string $v new value + * @return \Thelia\Model\ProductSaleElements The current object (for fluent API support) + */ + public function setRef($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->ref !== $v) { + $this->ref = $v; + $this->modifiedColumns[] = ProductSaleElementsTableMap::REF; + } + + + return $this; + } // setRef() + /** * Set the value of [quantity] column. * @@ -759,25 +797,28 @@ abstract class ProductSaleElements implements ActiveRecordInterface $col = $row[TableMap::TYPE_NUM == $indexType ? 1 + $startcol : ProductSaleElementsTableMap::translateFieldName('ProductId', TableMap::TYPE_PHPNAME, $indexType)]; $this->product_id = (null !== $col) ? (int) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : ProductSaleElementsTableMap::translateFieldName('Quantity', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : ProductSaleElementsTableMap::translateFieldName('Ref', TableMap::TYPE_PHPNAME, $indexType)]; + $this->ref = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : ProductSaleElementsTableMap::translateFieldName('Quantity', TableMap::TYPE_PHPNAME, $indexType)]; $this->quantity = (null !== $col) ? (double) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : ProductSaleElementsTableMap::translateFieldName('Promo', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : ProductSaleElementsTableMap::translateFieldName('Promo', TableMap::TYPE_PHPNAME, $indexType)]; $this->promo = (null !== $col) ? (int) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : ProductSaleElementsTableMap::translateFieldName('Newness', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : ProductSaleElementsTableMap::translateFieldName('Newness', TableMap::TYPE_PHPNAME, $indexType)]; $this->newness = (null !== $col) ? (int) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : ProductSaleElementsTableMap::translateFieldName('Weight', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : ProductSaleElementsTableMap::translateFieldName('Weight', TableMap::TYPE_PHPNAME, $indexType)]; $this->weight = (null !== $col) ? (double) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : ProductSaleElementsTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : ProductSaleElementsTableMap::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 ? 7 + $startcol : ProductSaleElementsTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 8 + $startcol : ProductSaleElementsTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } @@ -790,7 +831,7 @@ abstract class ProductSaleElements implements ActiveRecordInterface $this->ensureConsistency(); } - return $startcol + 8; // 8 = ProductSaleElementsTableMap::NUM_HYDRATE_COLUMNS. + return $startcol + 9; // 9 = ProductSaleElementsTableMap::NUM_HYDRATE_COLUMNS. } catch (Exception $e) { throw new PropelException("Error populating \Thelia\Model\ProductSaleElements object", 0, $e); @@ -1089,6 +1130,9 @@ abstract class ProductSaleElements implements ActiveRecordInterface if ($this->isColumnModified(ProductSaleElementsTableMap::PRODUCT_ID)) { $modifiedColumns[':p' . $index++] = 'PRODUCT_ID'; } + if ($this->isColumnModified(ProductSaleElementsTableMap::REF)) { + $modifiedColumns[':p' . $index++] = 'REF'; + } if ($this->isColumnModified(ProductSaleElementsTableMap::QUANTITY)) { $modifiedColumns[':p' . $index++] = 'QUANTITY'; } @@ -1124,6 +1168,9 @@ abstract class ProductSaleElements implements ActiveRecordInterface case 'PRODUCT_ID': $stmt->bindValue($identifier, $this->product_id, PDO::PARAM_INT); break; + case 'REF': + $stmt->bindValue($identifier, $this->ref, PDO::PARAM_STR); + break; case 'QUANTITY': $stmt->bindValue($identifier, $this->quantity, PDO::PARAM_STR); break; @@ -1211,21 +1258,24 @@ abstract class ProductSaleElements implements ActiveRecordInterface return $this->getProductId(); break; case 2: - return $this->getQuantity(); + return $this->getRef(); break; case 3: - return $this->getPromo(); + return $this->getQuantity(); break; case 4: - return $this->getNewness(); + return $this->getPromo(); break; case 5: - return $this->getWeight(); + return $this->getNewness(); break; case 6: - return $this->getCreatedAt(); + return $this->getWeight(); break; case 7: + return $this->getCreatedAt(); + break; + case 8: return $this->getUpdatedAt(); break; default: @@ -1259,12 +1309,13 @@ abstract class ProductSaleElements implements ActiveRecordInterface $result = array( $keys[0] => $this->getId(), $keys[1] => $this->getProductId(), - $keys[2] => $this->getQuantity(), - $keys[3] => $this->getPromo(), - $keys[4] => $this->getNewness(), - $keys[5] => $this->getWeight(), - $keys[6] => $this->getCreatedAt(), - $keys[7] => $this->getUpdatedAt(), + $keys[2] => $this->getRef(), + $keys[3] => $this->getQuantity(), + $keys[4] => $this->getPromo(), + $keys[5] => $this->getNewness(), + $keys[6] => $this->getWeight(), + $keys[7] => $this->getCreatedAt(), + $keys[8] => $this->getUpdatedAt(), ); $virtualColumns = $this->virtualColumns; foreach($virtualColumns as $key => $virtualColumn) @@ -1326,21 +1377,24 @@ abstract class ProductSaleElements implements ActiveRecordInterface $this->setProductId($value); break; case 2: - $this->setQuantity($value); + $this->setRef($value); break; case 3: - $this->setPromo($value); + $this->setQuantity($value); break; case 4: - $this->setNewness($value); + $this->setPromo($value); break; case 5: - $this->setWeight($value); + $this->setNewness($value); break; case 6: - $this->setCreatedAt($value); + $this->setWeight($value); break; case 7: + $this->setCreatedAt($value); + break; + case 8: $this->setUpdatedAt($value); break; } // switch() @@ -1369,12 +1423,13 @@ abstract class ProductSaleElements implements ActiveRecordInterface if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]); if (array_key_exists($keys[1], $arr)) $this->setProductId($arr[$keys[1]]); - if (array_key_exists($keys[2], $arr)) $this->setQuantity($arr[$keys[2]]); - if (array_key_exists($keys[3], $arr)) $this->setPromo($arr[$keys[3]]); - if (array_key_exists($keys[4], $arr)) $this->setNewness($arr[$keys[4]]); - if (array_key_exists($keys[5], $arr)) $this->setWeight($arr[$keys[5]]); - if (array_key_exists($keys[6], $arr)) $this->setCreatedAt($arr[$keys[6]]); - if (array_key_exists($keys[7], $arr)) $this->setUpdatedAt($arr[$keys[7]]); + if (array_key_exists($keys[2], $arr)) $this->setRef($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setQuantity($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setPromo($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setNewness($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setWeight($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setCreatedAt($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setUpdatedAt($arr[$keys[8]]); } /** @@ -1388,6 +1443,7 @@ abstract class ProductSaleElements implements ActiveRecordInterface if ($this->isColumnModified(ProductSaleElementsTableMap::ID)) $criteria->add(ProductSaleElementsTableMap::ID, $this->id); if ($this->isColumnModified(ProductSaleElementsTableMap::PRODUCT_ID)) $criteria->add(ProductSaleElementsTableMap::PRODUCT_ID, $this->product_id); + if ($this->isColumnModified(ProductSaleElementsTableMap::REF)) $criteria->add(ProductSaleElementsTableMap::REF, $this->ref); if ($this->isColumnModified(ProductSaleElementsTableMap::QUANTITY)) $criteria->add(ProductSaleElementsTableMap::QUANTITY, $this->quantity); if ($this->isColumnModified(ProductSaleElementsTableMap::PROMO)) $criteria->add(ProductSaleElementsTableMap::PROMO, $this->promo); if ($this->isColumnModified(ProductSaleElementsTableMap::NEWNESS)) $criteria->add(ProductSaleElementsTableMap::NEWNESS, $this->newness); @@ -1458,6 +1514,7 @@ abstract class ProductSaleElements implements ActiveRecordInterface public function copyInto($copyObj, $deepCopy = false, $makeNew = true) { $copyObj->setProductId($this->getProductId()); + $copyObj->setRef($this->getRef()); $copyObj->setQuantity($this->getQuantity()); $copyObj->setPromo($this->getPromo()); $copyObj->setNewness($this->getNewness()); @@ -2383,6 +2440,7 @@ abstract class ProductSaleElements implements ActiveRecordInterface { $this->id = null; $this->product_id = null; + $this->ref = null; $this->quantity = null; $this->promo = null; $this->newness = null; diff --git a/core/lib/Thelia/Model/Base/ProductSaleElementsQuery.php b/core/lib/Thelia/Model/Base/ProductSaleElementsQuery.php index 9892bff51..6e9068002 100644 --- a/core/lib/Thelia/Model/Base/ProductSaleElementsQuery.php +++ b/core/lib/Thelia/Model/Base/ProductSaleElementsQuery.php @@ -23,6 +23,7 @@ use Thelia\Model\Map\ProductSaleElementsTableMap; * * @method ChildProductSaleElementsQuery orderById($order = Criteria::ASC) Order by the id column * @method ChildProductSaleElementsQuery orderByProductId($order = Criteria::ASC) Order by the product_id column + * @method ChildProductSaleElementsQuery orderByRef($order = Criteria::ASC) Order by the ref column * @method ChildProductSaleElementsQuery orderByQuantity($order = Criteria::ASC) Order by the quantity column * @method ChildProductSaleElementsQuery orderByPromo($order = Criteria::ASC) Order by the promo column * @method ChildProductSaleElementsQuery orderByNewness($order = Criteria::ASC) Order by the newness column @@ -32,6 +33,7 @@ use Thelia\Model\Map\ProductSaleElementsTableMap; * * @method ChildProductSaleElementsQuery groupById() Group by the id column * @method ChildProductSaleElementsQuery groupByProductId() Group by the product_id column + * @method ChildProductSaleElementsQuery groupByRef() Group by the ref column * @method ChildProductSaleElementsQuery groupByQuantity() Group by the quantity column * @method ChildProductSaleElementsQuery groupByPromo() Group by the promo column * @method ChildProductSaleElementsQuery groupByNewness() Group by the newness column @@ -64,6 +66,7 @@ use Thelia\Model\Map\ProductSaleElementsTableMap; * * @method ChildProductSaleElements findOneById(int $id) Return the first ChildProductSaleElements filtered by the id column * @method ChildProductSaleElements findOneByProductId(int $product_id) Return the first ChildProductSaleElements filtered by the product_id column + * @method ChildProductSaleElements findOneByRef(string $ref) Return the first ChildProductSaleElements filtered by the ref column * @method ChildProductSaleElements findOneByQuantity(double $quantity) Return the first ChildProductSaleElements filtered by the quantity column * @method ChildProductSaleElements findOneByPromo(int $promo) Return the first ChildProductSaleElements filtered by the promo column * @method ChildProductSaleElements findOneByNewness(int $newness) Return the first ChildProductSaleElements filtered by the newness column @@ -73,6 +76,7 @@ use Thelia\Model\Map\ProductSaleElementsTableMap; * * @method array findById(int $id) Return ChildProductSaleElements objects filtered by the id column * @method array findByProductId(int $product_id) Return ChildProductSaleElements objects filtered by the product_id column + * @method array findByRef(string $ref) Return ChildProductSaleElements objects filtered by the ref column * @method array findByQuantity(double $quantity) Return ChildProductSaleElements objects filtered by the quantity column * @method array findByPromo(int $promo) Return ChildProductSaleElements objects filtered by the promo column * @method array findByNewness(int $newness) Return ChildProductSaleElements objects filtered by the newness column @@ -167,7 +171,7 @@ abstract class ProductSaleElementsQuery extends ModelCriteria */ protected function findPkSimple($key, $con) { - $sql = 'SELECT ID, PRODUCT_ID, QUANTITY, PROMO, NEWNESS, WEIGHT, CREATED_AT, UPDATED_AT FROM product_sale_elements WHERE ID = :p0'; + $sql = 'SELECT ID, PRODUCT_ID, REF, QUANTITY, PROMO, NEWNESS, WEIGHT, CREATED_AT, UPDATED_AT FROM product_sale_elements WHERE ID = :p0'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key, PDO::PARAM_INT); @@ -340,6 +344,35 @@ abstract class ProductSaleElementsQuery extends ModelCriteria return $this->addUsingAlias(ProductSaleElementsTableMap::PRODUCT_ID, $productId, $comparison); } + /** + * Filter the query on the ref column + * + * Example usage: + * + * $query->filterByRef('fooValue'); // WHERE ref = 'fooValue' + * $query->filterByRef('%fooValue%'); // WHERE ref LIKE '%fooValue%' + * + * + * @param string $ref 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 ChildProductSaleElementsQuery The current query, for fluid interface + */ + public function filterByRef($ref = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($ref)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $ref)) { + $ref = str_replace('*', '%', $ref); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(ProductSaleElementsTableMap::REF, $ref, $comparison); + } + /** * Filter the query on the quantity column * diff --git a/core/lib/Thelia/Model/Map/ProductSaleElementsTableMap.php b/core/lib/Thelia/Model/Map/ProductSaleElementsTableMap.php index 21c005f5c..9025784bc 100644 --- a/core/lib/Thelia/Model/Map/ProductSaleElementsTableMap.php +++ b/core/lib/Thelia/Model/Map/ProductSaleElementsTableMap.php @@ -57,7 +57,7 @@ class ProductSaleElementsTableMap extends TableMap /** * The total number of columns */ - const NUM_COLUMNS = 8; + const NUM_COLUMNS = 9; /** * The number of lazy-loaded columns @@ -67,7 +67,7 @@ class ProductSaleElementsTableMap extends TableMap /** * The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */ - const NUM_HYDRATE_COLUMNS = 8; + const NUM_HYDRATE_COLUMNS = 9; /** * the column name for the ID field @@ -79,6 +79,11 @@ class ProductSaleElementsTableMap extends TableMap */ const PRODUCT_ID = 'product_sale_elements.PRODUCT_ID'; + /** + * the column name for the REF field + */ + const REF = 'product_sale_elements.REF'; + /** * the column name for the QUANTITY field */ @@ -121,12 +126,12 @@ class ProductSaleElementsTableMap extends TableMap * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ protected static $fieldNames = array ( - self::TYPE_PHPNAME => array('Id', 'ProductId', 'Quantity', 'Promo', 'Newness', 'Weight', 'CreatedAt', 'UpdatedAt', ), - self::TYPE_STUDLYPHPNAME => array('id', 'productId', 'quantity', 'promo', 'newness', 'weight', 'createdAt', 'updatedAt', ), - self::TYPE_COLNAME => array(ProductSaleElementsTableMap::ID, ProductSaleElementsTableMap::PRODUCT_ID, ProductSaleElementsTableMap::QUANTITY, ProductSaleElementsTableMap::PROMO, ProductSaleElementsTableMap::NEWNESS, ProductSaleElementsTableMap::WEIGHT, ProductSaleElementsTableMap::CREATED_AT, ProductSaleElementsTableMap::UPDATED_AT, ), - self::TYPE_RAW_COLNAME => array('ID', 'PRODUCT_ID', 'QUANTITY', 'PROMO', 'NEWNESS', 'WEIGHT', 'CREATED_AT', 'UPDATED_AT', ), - self::TYPE_FIELDNAME => array('id', 'product_id', 'quantity', 'promo', 'newness', 'weight', 'created_at', 'updated_at', ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, ) + self::TYPE_PHPNAME => array('Id', 'ProductId', 'Ref', 'Quantity', 'Promo', 'Newness', 'Weight', 'CreatedAt', 'UpdatedAt', ), + self::TYPE_STUDLYPHPNAME => array('id', 'productId', 'ref', 'quantity', 'promo', 'newness', 'weight', 'createdAt', 'updatedAt', ), + self::TYPE_COLNAME => array(ProductSaleElementsTableMap::ID, ProductSaleElementsTableMap::PRODUCT_ID, ProductSaleElementsTableMap::REF, ProductSaleElementsTableMap::QUANTITY, ProductSaleElementsTableMap::PROMO, ProductSaleElementsTableMap::NEWNESS, ProductSaleElementsTableMap::WEIGHT, ProductSaleElementsTableMap::CREATED_AT, ProductSaleElementsTableMap::UPDATED_AT, ), + self::TYPE_RAW_COLNAME => array('ID', 'PRODUCT_ID', 'REF', 'QUANTITY', 'PROMO', 'NEWNESS', 'WEIGHT', 'CREATED_AT', 'UPDATED_AT', ), + self::TYPE_FIELDNAME => array('id', 'product_id', 'ref', 'quantity', 'promo', 'newness', 'weight', 'created_at', 'updated_at', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, ) ); /** @@ -136,12 +141,12 @@ class ProductSaleElementsTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'ProductId' => 1, 'Quantity' => 2, 'Promo' => 3, 'Newness' => 4, 'Weight' => 5, 'CreatedAt' => 6, 'UpdatedAt' => 7, ), - self::TYPE_STUDLYPHPNAME => array('id' => 0, 'productId' => 1, 'quantity' => 2, 'promo' => 3, 'newness' => 4, 'weight' => 5, 'createdAt' => 6, 'updatedAt' => 7, ), - self::TYPE_COLNAME => array(ProductSaleElementsTableMap::ID => 0, ProductSaleElementsTableMap::PRODUCT_ID => 1, ProductSaleElementsTableMap::QUANTITY => 2, ProductSaleElementsTableMap::PROMO => 3, ProductSaleElementsTableMap::NEWNESS => 4, ProductSaleElementsTableMap::WEIGHT => 5, ProductSaleElementsTableMap::CREATED_AT => 6, ProductSaleElementsTableMap::UPDATED_AT => 7, ), - self::TYPE_RAW_COLNAME => array('ID' => 0, 'PRODUCT_ID' => 1, 'QUANTITY' => 2, 'PROMO' => 3, 'NEWNESS' => 4, 'WEIGHT' => 5, 'CREATED_AT' => 6, 'UPDATED_AT' => 7, ), - self::TYPE_FIELDNAME => array('id' => 0, 'product_id' => 1, 'quantity' => 2, 'promo' => 3, 'newness' => 4, 'weight' => 5, 'created_at' => 6, 'updated_at' => 7, ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, ) + self::TYPE_PHPNAME => array('Id' => 0, 'ProductId' => 1, 'Ref' => 2, 'Quantity' => 3, 'Promo' => 4, 'Newness' => 5, 'Weight' => 6, 'CreatedAt' => 7, 'UpdatedAt' => 8, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'productId' => 1, 'ref' => 2, 'quantity' => 3, 'promo' => 4, 'newness' => 5, 'weight' => 6, 'createdAt' => 7, 'updatedAt' => 8, ), + self::TYPE_COLNAME => array(ProductSaleElementsTableMap::ID => 0, ProductSaleElementsTableMap::PRODUCT_ID => 1, ProductSaleElementsTableMap::REF => 2, ProductSaleElementsTableMap::QUANTITY => 3, ProductSaleElementsTableMap::PROMO => 4, ProductSaleElementsTableMap::NEWNESS => 5, ProductSaleElementsTableMap::WEIGHT => 6, ProductSaleElementsTableMap::CREATED_AT => 7, ProductSaleElementsTableMap::UPDATED_AT => 8, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'PRODUCT_ID' => 1, 'REF' => 2, 'QUANTITY' => 3, 'PROMO' => 4, 'NEWNESS' => 5, 'WEIGHT' => 6, 'CREATED_AT' => 7, 'UPDATED_AT' => 8, ), + self::TYPE_FIELDNAME => array('id' => 0, 'product_id' => 1, 'ref' => 2, 'quantity' => 3, 'promo' => 4, 'newness' => 5, 'weight' => 6, 'created_at' => 7, 'updated_at' => 8, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, ) ); /** @@ -162,6 +167,7 @@ class ProductSaleElementsTableMap extends TableMap // columns $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); $this->addForeignKey('PRODUCT_ID', 'ProductId', 'INTEGER', 'product', 'ID', true, null, null); + $this->addColumn('REF', 'Ref', 'VARCHAR', true, 45, null); $this->addColumn('QUANTITY', 'Quantity', 'FLOAT', true, null, null); $this->addColumn('PROMO', 'Promo', 'TINYINT', false, null, 0); $this->addColumn('NEWNESS', 'Newness', 'TINYINT', false, null, 0); @@ -343,6 +349,7 @@ class ProductSaleElementsTableMap extends TableMap if (null === $alias) { $criteria->addSelectColumn(ProductSaleElementsTableMap::ID); $criteria->addSelectColumn(ProductSaleElementsTableMap::PRODUCT_ID); + $criteria->addSelectColumn(ProductSaleElementsTableMap::REF); $criteria->addSelectColumn(ProductSaleElementsTableMap::QUANTITY); $criteria->addSelectColumn(ProductSaleElementsTableMap::PROMO); $criteria->addSelectColumn(ProductSaleElementsTableMap::NEWNESS); @@ -352,6 +359,7 @@ class ProductSaleElementsTableMap extends TableMap } else { $criteria->addSelectColumn($alias . '.ID'); $criteria->addSelectColumn($alias . '.PRODUCT_ID'); + $criteria->addSelectColumn($alias . '.REF'); $criteria->addSelectColumn($alias . '.QUANTITY'); $criteria->addSelectColumn($alias . '.PROMO'); $criteria->addSelectColumn($alias . '.NEWNESS'); diff --git a/install/thelia.sql b/install/thelia.sql index e4e5fb6b7..7f040ff50 100755 --- a/install/thelia.sql +++ b/install/thelia.sql @@ -349,6 +349,7 @@ CREATE TABLE `product_sale_elements` ( `id` INTEGER NOT NULL AUTO_INCREMENT, `product_id` INTEGER NOT NULL, + `ref` VARCHAR(45) NOT NULL, `quantity` FLOAT NOT NULL, `promo` TINYINT DEFAULT 0, `newness` TINYINT DEFAULT 0, @@ -356,6 +357,7 @@ CREATE TABLE `product_sale_elements` `created_at` DATETIME, `updated_at` DATETIME, PRIMARY KEY (`id`), + UNIQUE INDEX `ref_UNIQUE` (`ref`), INDEX `idx_product_sale_element_product_id` (`product_id`), CONSTRAINT `fk_product_sale_element_product_id` FOREIGN KEY (`product_id`) diff --git a/local/config/schema.xml b/local/config/schema.xml index 7590da1e4..8759624a9 100755 --- a/local/config/schema.xml +++ b/local/config/schema.xml @@ -264,6 +264,7 @@ + @@ -274,6 +275,9 @@ + + +
From 3115ee006db5777dd25f91c6172f62dace629986 Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Thu, 12 Sep 2013 11:59:45 +0200 Subject: [PATCH 16/45] pse ref in faker --- install/faker.php | 1 + 1 file changed, 1 insertion(+) diff --git a/install/faker.php b/install/faker.php index 5bb21d4fa..2584343a9 100755 --- a/install/faker.php +++ b/install/faker.php @@ -319,6 +319,7 @@ try { for($i=0; $isetProductId($productId); + $stock->setRef($productId . '_' . $i . '_' . $faker->randomNumber(8)); $stock->setQuantity($faker->randomNumber(1,50)); $stock->setPromo($faker->randomNumber(0,1)); $stock->setNewness($faker->randomNumber(0,1)); From 9856528a9499d952d057c3de9cb04acf218356cf Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Thu, 12 Sep 2013 12:40:14 +0200 Subject: [PATCH 17/45] valid customer removal --- core/lib/Thelia/Action/Customer.php | 9 ++++ .../Thelia/Config/Resources/routing/admin.xml | 4 ++ .../Controller/Admin/CustomerController.php | 46 +++++++++++++++++-- .../Event/CustomerCreateOrUpdateEvent.php | 34 ++++++++++---- core/lib/Thelia/Core/Event/TheliaEvents.php | 15 ++++++ core/lib/Thelia/Model/Customer.php | 4 +- templates/admin/default/customers.html | 16 ++++++- .../includes/generic-confirm-dialog.html | 3 +- 8 files changed, 115 insertions(+), 16 deletions(-) diff --git a/core/lib/Thelia/Action/Customer.php b/core/lib/Thelia/Action/Customer.php index 8dd2eebee..f132a01da 100755 --- a/core/lib/Thelia/Action/Customer.php +++ b/core/lib/Thelia/Action/Customer.php @@ -26,6 +26,7 @@ namespace Thelia\Action; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Thelia\Core\Event\ActionEvent; use Thelia\Core\Event\CustomerCreateOrUpdateEvent; +use Thelia\Core\Event\CustomerEvent; use Thelia\Core\Event\TheliaEvents; use Thelia\Model\Customer as CustomerModel; use Thelia\Core\Event\CustomerLoginEvent; @@ -59,6 +60,13 @@ class Customer extends BaseAction implements EventSubscriberInterface } + public function delete(CustomerEvent $event) + { + $customer = $event->getCustomer(); + + $customer->delete(); + } + private function createOrUpdateCustomer(CustomerModel $customer, CustomerCreateOrUpdateEvent $event) { $customer->setDispatcher($this->getDispatcher()); @@ -144,6 +152,7 @@ class Customer extends BaseAction implements EventSubscriberInterface TheliaEvents::CUSTOMER_UPDATEACCOUNT => array("modify", 128), TheliaEvents::CUSTOMER_LOGOUT => array("logout", 128), TheliaEvents::CUSTOMER_LOGIN => array("login" , 128), + TheliaEvents::CUSTOMER_DELETEACCOUNT => array("delete", 128), ); } } diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index 60150b3fa..69d525020 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -47,6 +47,10 @@ \d+ + + Thelia\Controller\Admin\CustomerController::deleteAction + + diff --git a/core/lib/Thelia/Controller/Admin/CustomerController.php b/core/lib/Thelia/Controller/Admin/CustomerController.php index ab897d24b..322e3839d 100644 --- a/core/lib/Thelia/Controller/Admin/CustomerController.php +++ b/core/lib/Thelia/Controller/Admin/CustomerController.php @@ -25,6 +25,7 @@ namespace Thelia\Controller\Admin; use Propel\Runtime\Exception\PropelException; use Symfony\Component\Form\Form; use Thelia\Core\Event\CustomerCreateOrUpdateEvent; +use Thelia\Core\Event\CustomerEvent; use Thelia\Core\Event\TheliaEvents; use Thelia\Form\CustomerModification; use Thelia\Form\Exception\FormValidationException; @@ -39,22 +40,28 @@ class CustomerController extends BaseAdminController { public function indexAction() { - if (null !== $response = $this->checkAuth("admin.customers.view")) return $response; + if (null !== $response = $this->checkAuth("admin.customer.view")) return $response; return $this->render("customers", array("display_customer" => 20)); } public function viewAction($customer_id) { - if (null !== $response = $this->checkAuth("admin.customers.view")) return $response; + if (null !== $response = $this->checkAuth("admin.customer.view")) return $response; return $this->render("customer-edit", array( "customer_id" => $customer_id )); } + /** + * update customer action + * + * @param $customer_id + * @return mixed|\Symfony\Component\HttpFoundation\Response + */ public function updateAction($customer_id) { - if (null !== $response = $this->checkAuth("admin.customers.update")) return $response; + if (null !== $response = $this->checkAuth("admin.customer.update")) return $response; $message = false; @@ -108,6 +115,39 @@ class CustomerController extends BaseAdminController )); } + public function deleteAction() + { + if (null !== $response = $this->checkAuth("admin.customer.delete")) return $response; + + $message = null; + + try { + $customer_id = $this->getRequest()->get("customer_id"); + $customer = CustomerQuery::create()->findPk($customer_id); + + if(null === $customer) { + throw new \InvalidArgumentException("The customer you want to delete does not exists"); + } + + $event = new CustomerEvent($customer); + + $this->dispatch(TheliaEvents::CUSTOMER_DELETEACCOUNT, $event); + } catch(\Exception $e) { + $message = $e->getMessage(); + } + + $params = array( + "customer_page" => $this->getRequest()->get("customer_page", 1) + ); + + if ($message) { + $param["delete_error_message"] = $message; + } + + $this->redirectToRoute("admin.customers", $params); + + } + /** * @param $data * @return CustomerCreateOrUpdateEvent diff --git a/core/lib/Thelia/Core/Event/CustomerCreateOrUpdateEvent.php b/core/lib/Thelia/Core/Event/CustomerCreateOrUpdateEvent.php index 8269cecf3..d3ae6f62d 100755 --- a/core/lib/Thelia/Core/Event/CustomerCreateOrUpdateEvent.php +++ b/core/lib/Thelia/Core/Event/CustomerCreateOrUpdateEvent.php @@ -1,17 +1,35 @@ . */ +/* */ +/*************************************************************************************/ namespace Thelia\Core\Event; use Symfony\Component\EventDispatcher\Event; use Thelia\Model\Customer; +/** + * Class CustomerCreateOrUpdateEvent + * @package Thelia\Core\Event + * @author Manuel Raynaud + */ class CustomerCreateOrUpdateEvent extends ActionEvent { //base parameters for creating new customer diff --git a/core/lib/Thelia/Core/Event/TheliaEvents.php b/core/lib/Thelia/Core/Event/TheliaEvents.php index 4cbaad675..f712dd7ae 100755 --- a/core/lib/Thelia/Core/Event/TheliaEvents.php +++ b/core/lib/Thelia/Core/Event/TheliaEvents.php @@ -71,6 +71,11 @@ final class TheliaEvents */ const CUSTOMER_UPDATEACCOUNT = "action.updateCustomer"; + /** + * sent on customer removal + */ + const CUSTOMER_DELETEACCOUNT = "action.deleteCustomer"; + /** * sent when a customer need a new password */ @@ -103,6 +108,16 @@ final class TheliaEvents */ const AFTER_UPDATECUSTOMER = "action.after_updateCustomer"; + /** + * sent just before customer removal + */ + const BEFORE_DELETECUSTOMER = "action.before_updateCustomer"; + + /** + * sent just after customer removal + */ + const AFTER_DELETECUSTOMER = "action.after_deleteCustomer"; + // -- ADDRESS MANAGEMENT --------------------------------------------------------- /** * sent for address creation diff --git a/core/lib/Thelia/Model/Customer.php b/core/lib/Thelia/Model/Customer.php index bb30d18e2..f839d5f5b 100755 --- a/core/lib/Thelia/Model/Customer.php +++ b/core/lib/Thelia/Model/Customer.php @@ -246,7 +246,7 @@ class Customer extends BaseCustomer implements UserInterface */ public function preDelete(ConnectionInterface $con = null) { - $this->dispatchEvent(TheliaEvents::BEFORE_DELETECONFIG, new CustomerEvent($this)); + $this->dispatchEvent(TheliaEvents::BEFORE_DELETECUSTOMER, new CustomerEvent($this)); return true; } @@ -255,6 +255,6 @@ class Customer extends BaseCustomer implements UserInterface */ public function postDelete(ConnectionInterface $con = null) { - $this->dispatchEvent(TheliaEvents::AFTER_DELETECONFIG, new CustomerEvent($this)); + $this->dispatchEvent(TheliaEvents::AFTER_DELETECUSTOMER, new CustomerEvent($this)); } } diff --git a/templates/admin/default/customers.html b/templates/admin/default/customers.html index c0fe81973..799115bf3 100644 --- a/templates/admin/default/customers.html +++ b/templates/admin/default/customers.html @@ -260,7 +260,8 @@ {* Delete confirmation dialog *} {capture "delete_customer_dialog"} - + + {/capture} {include @@ -271,7 +272,18 @@ dialog_message = {intl l="Do you really want to delete this customer ?"} form_action = {url path='/admin/customer/delete'} - form_content = {$smarty.capture.delete_dialog nofilter} + form_content = {$smarty.capture.delete_customer_dialog nofilter} + form_id = "form_delete_customer" } +{/block} + +{block name="javascript-initialization"} + + + {/block} \ No newline at end of file diff --git a/templates/admin/default/includes/generic-confirm-dialog.html b/templates/admin/default/includes/generic-confirm-dialog.html index b5f3ad700..be1f4b63d 100644 --- a/templates/admin/default/includes/generic-confirm-dialog.html +++ b/templates/admin/default/includes/generic-confirm-dialog.html @@ -14,6 +14,7 @@ Parameters: form_action = the form action URL, subtitted by a click on OK button form_method = the form method, default "POST" form_content = the form content + form_id = the form id *} - + {$form_content nofilter} From c64b987e9b47047e11dabb92e5b51ee9beb6b2d8 Mon Sep 17 00:00:00 2001 From: mespeche Date: Thu, 12 Sep 2013 12:40:46 +0200 Subject: [PATCH 18/45] - Creation of order-edit view --- .../Thelia/Config/Resources/routing/admin.xml | 5 + .../Controller/Admin/OrderController.php | 8 + .../default/assets/less/thelia/thelia.less | 12 +- templates/admin/default/order-edit.html | 451 ++++++++++++++++++ templates/admin/default/orders.html | 6 +- 5 files changed, 478 insertions(+), 4 deletions(-) create mode 100644 templates/admin/default/order-edit.html diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index 5e34aec39..064d5d2b9 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -50,6 +50,11 @@ Thelia\Controller\Admin\OrderController::indexAction + + Thelia\Controller\Admin\OrderController::viewAction + \d+ + + diff --git a/core/lib/Thelia/Controller/Admin/OrderController.php b/core/lib/Thelia/Controller/Admin/OrderController.php index b7e2b00ce..b2047cc31 100644 --- a/core/lib/Thelia/Controller/Admin/OrderController.php +++ b/core/lib/Thelia/Controller/Admin/OrderController.php @@ -36,4 +36,12 @@ class OrderController extends BaseAdminController return $this->render("orders", array("display_order" => 20)); } + public function viewAction($order_id) + { + + return $this->render("order-edit", array( + "order_id" => $order_id + )); + } + } \ No newline at end of file diff --git a/templates/admin/default/assets/less/thelia/thelia.less b/templates/admin/default/assets/less/thelia/thelia.less index 8576272bf..d1619d924 100644 --- a/templates/admin/default/assets/less/thelia/thelia.less +++ b/templates/admin/default/assets/less/thelia/thelia.less @@ -201,13 +201,23 @@ border-bottom: 2px solid #A5CED8; margin-bottom: 0.5em; } - + // The action bar on the right .actions { text-align: right; } } +.tab-pane{ + caption, .title{ + margin-top: 0.5em; + + .btn{ + text-transform: none; + } + } +} + // The overall form container .form-container { diff --git a/templates/admin/default/order-edit.html b/templates/admin/default/order-edit.html new file mode 100644 index 000000000..603176fe6 --- /dev/null +++ b/templates/admin/default/order-edit.html @@ -0,0 +1,451 @@ +{extends file="admin-layout.tpl"} + +{block name="page-title"}{intl l='Edit an order'}{/block} + +{block name="check-permissions"}admin.order.edit{/block} + +{block name="main-content"} +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ {intl l='Information about order 01201303540354'} +
{intl l="Designation"}{intl l="Price"}{intl l="Quantity"}{intl l="Total"}
T-Shirt F T120.00 €360.00 €
T-Shirt F T120.00 €360.00 €
T-Shirt F T120.00 €360.00 €
Total180.00 €
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ {intl l='Information about the bill'} +
{intl l="Bill n°"}{intl l="Compagny"}{intl l="Firstname & Lastname"}{intl l="Date & Hour"}
0001TheliaDupont Jean11/01/2013 14:11:00
+
+ +
+

+ {intl l='Information about the carriage'} + + {intl l='Download pdf bill'} + +

+ +
+
{intl l="Mode of transportation"}
+
Colissimo
+
+
+
{intl l="Description"}
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ut, error, necessitatibus ipsam dolores ad quisquam provident sed repudiandae ullam quasi quae perferendis numquam voluptates doloribus laborum possimus dicta similique in?
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ {intl l='Information about the settlement'} +
{intl l="Type of payment"}Unknown
{intl l="Transaction reference"}141100
{intl l="Total order before discount"}60 €
{intl l="Discount"}10%
{intl l="Coupon code"}
{intl l="Total with discount"}50 €
{intl l="Freight"}6 €
{intl l="Total"}56 €
+ +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ {intl l='Billing address'} + + + +
{intl l="Title"}Mr
{intl l="Compagny"}Thelia
{intl l="Firstname"}Espeche
{intl l="Lastname"}Michaël
{intl l="Street address"}5, rue Rochon
{intl l="Additional address"}Lorem ipsum dolor sit amet
{intl l="Additional address"}Lorem ipsum dolor sit
{intl l="Zip code"}63000
{intl l="City"}Clermont-Fd
{intl l="Country"}France
{intl l="Phone"}01 02 03 04 05
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ {intl l='Delivery address'} + + + +
{intl l="Title"}Mr
{intl l="Compagny"}Thelia
{intl l="Firstname"}Espeche
{intl l="Lastname"}Michaël
{intl l="Street address"}5, rue Rochon
{intl l="Additional address"}Lorem ipsum dolor sit amet
{intl l="Additional address"}Lorem ipsum dolor sit
{intl l="Zip code"}63000
{intl l="City"}Clermont-Fd
{intl l="Country"}France
{intl l="Phone"}01 02 03 04 05
+
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ {intl l='Further information'} +
+ +
+
+ +
+
+ +
+
+
+
+ +
+ +
+
+
{intl l='Bill'} {intl l='Download bill to pdf'}
{intl l='Delivery'} {intl l='Download delivery to pdf'}
+
+ +
+ +
+ +
+
+ + + + + {* Update an Address *} + + {form name="thelia.address.update"} + + {* Capture the dialog body, to pass it to the generic dialog *} + {capture "edit_address_dialog"} + + {form_hidden_fields form=$form} + + {form_field form=$form field='label'} +
+ + +
+ {/form_field} + + {form_field form=$form field='company'} +
+ + +
+ {/form_field} + + {form_field form=$form field='title'} +
+ + + +
+ {/form_field} + + {form_field form=$form field='firstname'} +
+ + +
+ {/form_field} + + {form_field form=$form field='lastname'} +
+ + +
+ {/form_field} + + {form_field form=$form field='address1'} +
+ + +
+ +
+ {form_field form=$form field='address2'} + + {/form_field} +
+ +
+ {form_field form=$form field='address3'} + + {/form_field} +
+ {/form_field} + + {form_field form=$form field='zipcode'} +
+ + +
+ {/form_field} + + {form_field form=$form field='city'} +
+ + +
+ {/form_field} + + {form_field form=$form field='country'} +
+ + +
+ {/form_field} + + {/capture} + + {include + file = "includes/generic-create-dialog.html" + + dialog_id = "edit_address_dialog" + dialog_title = {intl l="Edit an address"} + dialog_body = {$smarty.capture.edit_address_dialog nofilter} + + dialog_ok_label = {intl l="Edit this address"} + dialog_cancel_label = {intl l="Cancel"} + + form_action = {url path='/admin/address/update'} + form_enctype = {form_enctype form=$form} + form_error_message = $form_error_message + } + + {/form} + +{/block} \ No newline at end of file diff --git a/templates/admin/default/orders.html b/templates/admin/default/orders.html index 8693f2a33..8450bcd1d 100644 --- a/templates/admin/default/orders.html +++ b/templates/admin/default/orders.html @@ -60,7 +60,7 @@
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.orders.edit"} - + {/loop} {loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.orders.delete"} @@ -84,7 +84,7 @@
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.orders.edit"} - + {/loop} {loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.orders.delete"} @@ -108,7 +108,7 @@
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.orders.edit"} - + {/loop} {loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.orders.delete"} From 485e6dc29b6437b274cf7e29dfc5ad0a5e6ede55 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Thu, 12 Sep 2013 12:43:44 +0200 Subject: [PATCH 19/45] translate error message --- core/lib/Thelia/Controller/Admin/CustomerController.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/lib/Thelia/Controller/Admin/CustomerController.php b/core/lib/Thelia/Controller/Admin/CustomerController.php index 322e3839d..9209cb361 100644 --- a/core/lib/Thelia/Controller/Admin/CustomerController.php +++ b/core/lib/Thelia/Controller/Admin/CustomerController.php @@ -30,6 +30,7 @@ use Thelia\Core\Event\TheliaEvents; use Thelia\Form\CustomerModification; use Thelia\Form\Exception\FormValidationException; use Thelia\Model\CustomerQuery; +use Thelia\Core\Translation\Translator; /** * Class CustomerController @@ -126,7 +127,7 @@ class CustomerController extends BaseAdminController $customer = CustomerQuery::create()->findPk($customer_id); if(null === $customer) { - throw new \InvalidArgumentException("The customer you want to delete does not exists"); + throw new \InvalidArgumentException(Translator::getInstance("The customer you want to delete does not exists")); } $event = new CustomerEvent($customer); @@ -141,7 +142,7 @@ class CustomerController extends BaseAdminController ); if ($message) { - $param["delete_error_message"] = $message; + $params["delete_error_message"] = $message; } $this->redirectToRoute("admin.customers", $params); From 024866a44559e64e315b1d290b9931ce0cdc1b54 Mon Sep 17 00:00:00 2001 From: mespeche Date: Thu, 12 Sep 2013 12:49:11 +0200 Subject: [PATCH 20/45] Delete form on the orders view --- templates/admin/default/orders.html | 190 ++++++++++++++-------------- 1 file changed, 94 insertions(+), 96 deletions(-) diff --git a/templates/admin/default/orders.html b/templates/admin/default/orders.html index 8450bcd1d..947c615a3 100644 --- a/templates/admin/default/orders.html +++ b/templates/admin/default/orders.html @@ -17,119 +17,117 @@ {module_include location='orders_top'}
-
-
-
- - - - - - - - - - - - {module_include location='orders_table_header'} +
+
+
- {intl l='Orders'} - {loop type="auth" name="can_create" roles="ADMIN" permissions="admin.orders.create"} - - - - {/loop} -
{intl l="Order n°"}{intl l="Date & Hour"}{intl l="Compagny"}{intl l="Name"}{intl l="Amount"}{intl l="Status"}
+ + + + + + + + + + + {module_include location='orders_table_header'} - - - + + + - - + + - - - - - - + + + + + + - {module_include location='orders_table_row'} + {module_include location='orders_table_row'} - - - + {loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.orders.delete"} + + {/loop} + + + + - - - - - - + + + + + + - {module_include location='orders_table_row'} + {module_include location='orders_table_row'} - - - + {loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.orders.delete"} + + {/loop} + + + + - - - - - - + + + + + + - {module_include location='orders_table_row'} + {module_include location='orders_table_row'} - - - - - - -
+ {intl l='Orders'} + {loop type="auth" name="can_create" roles="ADMIN" permissions="admin.orders.create"} + + + + {/loop} +
{intl l="Order n°"}{intl l="Date & Hour"}{intl l="Compagny"}{intl l="Name"}{intl l="Amount"}{intl l="Status"}{intl l="Actions"}
{intl l="Actions"}
0123045012304511/09/2013 10:24:31TheliaDupont251 €Paid0123045012304511/09/2013 10:24:31TheliaDupont251 €Paid -
+
+
- {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.orders.edit"} - - {/loop} + {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.orders.edit"} + + {/loop} - {loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.orders.delete"} - - {/loop} -
-
0123045012304511/09/2013 10:24:31TheliaDupont251 €Canceled0123045012304511/09/2013 10:24:31TheliaDupont251 €Canceled -
+
+
- {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.orders.edit"} - - {/loop} + {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.orders.edit"} + + {/loop} - {loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.orders.delete"} - - {/loop} -
-
0123045012304511/09/2013 10:24:31TheliaDupont251 €Current0123045012304511/09/2013 10:24:31TheliaDupont251 €Current -
+
+
- {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.orders.edit"} - - {/loop} + {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.orders.edit"} + + {/loop} - {loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.orders.delete"} - - {/loop} -
-
-
-
+ {loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.orders.delete"} + + {/loop} +
+ + + + + + + +
From eeee25d6f59842a0f585339b1456d923d6ff59ca Mon Sep 17 00:00:00 2001 From: mespeche Date: Thu, 12 Sep 2013 12:52:13 +0200 Subject: [PATCH 21/45] Change script file declaration order for bootstrap-editable fix --- templates/admin/default/admin-layout.tpl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/templates/admin/default/admin-layout.tpl b/templates/admin/default/admin-layout.tpl index 188ba75f4..11e85c60f 100644 --- a/templates/admin/default/admin-layout.tpl +++ b/templates/admin/default/admin-layout.tpl @@ -228,13 +228,14 @@ {block name="after-javascript-include"}{/block} + {javascripts file='assets/js/bootstrap/bootstrap.js'} + + {/javascripts} + {block name="javascript-initialization"}{/block} {* Modules scripts are included now *} {module_include location='footer_js'} - {javascripts file='assets/js/bootstrap/bootstrap.js'} - - {/javascripts} \ No newline at end of file From 0671c2ce7dc3f00829738ab938a1cb0199b97cac Mon Sep 17 00:00:00 2001 From: franck Date: Thu, 12 Sep 2013 13:01:04 +0200 Subject: [PATCH 22/45] Continuer attributes management --- core/lib/Thelia/Config/Resources/config.xml | 4 ++ .../Thelia/Config/Resources/routing/admin.xml | 40 +++++++++++++------ core/lib/Thelia/Core/Event/TheliaEvents.php | 31 ++++++++++++++ templates/admin/default/admin-layout.tpl | 10 ++--- 4 files changed, 68 insertions(+), 17 deletions(-) diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index 74e1f4629..e5493cdfd 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -66,6 +66,10 @@
+ + + + diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index 8eaeb2547..7cbb04b08 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -79,12 +79,8 @@ - - - - - + Thelia\Controller\Admin\CouponController::browseAction @@ -105,10 +101,6 @@ - - - - @@ -197,12 +189,36 @@ - + Thelia\Controller\Admin\AttributeController::defaultAction - - Thelia\Controller\Admin\AttributeController::updateAction + + Thelia\Controller\Admin\AttributeController::createAction + + + + Thelia\Controller\Admin\AttributeController::createValueAction + + + + Thelia\Controller\Admin\AttributeController::changeAction + + + + Thelia\Controller\Admin\AttributeController::saveChangeAction + + + + Thelia\Controller\Admin\AttributeController::deleteAction + + + + Thelia\Controller\Admin\AttributeController::deleteValueAction + + + + Thelia\Controller\Admin\AttributeController::updatePositionAction diff --git a/core/lib/Thelia/Core/Event/TheliaEvents.php b/core/lib/Thelia/Core/Event/TheliaEvents.php index c19d3a400..fa6b3e0c3 100755 --- a/core/lib/Thelia/Core/Event/TheliaEvents.php +++ b/core/lib/Thelia/Core/Event/TheliaEvents.php @@ -358,4 +358,35 @@ final class TheliaEvents const BEFORE_DELETECURRENCY = "action.before_deleteCurrency"; const AFTER_DELETECURRENCY = "action.after_deleteCurrency"; + // -- Attributes management --------------------------------------------- + + const ATTRIBUTE_CREATE = "action.createAttribute"; + const ATTRIBUTE_UPDATE = "action.updateAttribute"; + const ATTRIBUTE_DELETE = "action.deleteAttribute"; + const ATTRIBUTE_UPDATE_POSITION = "action.updateAttributePosition"; + + const BEFORE_CREATEATTRIBUTE = "action.before_createAttribute"; + const AFTER_CREATEATTRIBUTE = "action.after_createAttribute"; + + const BEFORE_UPDATEATTRIBUTE = "action.before_updateAttribute"; + const AFTER_UPDATEATTRIBUTE = "action.after_updateAttribute"; + + const BEFORE_DELETEATTRIBUTE = "action.before_deleteAttribute"; + const AFTER_DELETEATTRIBUTE = "action.after_deleteAttribute"; + + // -- Attributes values management ---------------------------------------- + + const ATTRIBUTE_VALUE_CREATE = "action.createAttributeValue"; + const ATTRIBUTE_VALUE_UPDATE = "action.updateAttributeValue"; + const ATTRIBUTE_VALUE_DELETE = "action.deleteAttributeValue"; + const ATTRIBUTE_VALUE_UPDATE_POSITION = "action.updateAttributeValuePosition"; + + const BEFORE_CREATEATTRIBUTE_VALUE = "action.before_createAttributeValue"; + const AFTER_CREATEATTRIBUTE_VALUE = "action.after_createAttributeValue"; + + const BEFORE_UPDATEATTRIBUTE_VALUE = "action.before_updateAttributeValue"; + const AFTER_UPDATEATTRIBUTE_VALUE = "action.after_updateAttributeValue"; + + const BEFORE_DELETEATTRIBUTE_VALUE = "action.before_deleteAttributeValue"; + const AFTER_DELETEATTRIBUTE_VALUE = "action.after_deleteAttributeValue"; } diff --git a/templates/admin/default/admin-layout.tpl b/templates/admin/default/admin-layout.tpl index 942557600..334f95d44 100644 --- a/templates/admin/default/admin-layout.tpl +++ b/templates/admin/default/admin-layout.tpl @@ -144,9 +144,9 @@ {/loop} - {loop name="menu-auth-discount" type="auth" roles="ADMIN" permissions="admin.discount.view"} -
  • - {intl l="Discount"} + {loop name="menu-auth-coupon" type="auth" roles="ADMIN" permissions="admin.coupon.view"} +
  • + {intl l="Coupons"}
  • {/loop} @@ -222,10 +222,10 @@ {block name="before-javascript-include"}{/block} - +{* {debugbar_renderjs} {debugbar_renderresult} - +*} {block name="after-javascript-include"}{/block} {block name="javascript-initialization"}{/block} From c85ec2a9e3128858a277d33e6b8288794425cbc1 Mon Sep 17 00:00:00 2001 From: franck Date: Thu, 12 Sep 2013 13:02:40 +0200 Subject: [PATCH 23/45] Created AbstractCrudController, and refactored existing controllers --- core/lib/Thelia/Action/Currency.php | 16 +- core/lib/Thelia/Config/Resources/action.xml | 5 + .../Controller/Admin/AttributeController.php | 362 ++++++++++++++++- .../Controller/Admin/ConfigController.php | 2 +- .../Controller/Admin/CurrencyController.php | 377 ++++++------------ .../Controller/Admin/MessageController.php | 2 +- .../Event/CategoryUpdatePositionEvent.php | 28 -- .../Event/CurrencyUpdatePositionEvent.php | 28 -- ...ityEvent.php => ToggleVisibilityEvent.php} | 2 +- ...itionEvent.php => UpdatePositionEvent.php} | 2 +- .../Thelia/Core/Template/Loop/Attribute.php | 8 +- .../Thelia/Core/Template/Loop/Category.php | 8 +- core/lib/Thelia/Model/Attribute.php | 62 +++ core/lib/Thelia/Model/AttributeAv.php | 80 +++- .../Model/Tools/PositionManagementTrait.php | 1 + install/INSTALL-TODO.txt | 1 + templates/admin/default/attributes.html | 266 ++++++++++++ templates/admin/default/categories.html | 7 +- templates/admin/default/category-edit.html | 4 +- templates/admin/default/configuration.html | 18 +- templates/admin/default/coupon-list.html | 8 +- templates/admin/default/currencies.html | 5 + templates/admin/default/currency-edit.html | 2 +- templates/admin/default/customer-edit.html | 100 ++--- .../default/includes/generic-js-dialog.html | 2 +- .../default/includes/inner-form-toolbar.html | 7 +- templates/admin/default/message-edit.html | 24 +- templates/admin/default/messages.html | 6 + .../admin/default/product-attributes.html | 142 ------- templates/admin/default/variable-edit.html | 18 +- templates/admin/default/variables.html | 6 + 31 files changed, 1033 insertions(+), 566 deletions(-) delete mode 100644 core/lib/Thelia/Core/Event/CategoryUpdatePositionEvent.php delete mode 100644 core/lib/Thelia/Core/Event/CurrencyUpdatePositionEvent.php rename core/lib/Thelia/Core/Event/{BaseToggleVisibilityEvent.php => ToggleVisibilityEvent.php} (97%) rename core/lib/Thelia/Core/Event/{BaseUpdatePositionEvent.php => UpdatePositionEvent.php} (98%) create mode 100644 templates/admin/default/attributes.html delete mode 100644 templates/admin/default/product-attributes.html diff --git a/core/lib/Thelia/Action/Currency.php b/core/lib/Thelia/Action/Currency.php index 619374902..b73dd0184 100644 --- a/core/lib/Thelia/Action/Currency.php +++ b/core/lib/Thelia/Action/Currency.php @@ -34,7 +34,7 @@ use Thelia\Core\Event\CurrencyUpdateEvent; use Thelia\Core\Event\CurrencyCreateEvent; use Thelia\Core\Event\CurrencyDeleteEvent; use Thelia\Model\ConfigQuery; -use Thelia\Core\Event\CurrencyUpdatePositionEvent; +use Thelia\Core\Event\UpdatePositionEvent; class Currency extends BaseAction implements EventSubscriberInterface { @@ -164,21 +164,25 @@ class Currency extends BaseAction implements EventSubscriberInterface * * @param CategoryChangePositionEvent $event */ - public function updatePosition(CurrencyUpdatePositionEvent $event) + public function updatePosition(UpdatePositionEvent $event) { - if (null !== $currency = CurrencyQuery::create()->findOneById($event->getObjectId())) { +echo "update =".$event->getObjectId(); + + if (null !== $currency = CurrencyQuery::create()->findPk($event->getObjectId())) { $currency->setDispatcher($this->getDispatcher()); $mode = $event->getMode(); + echo "loaded $mode !"; - if ($mode == CurrencyUpdatePositionEvent::POSITION_ABSOLUTE) + if ($mode == UpdatePositionEvent::POSITION_ABSOLUTE) return $currency->changeAbsolutePosition($event->getPosition()); - else if ($mode == CurrencyUpdatePositionEvent::POSITION_UP) + else if ($mode == UpdatePositionEvent::POSITION_UP) return $currency->movePositionUp(); - else if ($mode == CurrencyUpdatePositionEvent::POSITION_DOWN) + else if ($mode == UpdatePositionEvent::POSITION_DOWN) return $currency->movePositionDown(); } + exit; } /** diff --git a/core/lib/Thelia/Config/Resources/action.xml b/core/lib/Thelia/Config/Resources/action.xml index dd43bbb91..07e4637ee 100755 --- a/core/lib/Thelia/Config/Resources/action.xml +++ b/core/lib/Thelia/Config/Resources/action.xml @@ -57,6 +57,11 @@ + + + + + diff --git a/core/lib/Thelia/Controller/Admin/AttributeController.php b/core/lib/Thelia/Controller/Admin/AttributeController.php index 50e32955d..0e1633210 100644 --- a/core/lib/Thelia/Controller/Admin/AttributeController.php +++ b/core/lib/Thelia/Controller/Admin/AttributeController.php @@ -1,7 +1,7 @@ . */ +/* along with this program. If not, see . */ /* */ /*************************************************************************************/ namespace Thelia\Controller\Admin; +use Thelia\Core\Event\AttributeDeleteEvent; +use Thelia\Core\Event\TheliaEvents; +use Thelia\Tools\URL; +use Thelia\Core\Event\AttributeUpdateEvent; +use Thelia\Core\Event\AttributeCreateEvent; +use Thelia\Log\Tlog; +use Thelia\Form\Exception\FormValidationException; +use Thelia\Core\Security\Exception\AuthorizationException; +use Thelia\Model\AttributeQuery; +use Thelia\Form\AttributeModificationForm; +use Thelia\Form\AttributeCreationForm; +use Thelia\Core\Event\AttributeUpdatePositionEvent; +use Thelia\Form\AttributeValueCreationForm; +use Thelia\Core\Event\AttributeValueCreateEvent; +use Thelia\Core\Event\AttributeValueDeleteEvent; + /** - * Manages messages sent by mail + * Manages product attributes * * @author Franck Allimant */ class AttributeController extends BaseAdminController { /** - * The default action is displaying the attributes list. + * Render the attributes list, ensuring the sort order is set. * * @return Symfony\Component\HttpFoundation\Response the response */ - public function defaultAction() - { - if (null !== $response = $this->checkAuth("admin.configuration.attributes.view")) return $response; - return $this->render('product-attributes'); + protected function renderList() { + + // Find the current order + $order = $this->getRequest()->get( + 'order', + $this->getSession()->get('admin.attribute_order', 'manual') + ); + + // Store the current sort order in session + $this->getSession()->set('admin.attribute_order', $order); + + return $this->render('attributes', array('order' => $order)); } - public function updateAction() - { - if (null !== $response = $this->checkAuth("admin.configuration.attributes.update")) return $response; - return $this->render('product-attributes-edit'); + /** + * The default action is displaying the product attributes list. + * + * @return Symfony\Component\HttpFoundation\Response the response + */ + public function defaultAction() { + + if (null !== $response = $this->checkAuth("admin.configuration.attributes.view")) return $response; + + return $this->renderList(); } -} + + /** + * Create a new product attribute object + * + * @return Symfony\Component\HttpFoundation\Response the response + */ + public function createAction() { + + // Check current user authorization + if (null !== $response = $this->checkAuth("admin.configuration.attributes.create")) return $response; + + $error_msg = false; + + // Create the Creation Form + $creationForm = new AttributeCreationForm($this->getRequest()); + + try { + + // Validate the form, create the AttributeCreation event and dispatch it. + $form = $this->validateForm($creationForm, "POST"); + + $data = $form->getData(); + + $createEvent = new AttributeCreateEvent(); + + $createEvent + ->setTitle($data['title']) + ->setLocale($data["locale"]) + ->setAddToAllTemplates($data['add_to_all']) + ; + + $this->dispatch(TheliaEvents::ATTRIBUTE_CREATE, $createEvent); + + if (! $createEvent->hasAttribute()) throw new \LogicException($this->getTranslator()->trans("No product attribute was created.")); + + $createdObject = $createEvent->getAttribute(); + + // Log product attribute creation + $this->adminLogAppend(sprintf("Attribute %s (ID %s) created", $createdObject->getTitle(), $createdObject->getId())); + + // Substitute _ID_ in the URL with the ID of the created object + $successUrl = str_replace('_ID_', $createdObject->getId(), $creationForm->getSuccessUrl()); + + // Redirect to the success URL + $this->redirect($successUrl); + } + catch (FormValidationException $ex) { + // Form cannot be validated + $error_msg = $this->createStandardFormValidationErrorMessage($ex); + } + catch (\Exception $ex) { + // Any other error + $error_msg = $ex->getMessage(); + } + + $this->setupFormErrorContext("product attribute creation", $error_msg, $creationForm, $ex); + + // At this point, the form has error, and should be redisplayed. + return $this->renderList(); + } + + /** + * Create a new product attribute value object + * + * @return Symfony\Component\HttpFoundation\Response the response + */ + public function createValueAction() { + + // Check current user authorization + if (null !== $response = $this->checkAuth("admin.configuration.attribute-values.create")) return $response; + + $error_msg = false; + + // Create the Creation Form + $creationForm = new AttributeValueCreationForm($this->getRequest()); + + try { + + // Validate the form, create the AttributeCreation event and dispatch it. + $form = $this->validateForm($creationForm, "POST"); + + $data = $form->getData(); + + $createEvent = new AttributeValueCreateEvent(); + + $createEvent + ->setTitle($data['title']) + ->setLocale($data["locale"]) + ->setAttributeId($data["attribute_id"]) + ; + + $this->dispatch(TheliaEvents::ATTRIBUTE_VALUE_CREATE, $createEvent); + + if (! $createEvent->hasAttribute()) throw new \LogicException($this->getTranslator()->trans("No product attribute value was created.")); + + $createdObject = $createEvent->getAttributeValue(); + + // Log product attribute creation + $this->adminLogAppend(sprintf("Attribute value %s (ID %s) created", $createdObject->getTitle(), $createdObject->getId())); + + // Redirect to the success URL + $this->redirect($creationForm->getSuccessUrl()); + } + catch (FormValidationException $ex) { + // Form cannot be validated + $error_msg = $this->createStandardFormValidationErrorMessage($ex); + } + catch (\Exception $ex) { + // Any other error + $error_msg = $ex->getMessage(); + } + + $this->setupFormErrorContext("product attribute value creation", $error_msg, $creationForm, $ex); + + // At this point, the form has error, and should be redisplayed on the edition page + return $this->render('attribute-edit', array('attribute_id' => $this->getRequest()->get('attribute_id'))); + } + + /** + * Load a product attribute object for modification, and display the edit template. + * + * @return Symfony\Component\HttpFoundation\Response the response + */ + public function changeAction() { + + // Check current user authorization + if (null !== $response = $this->checkAuth("admin.configuration.attributes.update")) return $response; + + // Load the product attribute object + $attribute = AttributeQuery::create() + ->joinWithI18n($this->getCurrentEditionLocale()) + ->findOneById($this->getRequest()->get('attribute_id')); + + if ($attribute != null) { + + // Prepare the data that will hydrate the form + $data = array( + 'id' => $attribute->getId(), + 'locale' => $attribute->getLocale(), + 'title' => $attribute->getTitle(), + 'chapo' => $attribute->getChapo(), + 'description' => $attribute->getDescription(), + 'postscriptum' => $attribute->getPostscriptum() + ); + + // Setup the object form + $changeForm = new AttributeModificationForm($this->getRequest(), "form", $data); + + // Pass it to the parser + $this->getParserContext()->addForm($changeForm); + } + + // Render the edition template. + return $this->render('attribute-edit', array('attribute_id' => $this->getRequest()->get('attribute_id'))); + } + + /** + * Save changes on a modified product attribute object, and either go back to the product attribute list, or stay on the edition page. + * + * @return Symfony\Component\HttpFoundation\Response the response + */ + public function saveChangeAction() { + + // Check current user authorization + if (null !== $response = $this->checkAuth("admin.configuration.attributes.update")) return $response; + + $error_msg = false; + + // Create the form from the request + $changeForm = new AttributeModificationForm($this->getRequest()); + + // Get the attribute ID + $attribute_id = $this->getRequest()->get('attribute_id'); + + try { + + // Check the form against constraints violations + $form = $this->validateForm($changeForm, "POST"); + + // Get the form field values + $data = $form->getData(); + + $changeEvent = new AttributeUpdateEvent($data['id']); + + // Create and dispatch the change event + $changeEvent + ->setLocale($data["locale"]) + ->setTitle($data['title']) + ->setChapo($data['chapo']) + ->setDescription($data['description']) + ->setPostscriptum($data['postscriptum']) + ; + + $this->dispatch(TheliaEvents::ATTRIBUTE_UPDATE, $changeEvent); + + if (! $changeEvent->hasAttribute()) throw new \LogicException($this->getTranslator()->trans("No product attribute was updated.")); + + // Log product attribute modification + $changedObject = $changeEvent->getAttribute(); + + $this->adminLogAppend(sprintf("Attribute %s (ID %s) modified", $changedObject->getTitle(), $changedObject->getId())); + + // If we have to stay on the same page, do not redirect to the succesUrl, + // just redirect to the edit page again. + if ($this->getRequest()->get('save_mode') == 'stay') { + $this->redirectToRoute( + "admin.configuration.attributes.update", + array('attribute_id' => $attribute_id) + ); + } + + // Redirect to the success URL + $this->redirect($changeForm->getSuccessUrl()); + } + catch (FormValidationException $ex) { + // Form cannot be validated + $error_msg = $this->createStandardFormValidationErrorMessage($ex); + } + catch (\Exception $ex) { + // Any other error + $error_msg = $ex->getMessage(); + } + + $this->setupFormErrorContext("product attribute modification", $error_msg, $changeForm, $ex); + + // At this point, the form has errors, and should be redisplayed. + return $this->render('attribute-edit', array('attribute_id' => $attribute_id)); + } + + /** + * Update product attribute position + */ + public function updatePositionAction() { + // Check current user authorization + if (null !== $response = $this->checkAuth("admin.configuration.attributes.update")) return $response; + + try { + $mode = $this->getRequest()->get('mode', null); + + if ($mode == 'up') + $mode = AttributeUpdatePositionEvent::POSITION_UP; + else if ($mode == 'down') + $mode = AttributeUpdatePositionEvent::POSITION_DOWN; + else + $mode = AttributeUpdatePositionEvent::POSITION_ABSOLUTE; + + $position = $this->getRequest()->get('position', null); + + $event = new AttributeUpdatePositionEvent( + $this->getRequest()->get('attribute_id', null), + $mode, + $this->getRequest()->get('position', null) + ); + + $this->dispatch(TheliaEvents::ATTRIBUTE_UPDATE_POSITION, $event); + } + catch (\Exception $ex) { + // Any error + return $this->errorPage($ex); + } + + $this->redirectToRoute('admin.configuration.attributes.default'); + } + + + /** + * Delete a product attribute object + * + * @return Symfony\Component\HttpFoundation\Response the response + */ + public function deleteAction() { + + // Check current user authorization + if (null !== $response = $this->checkAuth("admin.configuration.product attributes.delete")) return $response; + + // Get the product attribute id, and dispatch the delet request + $event = new AttributeDeleteEvent($this->getRequest()->get('attribute_id')); + + $this->dispatch(TheliaEvents::ATTRIBUTE_DELETE, $event); + + if ($event->hasAttribute()) + $this->adminLogAppend(sprintf("Attribute %s (ID %s) deleted", $event->getAttribute()->getTitle(), $event->getAttribute()->getId())); + + $this->redirectToRoute('admin.configuration.attributes.default'); + } + + /** + * Delete a product attribute value object + * + * @return Symfony\Component\HttpFoundation\Response the response + */ + public function deleteValueAction() { + + // Check current user authorization + if (null !== $response = $this->checkAuth("admin.configuration.product attribute-values.delete")) return $response; + + // Get the product attribute id, and dispatch the delet request + $event = new AttributeValueDeleteEvent($this->getRequest()->get('value_id')); + + $this->dispatch(TheliaEvents::ATTRIBUTE_VALUE_DELETE, $event); + + if ($event->hasAttributeValue()) + $this->adminLogAppend(sprintf("Attribute value %s (ID %s) deleted", $event->getAttributeValue()->getTitle(), $event->getAttributeValue()->getId())); + + $this->redirectToRoute('admin.configuration.attributes.default'); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Controller/Admin/ConfigController.php b/core/lib/Thelia/Controller/Admin/ConfigController.php index 397266677..785920562 100644 --- a/core/lib/Thelia/Controller/Admin/ConfigController.php +++ b/core/lib/Thelia/Controller/Admin/ConfigController.php @@ -288,7 +288,7 @@ class ConfigController extends BaseAdminController $this->dispatch(TheliaEvents::CONFIG_DELETE, $event); if ($event->hasConfig()) - $this->adminLogAppend(sprintf("Variable %s (ID %s) modified", $event->getConfig()->getName(), $event->getConfig()->getId())); + $this->adminLogAppend(sprintf("Variable %s (ID %s) deleted", $event->getConfig()->getName(), $event->getConfig()->getId())); $this->redirectToRoute('admin.configuration.variables.default'); } diff --git a/core/lib/Thelia/Controller/Admin/CurrencyController.php b/core/lib/Thelia/Controller/Admin/CurrencyController.php index ff2db0ab2..ae1005432 100644 --- a/core/lib/Thelia/Controller/Admin/CurrencyController.php +++ b/core/lib/Thelia/Controller/Admin/CurrencyController.php @@ -25,219 +25,167 @@ namespace Thelia\Controller\Admin; use Thelia\Core\Event\CurrencyDeleteEvent; use Thelia\Core\Event\TheliaEvents; -use Thelia\Tools\URL; use Thelia\Core\Event\CurrencyUpdateEvent; use Thelia\Core\Event\CurrencyCreateEvent; -use Thelia\Form\Exception\FormValidationException; use Thelia\Model\CurrencyQuery; use Thelia\Form\CurrencyModificationForm; use Thelia\Form\CurrencyCreationForm; -use Thelia\Core\Event\CurrencyUpdatePositionEvent; +use Thelia\Core\Event\UpdatePositionEvent; /** * Manages currencies sent by mail * * @author Franck Allimant */ -class CurrencyController extends BaseAdminController +class CurrencyController extends AbstractCrudController { - /** - * Render the currencies list, ensuring the sort order is set. - * - * @return Symfony\Component\HttpFoundation\Response the response - */ - protected function renderList() - { - // Find the current order - $order = $this->getRequest()->get( - 'order', - $this->getSession()->get('admin.currency_order', 'manual') + public function __construct() { + parent::__construct( + 'currency', + 'manual', + + 'admin.configuration.currencies.view', + 'admin.configuration.currencies.create', + 'admin.configuration.currencies.update', + 'admin.configuration.currencies.delete', + + TheliaEvents::CURRENCY_CREATE, + TheliaEvents::CURRENCY_UPDATE, + TheliaEvents::CURRENCY_DELETE, + null, // No visibility toggle + TheliaEvents::CURRENCY_UPDATE_POSITION + ); + } + + protected function getCreationForm() { + return new CurrencyCreationForm($this->getRequest()); + } + + protected function getUpdateForm() { + return new CurrencyModificationForm($this->getRequest()); + } + + protected function getCreationEvent($formData) { + $createEvent = new CurrencyCreateEvent(); + + $createEvent + ->setCurrencyName($formData['name']) + ->setLocale($formData["locale"]) + ->setSymbol($formData['symbol']) + ->setCode($formData['code']) + ->setRate($formData['rate']) + ; + + return $createEvent; + } + + protected function getUpdateEvent($formData) { + $changeEvent = new CurrencyUpdateEvent($formData['id']); + + // Create and dispatch the change event + $changeEvent + ->setCurrencyName($formData['name']) + ->setLocale($formData["locale"]) + ->setSymbol($formData['symbol']) + ->setCode($formData['code']) + ->setRate($formData['rate']) + ; + + return $changeEvent; + } + + protected function createUpdatePositionEvent($positionChangeMode, $positionValue) { + + return new UpdatePositionEvent( + $this->getRequest()->get('currency_id', null), + $positionChangeMode, + $positionValue + ); + } + + protected function createToggleVisibilityEvent() { + + return new ToggleVisibilityEvent($this->getRequest()->get('currency_id', null)); + } + + protected function getDeleteEvent() { + return new CurrencyDeleteEvent($this->getRequest()->get('currency_id')); + } + + protected function eventContainsObject($event) { + return $event->hasCurrency(); + } + + protected function hydrateObjectForm($object) { + + // Prepare the data that will hydrate the form + $data = array( + 'id' => $object->getId(), + 'name' => $object->getName(), + 'locale' => $object->getLocale(), + 'code' => $object->getCode(), + 'symbol' => $object->getSymbol(), + 'rate' => $object->getRate() ); - // Store the current sort order in session - $this->getSession()->set('admin.currency_order', $order); - - return $this->render('currencies', array('order' => $order)); + // Setup the object form + return new CurrencyModificationForm($this->getRequest(), "form", $data); } - /** - * The default action is displaying the currencies list. - * - * @return Symfony\Component\HttpFoundation\Response the response - */ - public function defaultAction() - { - if (null !== $response = $this->checkAuth("admin.configuration.currencies.view")) return $response; - return $this->renderList(); + protected function getObjectFromEvent($event) { + return $event->hasCurrency() ? $event->getCurrency() : null; } - /** - * Create a new currency object - * - * @return Symfony\Component\HttpFoundation\Response the response - */ - public function createAction() - { - // Check current user authorization - if (null !== $response = $this->checkAuth("admin.configuration.currencies.create")) return $response; - - $error_msg = false; - - // Create the Creation Form - $creationForm = new CurrencyCreationForm($this->getRequest()); - - try { - - // Validate the form, create the CurrencyCreation event and dispatch it. - $form = $this->validateForm($creationForm, "POST"); - - $data = $form->getData(); - - $createEvent = new CurrencyCreateEvent(); - - $createEvent - ->setCurrencyName($data['name']) - ->setLocale($data["locale"]) - ->setSymbol($data['symbol']) - ->setCode($data['code']) - ->setRate($data['rate']) - ; - - $this->dispatch(TheliaEvents::CURRENCY_CREATE, $createEvent); - - if (! $createEvent->hasCurrency()) throw new \LogicException($this->getTranslator()->trans("No currency was created.")); - - $createdObject = $createEvent->getCurrency(); - - // Log currency creation - $this->adminLogAppend(sprintf("Currency %s (ID %s) created", $createdObject->getName(), $createdObject->getId())); - - // Substitute _ID_ in the URL with the ID of the created object - $successUrl = str_replace('_ID_', $createdObject->getId(), $creationForm->getSuccessUrl()); - - // Redirect to the success URL - $this->redirect($successUrl); - } catch (FormValidationException $ex) { - // Form cannot be validated - $error_msg = $this->createStandardFormValidationErrorMessage($ex); - } catch (\Exception $ex) { - // Any other error - $error_msg = $ex->getMessage(); - } - - $this->setupFormErrorContext("currency creation", $error_msg, $creationForm, $ex); - - // At this point, the form has error, and should be redisplayed. - return $this->renderList(); + protected function getExistingObject() { + return CurrencyQuery::create() + ->joinWithI18n($this->getCurrentEditionLocale()) + ->findOneById($this->getRequest()->get('currency_id')); } - /** - * Load a currency object for modification, and display the edit template. - * - * @return Symfony\Component\HttpFoundation\Response the response - */ - public function changeAction() - { - // Check current user authorization - if (null !== $response = $this->checkAuth("admin.configuration.currencies.update")) return $response; + protected function getObjectLabel($object) { + return $object->getName(); + } - // Load the currency object - $currency = CurrencyQuery::create() - ->joinWithI18n($this->getCurrentEditionLocale()) - ->findOneById($this->getRequest()->get('currency_id')); + protected function getObjectId($object) { + return $object->getId(); + } - if ($currency != null) { + protected function renderListTemplate($currentOrder) { + return $this->render('currencies', array('order' => $currentOrder)); + } - // Prepare the data that will hydrate the form - $data = array( - 'id' => $currency->getId(), - 'name' => $currency->getName(), - 'locale' => $currency->getLocale(), - 'code' => $currency->getCode(), - 'symbol' => $currency->getSymbol(), - 'rate' => $currency->getRate() - ); - - // Setup the object form - $changeForm = new CurrencyModificationForm($this->getRequest(), "form", $data); - - // Pass it to the parser - $this->getParserContext()->addForm($changeForm); - } - - // Render the edition template. + protected function renderEditionTemplate() { return $this->render('currency-edit', array('currency_id' => $this->getRequest()->get('currency_id'))); } + protected function redirectToEditionTemplate() { + $this->redirectToRoute( + "admin.configuration.currencies.update", + array('currency_id' => $this->getRequest()->get('currency_id')) + ); + } + + protected function redirectToListTemplate() { + $this->redirectToRoute('admin.configuration.currencies.default'); + } + + /** - * Save changes on a modified currency object, and either go back to the currency list, or stay on the edition page. - * - * @return Symfony\Component\HttpFoundation\Response the response + * Update currencies rates */ - public function saveChangeAction() + public function updateRatesAction() { // Check current user authorization if (null !== $response = $this->checkAuth("admin.configuration.currencies.update")) return $response; - $error_msg = false; - - // Create the form from the request - $changeForm = new CurrencyModificationForm($this->getRequest()); - - // Get the currency ID - $currency_id = $this->getRequest()->get('currency_id'); - try { - - // Check the form against constraints violations - $form = $this->validateForm($changeForm, "POST"); - - // Get the form field values - $data = $form->getData(); - - $changeEvent = new CurrencyUpdateEvent($data['id']); - - // Create and dispatch the change event - $changeEvent - ->setCurrencyName($data['name']) - ->setLocale($data["locale"]) - ->setSymbol($data['symbol']) - ->setCode($data['code']) - ->setRate($data['rate']) - ; - - $this->dispatch(TheliaEvents::CURRENCY_UPDATE, $changeEvent); - - if (! $changeEvent->hasCurrency()) throw new \LogicException($this->getTranslator()->trans("No currency was updated.")); - - // Log currency modification - $changedObject = $changeEvent->getCurrency(); - - $this->adminLogAppend(sprintf("Currency %s (ID %s) modified", $changedObject->getName(), $changedObject->getId())); - - // If we have to stay on the same page, do not redirect to the succesUrl, - // just redirect to the edit page again. - if ($this->getRequest()->get('save_mode') == 'stay') { - $this->redirectToRoute( - "admin.configuration.currencies.update", - array('currency_id' => $currency_id) - ); - } - - // Redirect to the success URL - $this->redirect($changeForm->getSuccessUrl()); - } catch (FormValidationException $ex) { - // Form cannot be validated - $error_msg = $this->createStandardFormValidationErrorMessage($ex); + $this->dispatch(TheliaEvents::CURRENCY_UPDATE_RATES); } catch (\Exception $ex) { - // Any other error - $error_msg = $ex->getMessage(); + // Any error + return $this->errorPage($ex); } - $this->setupFormErrorContext("currency modification", $error_msg, $changeForm, $ex); - - // At this point, the form has errors, and should be redisplayed. - return $this->render('currency-edit', array('currency_id' => $currency_id)); + $this->redirectToListTemplate(); } /** @@ -260,80 +208,7 @@ class CurrencyController extends BaseAdminController return $this->errorPage($ex); } - $this->redirectToRoute('admin.configuration.currencies.default'); + $this->redirectToListTemplate(); } - /** - * Update currencies rates - */ - public function updateRatesAction() - { - // Check current user authorization - if (null !== $response = $this->checkAuth("admin.configuration.currencies.update")) return $response; - - try { - $this->dispatch(TheliaEvents::CURRENCY_UPDATE_RATES); - } catch (\Exception $ex) { - // Any error - return $this->errorPage($ex); - } - - $this->redirectToRoute('admin.configuration.currencies.default'); - } - - /** - * Update currencyposition - */ - public function updatePositionAction() - { - // Check current user authorization - if (null !== $response = $this->checkAuth("admin.configuration.currencies.update")) return $response; - - try { - $mode = $this->getRequest()->get('mode', null); - - if ($mode == 'up') - $mode = CurrencyUpdatePositionEvent::POSITION_UP; - else if ($mode == 'down') - $mode = CurrencyUpdatePositionEvent::POSITION_DOWN; - else - $mode = CurrencyUpdatePositionEvent::POSITION_ABSOLUTE; - - $position = $this->getRequest()->get('position', null); - - $event = new CurrencyUpdatePositionEvent( - $this->getRequest()->get('currency_id', null), - $mode, - $this->getRequest()->get('position', null) - ); - - $this->dispatch(TheliaEvents::CURRENCY_UPDATE_POSITION, $event); - } catch (\Exception $ex) { - // Any error - return $this->errorPage($ex); - } - - $this->redirectToRoute('admin.configuration.currencies.default'); - } - - /** - * Delete a currency object - * - * @return Symfony\Component\HttpFoundation\Response the response - */ - public function deleteAction() - { - // Check current user authorization - if (null !== $response = $this->checkAuth("admin.configuration.currencies.delete")) return $response; - - // Get the currency id, and dispatch the delet request - $event = new CurrencyDeleteEvent($this->getRequest()->get('currency_id')); - - $this->dispatch(TheliaEvents::CURRENCY_DELETE, $event); - - if ($event->hasCurrency()) - $this->adminLogAppend(sprintf("Currency %s (ID %s) modified", $event->getCurrency()->getName(), $event->getCurrency()->getId())); - - $this->redirectToRoute('admin.configuration.currencies.default'); - } } diff --git a/core/lib/Thelia/Controller/Admin/MessageController.php b/core/lib/Thelia/Controller/Admin/MessageController.php index b5316efdd..d2d319255 100644 --- a/core/lib/Thelia/Controller/Admin/MessageController.php +++ b/core/lib/Thelia/Controller/Admin/MessageController.php @@ -247,7 +247,7 @@ class MessageController extends BaseAdminController $this->dispatch(TheliaEvents::MESSAGE_DELETE, $event); if ($event->hasMessage()) - $this->adminLogAppend(sprintf("Message %s (ID %s) modified", $event->getMessage()->getName(), $event->getMessage()->getId())); + $this->adminLogAppend(sprintf("Message %s (ID %s) deleted", $event->getMessage()->getName(), $event->getMessage()->getId())); $this->redirectToRoute('admin.configuration.messages.default'); } diff --git a/core/lib/Thelia/Core/Event/CategoryUpdatePositionEvent.php b/core/lib/Thelia/Core/Event/CategoryUpdatePositionEvent.php deleted file mode 100644 index 701fd4c8a..000000000 --- a/core/lib/Thelia/Core/Event/CategoryUpdatePositionEvent.php +++ /dev/null @@ -1,28 +0,0 @@ -. */ -/* */ -/*************************************************************************************/ - -namespace Thelia\Core\Event; - -class CategoryUpdatePositionEvent extends BaseUpdatePositionEvent -{ -} diff --git a/core/lib/Thelia/Core/Event/CurrencyUpdatePositionEvent.php b/core/lib/Thelia/Core/Event/CurrencyUpdatePositionEvent.php deleted file mode 100644 index fad51f2c7..000000000 --- a/core/lib/Thelia/Core/Event/CurrencyUpdatePositionEvent.php +++ /dev/null @@ -1,28 +0,0 @@ -. */ -/* */ -/*************************************************************************************/ - -namespace Thelia\Core\Event; - -class CurrencyUpdatePositionEvent extends BaseUpdatePositionEvent -{ -} diff --git a/core/lib/Thelia/Core/Event/BaseToggleVisibilityEvent.php b/core/lib/Thelia/Core/Event/ToggleVisibilityEvent.php similarity index 97% rename from core/lib/Thelia/Core/Event/BaseToggleVisibilityEvent.php rename to core/lib/Thelia/Core/Event/ToggleVisibilityEvent.php index 65be75292..996292c8e 100644 --- a/core/lib/Thelia/Core/Event/BaseToggleVisibilityEvent.php +++ b/core/lib/Thelia/Core/Event/ToggleVisibilityEvent.php @@ -23,7 +23,7 @@ namespace Thelia\Core\Event; -class BaseToggleVisibilityEvent extends ActionEvent +class ToggleVisibilityEvent extends ActionEvent { protected $object_id; diff --git a/core/lib/Thelia/Core/Event/BaseUpdatePositionEvent.php b/core/lib/Thelia/Core/Event/UpdatePositionEvent.php similarity index 98% rename from core/lib/Thelia/Core/Event/BaseUpdatePositionEvent.php rename to core/lib/Thelia/Core/Event/UpdatePositionEvent.php index 9b58ecfeb..e75e30b98 100644 --- a/core/lib/Thelia/Core/Event/BaseUpdatePositionEvent.php +++ b/core/lib/Thelia/Core/Event/UpdatePositionEvent.php @@ -23,7 +23,7 @@ namespace Thelia\Core\Event; -class BaseUpdatePositionEvent extends ActionEvent +class UpdatePositionEvent extends ActionEvent { const POSITION_UP = 1; const POSITION_DOWN = 2; diff --git a/core/lib/Thelia/Core/Template/Loop/Attribute.php b/core/lib/Thelia/Core/Template/Loop/Attribute.php index 5ab4a2b4e..cb3a25e17 100755 --- a/core/lib/Thelia/Core/Template/Loop/Attribute.php +++ b/core/lib/Thelia/Core/Template/Loop/Attribute.php @@ -66,7 +66,7 @@ class Attribute extends BaseI18nLoop new Argument( 'order', new TypeCollection( - new Type\EnumListType(array('alpha', 'alpha_reverse', 'manual', 'manual_reverse')) + new Type\EnumListType(array('id', 'id_reverse', 'alpha', 'alpha_reverse', 'manual', 'manual_reverse')) ), 'manual' ) @@ -129,6 +129,12 @@ class Attribute extends BaseI18nLoop 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; diff --git a/core/lib/Thelia/Core/Template/Loop/Category.php b/core/lib/Thelia/Core/Template/Loop/Category.php index 91cb90b0a..2b1156b98 100755 --- a/core/lib/Thelia/Core/Template/Loop/Category.php +++ b/core/lib/Thelia/Core/Template/Loop/Category.php @@ -79,7 +79,7 @@ class Category extends BaseI18nLoop new Argument( 'order', new TypeCollection( - new Type\EnumListType(array('alpha', 'alpha_reverse', 'manual', 'manual_reverse', 'visible', 'visible_reverse', 'random')) + new Type\EnumListType(array('id', 'id_reverse', 'alpha', 'alpha_reverse', 'manual', 'manual_reverse', 'visible', 'visible_reverse', 'random')) ), 'manual' ), @@ -132,6 +132,12 @@ class Category extends BaseI18nLoop 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; diff --git a/core/lib/Thelia/Model/Attribute.php b/core/lib/Thelia/Model/Attribute.php index 34512b33b..b4101da8c 100755 --- a/core/lib/Thelia/Model/Attribute.php +++ b/core/lib/Thelia/Model/Attribute.php @@ -3,7 +3,69 @@ namespace Thelia\Model; use Thelia\Model\Base\Attribute as BaseAttribute; +use Propel\Runtime\Connection\ConnectionInterface; +use Thelia\Core\Event\TheliaEvents; +use Thelia\Core\Event\AttributeEvent; class Attribute extends BaseAttribute { + use \Thelia\Model\Tools\ModelEventDispatcherTrait; + use \Thelia\Model\Tools\PositionManagementTrait; + + /** + * {@inheritDoc} + */ + public function preInsert(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::BEFORE_CREATEATTRIBUTE, new AttributeEvent($this)); + + // Set the current position for the new object + $this->setPosition($this->getNextPosition()); + + return true; + } + + /** + * {@inheritDoc} + */ + public function postInsert(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_CREATEATTRIBUTE, new AttributeEvent($this)); + } + + /** + * {@inheritDoc} + */ + public function preUpdate(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::BEFORE_UPDATEATTRIBUTE, new AttributeEvent($this)); + + return true; + } + + /** + * {@inheritDoc} + */ + public function postUpdate(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_UPDATEATTRIBUTE, new AttributeEvent($this)); + } + + /** + * {@inheritDoc} + */ + public function preDelete(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::BEFORE_DELETEATTRIBUTE, new AttributeEvent($this)); + + return true; + } + + /** + * {@inheritDoc} + */ + public function postDelete(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_DELETEATTRIBUTE, new AttributeEvent($this)); + } } diff --git a/core/lib/Thelia/Model/AttributeAv.php b/core/lib/Thelia/Model/AttributeAv.php index a09db787c..2b70881d7 100755 --- a/core/lib/Thelia/Model/AttributeAv.php +++ b/core/lib/Thelia/Model/AttributeAv.php @@ -3,7 +3,85 @@ namespace Thelia\Model; use Thelia\Model\Base\AttributeAv as BaseAttributeAv; +use Thelia\Core\Event\AttributeValueEvent; +use Propel\Runtime\Connection\ConnectionInterface; +use Thelia\Core\Event\TheliaEvents; +use Propel\Runtime\ActiveQuery\Criteria; class AttributeAv extends BaseAttributeAv { -} + use \Thelia\Model\Tools\ModelEventDispatcherTrait; + use \Thelia\Model\Tools\PositionManagementTrait; + + /** + * Get the position of the next inserted object + */ + public function getNextPosition($parent = null) { + + $last = $this->createQuery() + ->filterByAttributeId($this->getAttributeId()) + ->orderByPosition(Criteria::DESC) + ->limit(1) + ->findOne() + ; + + return $last != null ? $last->getPosition() + 1 : 1; + } + + /** + * {@inheritDoc} + */ + public function preInsert(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::BEFORE_CREATEATTRIBUTE_VALUE, new AttributeValueEvent($this)); + + // Set the current position for the new object + $this->setPosition($this->getNextPosition()); + + return true; + } + + /** + * {@inheritDoc} + */ + public function postInsert(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_CREATEATTRIBUTE_VALUE, new AttributeValueEvent($this)); + } + + /** + * {@inheritDoc} + */ + public function preUpdate(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::BEFORE_UPDATEATTRIBUTE_VALUE, new AttributeValueEvent($this)); + + return true; + } + + /** + * {@inheritDoc} + */ + public function postUpdate(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_UPDATEATTRIBUTE_VALUE, new AttributeValueEvent($this)); + } + + /** + * {@inheritDoc} + */ + public function preDelete(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::BEFORE_DELETEATTRIBUTE_VALUE, new AttributeValueEvent($this)); + + return true; + } + + /** + * {@inheritDoc} + */ + public function postDelete(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_DELETEATTRIBUTE_VALUE, new AttributeValueEvent($this)); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Model/Tools/PositionManagementTrait.php b/core/lib/Thelia/Model/Tools/PositionManagementTrait.php index eb71564eb..d5cc4ea63 100644 --- a/core/lib/Thelia/Model/Tools/PositionManagementTrait.php +++ b/core/lib/Thelia/Model/Tools/PositionManagementTrait.php @@ -67,6 +67,7 @@ trait PositionManagementTrait { * Move up a object */ public function movePositionUp() { + echo "move up !"; $this->movePositionUpOrDown(true); } diff --git a/install/INSTALL-TODO.txt b/install/INSTALL-TODO.txt index 0b8001fe9..df1e39a8d 100755 --- a/install/INSTALL-TODO.txt +++ b/install/INSTALL-TODO.txt @@ -23,3 +23,4 @@ Variables Config à initialiser: - images_library_path : chemin vers le répertoire où sont stockés les images source (defaut: local/media/images) - image_cache_dir_from_web_root : le repértoire de base où sont cachées les images, relatif à /web (cache/images) - imagine_graphic_driver : le drivers utilisé par Imagine (gd, imagik, gmagick), defaut: 'gd' +- process_assets : ne pas processer les assets pour de meilleurs perfs (attention, les modifs sur les fichiers ne seront plus reportées !) diff --git a/templates/admin/default/attributes.html b/templates/admin/default/attributes.html new file mode 100644 index 000000000..eab4996ac --- /dev/null +++ b/templates/admin/default/attributes.html @@ -0,0 +1,266 @@ +{extends file="admin-layout.tpl"} + +{block name="page-title"}{intl l='Thelia Product Attributes'}{/block} + +{block name="check-permissions"}admin.configuration.attributes.view{/block} + +{block name="main-content"} +
    + +
    + + + + {module_include location='attributes_top'} + +
    +
    + +
    + + + + + + + + + + + {module_include location='attributes_table_header'} + + + + + + + {loop name="list" type="attribute" backend_context="1" lang=$lang_id order=$order} + + + + + + + + {module_include location='attributes_table_row'} + + + + {/loop} + + {elseloop rel="list"} + + + + {/elseloop} + +
    + {intl l='Thelia product attributes'} + + {loop type="auth" name="can_create" roles="ADMIN" permissions="admin.configuration.attributes.create"} + + + + {/loop} +
    + {admin_sortable_header + current_order=$order + order='id' + reverse_order='id_reverse' + path='/admin/configuration/attributes' + label="{intl l='ID'}" + } + + {admin_sortable_header + current_order=$order + order='alpha' + reverse_order='alpha_reverse' + path='/admin/configuration/attributes' + label="{intl l='Title'}" + } + + {admin_sortable_header + current_order=$order + order='manual' + reverse_order='manual_reverse' + path='/admin/configuration/attributes' + label="{intl l="Position"}" + } + {intl l="Actions"}
    {$ID} + {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.attributes.change"} + {$TITLE} + {/loop} + {elseloop rel="can_change"} + {$TITLE} + {/elseloop} + + {admin_position_block + permission="admin.attributes.edit" + path="/admin/configuration/attributes/update-position" + url_parameter="attribute_id" + in_place_edit_class="positionChange" + position="$POSITION" + id="$ID" + } + +
    + {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.attributes.change"} + + {/loop} + + {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.attributes.delete"} + + {/loop} +
    +
    +
    + {intl l="No product attribute has been created yet. Click the + button to create one."} +
    +
    +
    + +
    +
    + + {module_include location='attributes_bottom'} + +
    +
    + +{* Adding a new attribute *} + +{form name="thelia.admin.attribute.creation"} + + {* Capture the dialog body, to pass it to the generic dialog *} + {capture "creation_dialog"} + {form_hidden_fields form=$form} + + {form_field form=$form field='success_url'} + {* on success, redirect to the edition page, _ID_ is replaced with the created attribute ID, see controller *} + + {/form_field} + + {form_field form=$form field='title'} +
    + + + {loop type="lang" name="default-lang" default_only="1"} +
    + + {intl l=$TITLE} +
    + +
    {intl l="Enter here the attribute name in the default language ($TITLE)"}
    + + {* Switch edition to the current locale *} + + + {form_field form=$form field='locale'} + + {/form_field} + {/loop} +
    + {/form_field} + + {form_field form=$form field='add_to_all'} +
    +
    + + {intl l='Check this box if you want to add this attributes to all product templates'} +
    +
    + {/form_field} + + {module_include location='attribute_create_form'} + + {/capture} + + {include + file = "includes/generic-create-dialog.html" + + dialog_id = "creation_dialog" + dialog_title = {intl l="Create a new attribute"} + dialog_body = {$smarty.capture.creation_dialog nofilter} + + dialog_ok_label = {intl l="Create this attribute"} + + form_action = {url path='/admin/configuration/attributes/create'} + form_enctype = {form_enctype form=$form} + form_error_message = $form_error_message + } +{/form} + +{* Delete confirmation dialog *} + +{capture "delete_dialog"} + + + {module_include location='attribute_delete_form'} + +{/capture} + +{include + file = "includes/generic-confirm-dialog.html" + + dialog_id = "delete_dialog" + dialog_title = {intl l="Delete attribute"} + dialog_message = {intl l="Do you really want to delete this attribute ? It will be removed from all product templates."} + + form_action = {url path='/admin/configuration/attributes/delete'} + form_content = {$smarty.capture.delete_dialog nofilter} +} + +{/block} + +{block name="javascript-initialization"} + + {javascripts file='assets/js/bootstrap-editable/bootstrap-editable.js'} + + {/javascripts} + + +{/block} \ No newline at end of file diff --git a/templates/admin/default/categories.html b/templates/admin/default/categories.html index 1d1cf53c2..0423bcc66 100755 --- a/templates/admin/default/categories.html +++ b/templates/admin/default/categories.html @@ -327,7 +327,6 @@ {* Adding a new Category *} - {form name="thelia.admin.category.creation"} {* Capture the dialog body, to pass it to the generic dialog *} @@ -366,6 +365,9 @@ {/loop}
    {/form_field} + + {module_include location='category_create_form'} + {/capture} {include @@ -389,6 +391,9 @@ {capture "category_delete_dialog"} + + {module_include location='category_delete_form'} + {/capture} {include diff --git a/templates/admin/default/category-edit.html b/templates/admin/default/category-edit.html index 7f59fd38e..e01849475 100755 --- a/templates/admin/default/category-edit.html +++ b/templates/admin/default/category-edit.html @@ -53,7 +53,7 @@
    - {include file="includes/inner-form-toolbar.html"} + {include file="includes/inner-form-toolbar.html" close_url="{url path='admin/catalog/category/edit' category_id=$current_category_id}"}
    @@ -136,7 +136,7 @@
    - {include file="includes/inner-form-toolbar.html"} + {include file="includes/inner-form-toolbar.html" close_url="{url path='admin/catalog/category/edit' category_id=$current_category_id}"}
    diff --git a/templates/admin/default/configuration.html b/templates/admin/default/configuration.html index 70b7cffb8..0bf0e9bed 100644 --- a/templates/admin/default/configuration.html +++ b/templates/admin/default/configuration.html @@ -22,24 +22,24 @@ {module_include location='catalog_configuration_top'} - {loop type="auth" name="pcc1" roles="ADMIN" permissions="admin.configuration.product_templates"} + {loop type="auth" name="pcc1" roles="ADMIN" permissions="admin.configuration.templates"} - {intl l='Product templates'} - + {intl l='Product templates'} + {/loop} - {loop type="auth" name="pcc2" roles="ADMIN" permissions="admin.configuration.product_attributes"} + {loop type="auth" name="pcc2" roles="ADMIN" permissions="admin.configuration.attributes"} - {intl l='Product attributes'} - + {intl l='Product attributes'} + {/loop} - {loop type="auth" name="pcc3" roles="ADMIN" permissions="admin.configuration.product_features"} + {loop type="auth" name="pcc3" roles="ADMIN" permissions="admin.configuration.features"} - {intl l='Product features'} - + {intl l='Product features'} + {/loop} diff --git a/templates/admin/default/coupon-list.html b/templates/admin/default/coupon-list.html index 331b97231..e4a1d5e36 100755 --- a/templates/admin/default/coupon-list.html +++ b/templates/admin/default/coupon-list.html @@ -10,7 +10,7 @@ {include file="includes/coupon_breadcrumb.html"} - + @@ -28,7 +28,7 @@ Expiration date Usage left Actions - + @@ -146,8 +146,8 @@ {block name="javascript-initialization"} - - {javascripts file='assets/bootstrap-editable/js/bootstrap-editable.js'} + + {javascripts file='assets/js/bootstrap-editable/bootstrap-editable.js'} {/javascripts} diff --git a/templates/admin/default/currencies.html b/templates/admin/default/currencies.html index 5854b2f49..72bf01e75 100644 --- a/templates/admin/default/currencies.html +++ b/templates/admin/default/currencies.html @@ -255,6 +255,8 @@
    {/form_field} + {module_include location='currency_create_form'} + {/capture} {include @@ -277,6 +279,9 @@ {capture "delete_dialog"} + + {module_include location='currency_delete_form'} + {/capture} {include diff --git a/templates/admin/default/currency-edit.html b/templates/admin/default/currency-edit.html index 6c85d604a..cc7ac16ac 100644 --- a/templates/admin/default/currency-edit.html +++ b/templates/admin/default/currency-edit.html @@ -35,7 +35,7 @@ {* Be sure to get the currency ID, even if the form could not be validated *} - {include file="includes/inner-form-toolbar.html"} + {include file="includes/inner-form-toolbar.html" close_url="{url path='/admin/configuration/currencies'}"} {form_hidden_fields form=$form} diff --git a/templates/admin/default/customer-edit.html b/templates/admin/default/customer-edit.html index c512bb056..d14e0056a 100644 --- a/templates/admin/default/customer-edit.html +++ b/templates/admin/default/customer-edit.html @@ -10,9 +10,9 @@
    {loop name="customer_edit" type="customer" current="false" id="$customer_id" backend_context="1" lang="$edit_language_id"} - + @@ -34,7 +34,7 @@ {* Be sure to get the customer ID, even if the form could not be validated *} - {include file="includes/inner-form-toolbar.html"} + {include file="includes/inner-form-toolbar.html" close_url="{url path='/admin/customers'}"} {form_hidden_fields form=$form} @@ -44,18 +44,18 @@ {if $form_error}
    {$form_error_message}
    {/if} -
    +

    {intl l="Customer informations"}

    - {form_field form=$form field='title'} + {form_field form=$form field='title'}
    - + +
    {/form_field} @@ -74,7 +74,7 @@ {/form_field} {loop name="address" type="address" customer="$customer_id" backend_context="1" default="true"} - +

    {intl l="Default address"}

    {form_field form=$form field='address1'} @@ -85,16 +85,16 @@ {/form_field} {form_field form=$form field='address2'} -
    - +
    +
    - {/form_field} + {/form_field} {form_field form=$form field='address3'} -
    - +
    +
    - {/form_field} + {/form_field} {form_field form=$form field='zipcode'}
    @@ -119,16 +119,16 @@ {/loop}
    - {/form_field} + {/form_field} - {/loop} + {/loop}

    {intl l="Other addresses"} - + @@ -154,11 +154,11 @@

    - + - + @@ -166,7 +166,7 @@ - +
    @@ -181,11 +181,11 @@
    - + - + @@ -193,7 +193,7 @@ - +
    @@ -208,11 +208,11 @@
    - + - + @@ -220,7 +220,7 @@ - +
    @@ -258,12 +258,12 @@ {* Add an Address *} {form name="thelia.address.create"} - + {* Capture the dialog body, to pass it to the generic dialog *} {capture "address_creation_dialog"} - + {form_hidden_fields form=$form} - + {form_field form=$form field='label'}
    @@ -277,16 +277,16 @@
    {/form_field} - - {form_field form=$form field='title'} + + {form_field form=$form field='title'}
    - + +
    {/form_field} @@ -307,13 +307,13 @@ {form_field form=$form field='address1'}
    - +
    {form_field form=$form field='address2'} - {/form_field} + {/form_field}
    @@ -346,10 +346,10 @@ {/loop}
    - {/form_field} + {/form_field} {/capture} - + {include file = "includes/generic-create-dialog.html" @@ -370,12 +370,12 @@ {* Update an Address *} {form name="thelia.address.update"} - + {* Capture the dialog body, to pass it to the generic dialog *} {capture "edit_address_dialog"} - + {form_hidden_fields form=$form} - + {form_field form=$form field='label'}
    @@ -389,16 +389,16 @@
    {/form_field} - - {form_field form=$form field='title'} + + {form_field form=$form field='title'}
    - + +
    {/form_field} @@ -419,13 +419,13 @@ {form_field form=$form field='address1'}
    - +
    {form_field form=$form field='address2'} - {/form_field} + {/form_field}
    @@ -458,10 +458,10 @@ {/loop}
    - {/form_field} + {/form_field} {/capture} - + {include file = "includes/generic-create-dialog.html" @@ -478,8 +478,8 @@ } {/form} - - + + {* Default confirmation dialog *} {capture "use_address_dialog"} diff --git a/templates/admin/default/includes/generic-js-dialog.html b/templates/admin/default/includes/generic-js-dialog.html index 051aefd29..aca78e1bc 100644 --- a/templates/admin/default/includes/generic-js-dialog.html +++ b/templates/admin/default/includes/generic-js-dialog.html @@ -22,7 +22,7 @@ Parameters: {* Always reset create dialog on close *} -$('#{$dialog_id}').on('hidden', function() { +$('#{$dialog_id}').on('hidden.bs.modal', function() { // Hide error message $('#{$dialog_id}_error').remove(); diff --git a/templates/admin/default/includes/inner-form-toolbar.html b/templates/admin/default/includes/inner-form-toolbar.html index 0b37d7bd8..518c204e3 100755 --- a/templates/admin/default/includes/inner-form-toolbar.html +++ b/templates/admin/default/includes/inner-form-toolbar.html @@ -12,7 +12,7 @@
    - + + {if ! empty($close_url)} + {intl l='Close'} + {/if}
    diff --git a/templates/admin/default/message-edit.html b/templates/admin/default/message-edit.html index 4014940a5..db6118c05 100644 --- a/templates/admin/default/message-edit.html +++ b/templates/admin/default/message-edit.html @@ -30,11 +30,11 @@
    {form name="thelia.admin.message.modification"}
    - + {* Be sure to get the message ID, even if the form could not be validated *} - {include file="includes/inner-form-toolbar.html"} + {include file="includes/inner-form-toolbar.html" close_url="{url path='/admin/configuration/messages'}"} {form_hidden_fields form=$form} @@ -51,33 +51,33 @@ {/form_field} {if $form_error}
    {$form_error_message}
    {/if} - + {form_field form=$form field='name'}
    - +
    {/form_field} - + {form_field form=$form field='secured'}
    +
    {/form_field} {form_field form=$form field='title'}
    - +
    {/form_field} {form_field form=$form field='subject'}
    - +
    {/form_field} @@ -85,7 +85,7 @@ {form_field form=$form field='html_message'}
    @@ -95,17 +95,17 @@ {form_field form=$form field='text_message'}
    {/form_field} -
    +

    {intl l='Message created on %date_create. Last modification: %date_change' date_create="{format_date date=$CREATE_DATE}" date_change="{format_date date=$UPDATE_DATE}"}}

    - + {/form}
    diff --git a/templates/admin/default/messages.html b/templates/admin/default/messages.html index 755388fcf..afa7764af 100644 --- a/templates/admin/default/messages.html +++ b/templates/admin/default/messages.html @@ -152,6 +152,9 @@
    {/form_field} + + {module_include location='message_create_form'} + {/capture} {include @@ -173,6 +176,9 @@ {capture "delete_dialog"} + + {module_include location='message_delete_form'} + {/capture} {include diff --git a/templates/admin/default/product-attributes.html b/templates/admin/default/product-attributes.html deleted file mode 100644 index 921674b03..000000000 --- a/templates/admin/default/product-attributes.html +++ /dev/null @@ -1,142 +0,0 @@ -{extends file="admin-layout.tpl"} - -{block name="page-title"}{intl l='Thelia Product Attributes'}{/block} - -{block name="check-permissions"}admin.configuration.product_attributes.view{/block} - -{block name="main-content"} -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - -
    - {intl l='Thelia product attributes'} - - - - -
    {intl l="Title"}{intl l="Position"}{intl l="Actions"}
    Title here1 -
    - - - -
    -
    -
    -
    -
    -
    - -
    -
    - - -{* Adding a new message *} - - - - -{* Delete confirmation dialog *} - - -{/block} \ No newline at end of file diff --git a/templates/admin/default/variable-edit.html b/templates/admin/default/variable-edit.html index ea2701f66..7e634b92a 100644 --- a/templates/admin/default/variable-edit.html +++ b/templates/admin/default/variable-edit.html @@ -34,7 +34,7 @@ {* Be sure to get the variable ID, even if the form could not be validated *} - {include file="includes/inner-form-toolbar.html"} + {include file="includes/inner-form-toolbar.html" close_url="{url path='/admin/configuration/variables'}"} {form_hidden_fields form=$form} @@ -57,27 +57,27 @@ {/form_field} {if $form_error}
    {$form_error_message}
    {/if} - + {form_field form=$form field='name'}
    - - + +
    {/form_field} - + {form_field form=$form field='value'}
    - - + +
    {/form_field} - + {form_field form=$form field='secured'}
    +
    {/form_field} diff --git a/templates/admin/default/variables.html b/templates/admin/default/variables.html index 0d1c948a0..3f1e90a09 100644 --- a/templates/admin/default/variables.html +++ b/templates/admin/default/variables.html @@ -194,6 +194,9 @@ {/loop}
    {/form_field} + + + {module_include location='variable_create_form'} {/capture} {include @@ -215,6 +218,9 @@ {capture "delete_dialog"} + + {module_include location='variable_delete_form'} + {/capture} {include From 3f8242187940e3e954d97a62bf69d9d0ba911a96 Mon Sep 17 00:00:00 2001 From: franck Date: Thu, 12 Sep 2013 13:39:47 +0200 Subject: [PATCH 24/45] Finished admin controllers refactoriing --- core/lib/Thelia/Action/Attribute.php | 149 ++++++ core/lib/Thelia/Action/AttributeValue.php | 149 ++++++ core/lib/Thelia/Action/Currency.php | 3 - .../Thelia/Action/PositionManagementTrait.php | 157 ------ .../Admin/AbstractCrudController.php | 448 ++++++++++++++++++ .../Controller/Admin/AttributeController.php | 437 +++++------------ .../Controller/Admin/ConfigController.php | 331 +++++-------- .../Controller/Admin/CurrencyController.php | 5 - .../Controller/Admin/MessageController.php | 316 +++++------- .../Core/Event/AttributeCreateEvent.php | 68 +++ ...lityEvent.php => AttributeDeleteEvent.php} | 24 +- core/lib/Thelia/Core/Event/AttributeEvent.php | 52 ++ .../Core/Event/AttributeUpdateEvent.php | 86 ++++ .../Core/Event/AttributeValueCreateEvent.php | 68 +++ .../Core/Event/AttributeValueDeleteEvent.php | 46 ++ .../Thelia/Core/Event/AttributeValueEvent.php | 52 ++ .../Core/Event/AttributeValueUpdateEvent.php | 86 ++++ .../lib/Thelia/Form/AttributeCreationForm.php | 66 +++ .../Thelia/Form/AttributeModificationForm.php | 56 +++ .../Form/AttributeValueCreationForm.php | 62 +++ templates/admin/default/attribute-edit.html | 306 ++++++++++++ .../default/includes/thelia_news_feed.html | 4 +- 22 files changed, 2048 insertions(+), 923 deletions(-) create mode 100644 core/lib/Thelia/Action/Attribute.php create mode 100644 core/lib/Thelia/Action/AttributeValue.php delete mode 100644 core/lib/Thelia/Action/PositionManagementTrait.php create mode 100644 core/lib/Thelia/Controller/Admin/AbstractCrudController.php create mode 100644 core/lib/Thelia/Core/Event/AttributeCreateEvent.php rename core/lib/Thelia/Core/Event/{CategoryToggleVisibilityEvent.php => AttributeDeleteEvent.php} (74%) create mode 100644 core/lib/Thelia/Core/Event/AttributeEvent.php create mode 100644 core/lib/Thelia/Core/Event/AttributeUpdateEvent.php create mode 100644 core/lib/Thelia/Core/Event/AttributeValueCreateEvent.php create mode 100644 core/lib/Thelia/Core/Event/AttributeValueDeleteEvent.php create mode 100644 core/lib/Thelia/Core/Event/AttributeValueEvent.php create mode 100644 core/lib/Thelia/Core/Event/AttributeValueUpdateEvent.php create mode 100644 core/lib/Thelia/Form/AttributeCreationForm.php create mode 100644 core/lib/Thelia/Form/AttributeModificationForm.php create mode 100644 core/lib/Thelia/Form/AttributeValueCreationForm.php create mode 100644 templates/admin/default/attribute-edit.html diff --git a/core/lib/Thelia/Action/Attribute.php b/core/lib/Thelia/Action/Attribute.php new file mode 100644 index 000000000..8524f6054 --- /dev/null +++ b/core/lib/Thelia/Action/Attribute.php @@ -0,0 +1,149 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Action; + +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +use Thelia\Model\AttributeQuery; +use Thelia\Model\Attribute as AttributeModel; + +use Thelia\Core\Event\TheliaEvents; + +use Thelia\Core\Event\AttributeUpdateEvent; +use Thelia\Core\Event\AttributeCreateEvent; +use Thelia\Core\Event\AttributeDeleteEvent; +use Thelia\Model\ConfigQuery; +use Thelia\Model\AttributeAv; +use Thelia\Model\AttributeAvQuery; +use Thelia\Core\Event\UpdatePositionEvent; + +class Attribute extends BaseAction implements EventSubscriberInterface +{ + /** + * Create a new attribute entry + * + * @param AttributeCreateEvent $event + */ + public function create(AttributeCreateEvent $event) + { + $attribute = new AttributeModel(); + + $attribute + ->setDispatcher($this->getDispatcher()) + + ->setLocale($event->getLocale()) + ->setTitle($event->getTitle()) + + ->save() + ; + + $event->setAttribute($attribute); + + // Add atribute to all product templates if required + if ($event->getAddToAllTemplates() != 0) { + // TODO: add to all product template + } + } + + /** + * Change a product attribute + * + * @param AttributeUpdateEvent $event + */ + public function update(AttributeUpdateEvent $event) + { + $search = AttributeQuery::create(); + + if (null !== $attribute = AttributeQuery::create()->findPk($event->getAttributeId())) { + + $attribute + ->setDispatcher($this->getDispatcher()) + + ->setLocale($event->getLocale()) + ->setTitle($event->getTitle()) + ->setDescription($event->getDescription()) + ->setChapo($event->getChapo()) + ->setPostscriptum($event->getPostscriptum()) + + ->save(); + + $event->setAttribute($attribute); + } + } + + /** + * Delete a product attribute entry + * + * @param AttributeDeleteEvent $event + */ + public function delete(AttributeDeleteEvent $event) + { + + if (null !== ($attribute = AttributeQuery::create()->findPk($event->getAttributeId()))) { + + $attribute + ->setDispatcher($this->getDispatcher()) + ->delete() + ; + + $event->setAttribute($attribute); + } + } + + /** + * Changes position, selecting absolute ou relative change. + * + * @param CategoryChangePositionEvent $event + */ + public function updatePosition(UpdatePositionEvent $event) + { + if (null !== $attribute = AttributeQuery::create()->findPk($event->getObjectId())) { + + $attribute->setDispatcher($this->getDispatcher()); + + $mode = $event->getMode(); + + if ($mode == UpdatePositionEvent::POSITION_ABSOLUTE) + return $attribute->changeAbsolutePosition($event->getPosition()); + else if ($mode == UpdatePositionEvent::POSITION_UP) + return $attribute->movePositionUp(); + else if ($mode == UpdatePositionEvent::POSITION_DOWN) + return $attribute->movePositionDown(); + } + } + + + /** + * {@inheritDoc} + */ + public static function getSubscribedEvents() + { + return array( + TheliaEvents::ATTRIBUTE_CREATE => array("create", 128), + TheliaEvents::ATTRIBUTE_UPDATE => array("update", 128), + TheliaEvents::ATTRIBUTE_DELETE => array("delete", 128), + TheliaEvents::ATTRIBUTE_UPDATE_POSITION => array("updatePosition", 128), + ); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Action/AttributeValue.php b/core/lib/Thelia/Action/AttributeValue.php new file mode 100644 index 000000000..8524f6054 --- /dev/null +++ b/core/lib/Thelia/Action/AttributeValue.php @@ -0,0 +1,149 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Action; + +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +use Thelia\Model\AttributeQuery; +use Thelia\Model\Attribute as AttributeModel; + +use Thelia\Core\Event\TheliaEvents; + +use Thelia\Core\Event\AttributeUpdateEvent; +use Thelia\Core\Event\AttributeCreateEvent; +use Thelia\Core\Event\AttributeDeleteEvent; +use Thelia\Model\ConfigQuery; +use Thelia\Model\AttributeAv; +use Thelia\Model\AttributeAvQuery; +use Thelia\Core\Event\UpdatePositionEvent; + +class Attribute extends BaseAction implements EventSubscriberInterface +{ + /** + * Create a new attribute entry + * + * @param AttributeCreateEvent $event + */ + public function create(AttributeCreateEvent $event) + { + $attribute = new AttributeModel(); + + $attribute + ->setDispatcher($this->getDispatcher()) + + ->setLocale($event->getLocale()) + ->setTitle($event->getTitle()) + + ->save() + ; + + $event->setAttribute($attribute); + + // Add atribute to all product templates if required + if ($event->getAddToAllTemplates() != 0) { + // TODO: add to all product template + } + } + + /** + * Change a product attribute + * + * @param AttributeUpdateEvent $event + */ + public function update(AttributeUpdateEvent $event) + { + $search = AttributeQuery::create(); + + if (null !== $attribute = AttributeQuery::create()->findPk($event->getAttributeId())) { + + $attribute + ->setDispatcher($this->getDispatcher()) + + ->setLocale($event->getLocale()) + ->setTitle($event->getTitle()) + ->setDescription($event->getDescription()) + ->setChapo($event->getChapo()) + ->setPostscriptum($event->getPostscriptum()) + + ->save(); + + $event->setAttribute($attribute); + } + } + + /** + * Delete a product attribute entry + * + * @param AttributeDeleteEvent $event + */ + public function delete(AttributeDeleteEvent $event) + { + + if (null !== ($attribute = AttributeQuery::create()->findPk($event->getAttributeId()))) { + + $attribute + ->setDispatcher($this->getDispatcher()) + ->delete() + ; + + $event->setAttribute($attribute); + } + } + + /** + * Changes position, selecting absolute ou relative change. + * + * @param CategoryChangePositionEvent $event + */ + public function updatePosition(UpdatePositionEvent $event) + { + if (null !== $attribute = AttributeQuery::create()->findPk($event->getObjectId())) { + + $attribute->setDispatcher($this->getDispatcher()); + + $mode = $event->getMode(); + + if ($mode == UpdatePositionEvent::POSITION_ABSOLUTE) + return $attribute->changeAbsolutePosition($event->getPosition()); + else if ($mode == UpdatePositionEvent::POSITION_UP) + return $attribute->movePositionUp(); + else if ($mode == UpdatePositionEvent::POSITION_DOWN) + return $attribute->movePositionDown(); + } + } + + + /** + * {@inheritDoc} + */ + public static function getSubscribedEvents() + { + return array( + TheliaEvents::ATTRIBUTE_CREATE => array("create", 128), + TheliaEvents::ATTRIBUTE_UPDATE => array("update", 128), + TheliaEvents::ATTRIBUTE_DELETE => array("delete", 128), + TheliaEvents::ATTRIBUTE_UPDATE_POSITION => array("updatePosition", 128), + ); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Action/Currency.php b/core/lib/Thelia/Action/Currency.php index b73dd0184..7908d1f0d 100644 --- a/core/lib/Thelia/Action/Currency.php +++ b/core/lib/Thelia/Action/Currency.php @@ -166,8 +166,6 @@ class Currency extends BaseAction implements EventSubscriberInterface */ public function updatePosition(UpdatePositionEvent $event) { -echo "update =".$event->getObjectId(); - if (null !== $currency = CurrencyQuery::create()->findPk($event->getObjectId())) { $currency->setDispatcher($this->getDispatcher()); @@ -182,7 +180,6 @@ echo "update =".$event->getObjectId(); else if ($mode == UpdatePositionEvent::POSITION_DOWN) return $currency->movePositionDown(); } - exit; } /** diff --git a/core/lib/Thelia/Action/PositionManagementTrait.php b/core/lib/Thelia/Action/PositionManagementTrait.php deleted file mode 100644 index 5da085594..000000000 --- a/core/lib/Thelia/Action/PositionManagementTrait.php +++ /dev/null @@ -1,157 +0,0 @@ -. */ -/* */ -/*************************************************************************************/ - -namespace Thelia\Action; - -use Thelia\Core\Event\BaseChangePositionEvent; - -trait PositionManagementTrait -{ - const POSITION_UP - /** - * Changes object position, selecting absolute ou relative change. - * - * @param BaseChangePositionEvent $event - */ - public function changePosition(BaseChangePositionEvent $event) - { - if ($event->getMode() == BaseChangePositionEvent::POSITION_ABSOLUTE) - return $this->changeAbsolutePosition($event); - else - return $this->exchangePosition($event); - } - - /** - * Move up or down a object - * - * @param BaseChangePositionEvent $event - */ - protected function exchangePosition(BaseChangePositionEvent $event) - { - $object = CategoryQuery::create()->findPk($event->getCategoryId()); - - if ($object !== null) { - - // The current position of the object - $my_position = $object->getPosition(); - - // Find object to exchange position with - $search = CategoryQuery::create() - ->filterByParent($object->getParent()); - - // Up or down ? - if ($event->getMode() == BaseChangePositionEvent::POSITION_UP) { - // Find the object immediately before me - $search->filterByPosition(array('max' => $my_position-1))->orderByPosition(Criteria::DESC); - } elseif ($event->getMode() == BaseChangePositionEvent::POSITION_DOWN) { - // Find the object immediately after me - $search->filterByPosition(array('min' => $my_position+1))->orderByPosition(Criteria::ASC); - } else - - return; - - $result = $search->findOne(); - - // If we found the proper object, exchange their positions - if ($result) { - - $cnx = Propel::getWriteConnection(CategoryTableMap::DATABASE_NAME); - - $cnx->beginTransaction(); - - try { - $object - ->setDispatcher($this->getDispatcher()) - ->setPosition($result->getPosition()) - ->save() - ; - - $result->setPosition($my_position)->save(); - - $cnx->commit(); - } catch (Exception $e) { - $cnx->rollback(); - } - } - } - } - - /** - * Changes object position - * - * @param BaseChangePositionEvent $event - */ - protected function changeAbsolutePosition(BaseChangePositionEvent $event) - { - $object = CategoryQuery::create()->findPk($event->getCategoryId()); - - if ($object !== null) { - - // The required position - $new_position = $event->getPosition(); - - // The current position - $current_position = $object->getPosition(); - - if ($new_position != null && $new_position > 0 && $new_position != $current_position) { - - // Find categories to offset - $search = CategoryQuery::create()->filterByParent($object->getParent()); - - if ($new_position > $current_position) { - // The new position is after the current position -> we will offset + 1 all categories located between us and the new position - $search->filterByPosition(array('min' => 1+$current_position, 'max' => $new_position)); - - $delta = -1; - } else { - // The new position is brefore the current position -> we will offset - 1 all categories located between us and the new position - $search->filterByPosition(array('min' => $new_position, 'max' => $current_position - 1)); - - $delta = 1; - } - - $results = $search->find(); - - $cnx = Propel::getWriteConnection(CategoryTableMap::DATABASE_NAME); - - $cnx->beginTransaction(); - - try { - foreach ($results as $result) { - $result->setPosition($result->getPosition() + $delta)->save($cnx); - } - - $object - ->setDispatcher($this->getDispatcher()) - ->setPosition($new_position) - ->save($cnx) - ; - - $cnx->commit(); - } catch (Exception $e) { - $cnx->rollback(); - } - } - } - } -} diff --git a/core/lib/Thelia/Controller/Admin/AbstractCrudController.php b/core/lib/Thelia/Controller/Admin/AbstractCrudController.php new file mode 100644 index 000000000..6d32220b7 --- /dev/null +++ b/core/lib/Thelia/Controller/Admin/AbstractCrudController.php @@ -0,0 +1,448 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Controller\Admin; + +use Thelia\Form\Exception\FormValidationException; +use Thelia\Core\Event\UpdatePositionEvent; +use Thelia\Core\Event\ToggleVisibilityEvent; + +/** + * Manages currencies sent by mail + * + * @author Franck Allimant + */ +abstract class AbstractCrudController extends BaseAdminController +{ + protected $objectName; + + // List ordering + protected $defaultListOrder; + + // Permissions + protected $viewPermissionIdentifier; + protected $createPermissionIdentifier; + protected $updatePermissionIdentifier; + protected $deletePermissionIdentifier; + + // Events + protected $createEventIdentifier; + protected $updateEventIdentifier; + protected $deleteEventIdentifier; + protected $visibilityToggleEventIdentifier; + protected $changePositionEventIdentifier; + + + public function __construct( + $objectName, + + $defaultListOrder = null, + + $viewPermissionIdentifier, + $createPermissionIdentifier, + $updatePermissionIdentifier, + $deletePermissionIdentifier, + + $createEventIdentifier, + $updateEventIdentifier, + $deleteEventIdentifier, + $visibilityToggleEventIdentifier = null, + $changePositionEventIdentifier = null + ) { + $this->objectName = $objectName; + + $this->defaultListOrder = $defaultListOrder; + + $this->viewPermissionIdentifier = $viewPermissionIdentifier; + $this->createPermissionIdentifier = $createPermissionIdentifier; + $this->updatePermissionIdentifier = $updatePermissionIdentifier; + $this->deletePermissionIdentifier = $deletePermissionIdentifier; + + $this->createEventIdentifier = $createEventIdentifier; + $this->updateEventIdentifier = $updateEventIdentifier; + $this->deleteEventIdentifier = $deleteEventIdentifier; + $this->visibilityToggleEventIdentifier = $visibilityToggleEventIdentifier; + $this->changePositionEventIdentifier = $changePositionEventIdentifier; + } + + /** + * Return the creation form for this object + */ + protected abstract function getCreationForm(); + + /** + * Return the update form for this object + */ + protected abstract function getUpdateForm(); + + /** + * Hydrate the update form for this object, before passing it to the update template + * + * @param unknown $object + */ + protected abstract function hydrateObjectForm($object); + + /** + * Creates the creation event with the provided form data + * + * @param unknown $formData + */ + protected abstract function getCreationEvent($formData); + + /** + * Creates the update event with the provided form data + * + * @param unknown $formData + */ + protected abstract function getUpdateEvent($formData); + + /** + * Creates the delete event with the provided form data + */ + protected abstract function getDeleteEvent(); + + /** + * Return true if the event contains the object, e.g. the action has updated the object in the event. + * + * @param unknown $event + */ + protected abstract function eventContainsObject($event); + + /** + * Get the created object from an event. + * + * @param unknown $createEvent + */ + protected abstract function getObjectFromEvent($event); + + /** + * Load an existing object from the database + */ + protected abstract function getExistingObject(); + + /** + * Returns the object label form the object event (name, title, etc.) + * + * @param unknown $object + */ + protected abstract function getObjectLabel($object); + + /** + * Returns the object ID from the object + * + * @param unknown $object + */ + protected abstract function getObjectId($object); + + /** + * Render the main list template + * + * @param unknown $currentOrder, if any, null otherwise. + */ + protected abstract function renderListTemplate($currentOrder); + + /** + * Render the edition template + */ + protected abstract function renderEditionTemplate(); + + /** + * Redirect to the edition template + */ + protected abstract function redirectToEditionTemplate(); + + /** + * Redirect to the list template + */ + protected abstract function redirectToListTemplate(); + + + protected function createUpdatePositionEvent($positionChangeMode, $positionValue) { + throw new \LogicException ("Position Update is not supported for this object"); + } + + protected function createToggleVisibilityEvent() { + + throw new \LogicException ("Toggle Visibility is not supported for this object"); + } + + /** + * Render the object list, ensuring the sort order is set. + * + * @return Symfony\Component\HttpFoundation\Response the response + */ + protected function renderList() + { + $order = null; + + if ($this->defaultListOrder != null) { + $orderSessionIdentifier = sprintf("admin.%s.currentListOrder", $this->objectName); + + // Find the current order + $order = $this->getRequest()->get( + 'order', + $this->getSession()->get($orderSessionIdentifier, $this->defaultListOrder) + ); + + // Store the current sort order in session + $this->getSession()->set($orderSessionIdentifier, $order); + } + + return $this->renderListTemplate($order); + } + + /** + * The default action is displaying the list. + * + * @return Symfony\Component\HttpFoundation\Response the response + */ + public function defaultAction() + { + if (null !== $response = $this->checkAuth($this->viewPermissionIdentifier)) return $response; + + return $this->renderList(); + } + + /** + * Create a new object + * + * @return Symfony\Component\HttpFoundation\Response the response + */ + public function createAction() + { + // Check current user authorization + if (null !== $response = $this->checkAuth($this->createPermissionIdentifier)) return $response; + + $error_msg = false; + + // Create the Creation Form + $creationForm = $this->getCreationForm($this->getRequest()); + + try { + + // Validate the form, create the event and dispatch it. + $form = $this->validateForm($creationForm, "POST"); + + $data = $form->getData(); + + $createEvent = $this->getCreationEvent($data); + + $this->dispatch($this->createEventIdentifier, $createEvent); + + if (! $this->eventContainsObject($createEvent)) + throw new \LogicException( + $this->getTranslator()->trans("No %obj was created.", array('%obj', $this->objectName))); + + if (null !== $createdObject = $this->getObjectFromEvent($createEvent)) { + // Log object creation + $this->adminLogAppend(sprintf("%s %s (ID %s) created", ucfirst($this->objectName), $this->getObjectLabel($createdObject), $this->getObjectId($createdObject))); + } + + // Substitute _ID_ in the URL with the ID of the created object + $successUrl = str_replace('_ID_', $this->getObjectId($createdObject), $creationForm->getSuccessUrl()); + + // Redirect to the success URL + $this->redirect($successUrl); + + } + catch (FormValidationException $ex) { + // Form cannot be validated + $error_msg = $this->createStandardFormValidationErrorMessage($ex); + } + catch (\Exception $ex) { + // Any other error + $error_msg = $ex->getMessage(); + } + + $this->setupFormErrorContext( + $this->getTranslator()->trans("%obj creation", array('%obj' => $this->objectName)), $error_msg, $creationForm, $ex); + + // At this point, the form has error, and should be redisplayed. + return $this->renderList(); + } + + /** + * Load a object for modification, and display the edit template. + * + * @return Symfony\Component\HttpFoundation\Response the response + */ + public function changeAction() + { + // Check current user authorization + if (null !== $response = $this->checkAuth($this->updatePermissionIdentifier)) return $response; + + // Load the object + $object = $this->getExistingObject($this->getRequest()); + + if ($object != null) { + + // Hydrate the form abd pass it to the parser + $changeForm = $this->hydrateObjectForm($object); + + // Pass it to the parser + $this->getParserContext()->addForm($changeForm); + } + + // Render the edition template. + return $this->renderEditionTemplate(); + } + + /** + * 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 saveChangeAction() + { + // Check current user authorization + if (null !== $response = $this->checkAuth($this->updatePermissionIdentifier)) return $response; + + $error_msg = false; + + // Create the form from the request + $changeForm = $this->getUpdateForm($this->getRequest()); + + try { + + // Check the form against constraints violations + $form = $this->validateForm($changeForm, "POST"); + + // Get the form field values + $data = $form->getData(); + + $changeEvent = $this->getUpdateEvent($data); + + $this->dispatch($this->updateEventIdentifier, $changeEvent); + + if (! $this->eventContainsObject($changeEvent)) + throw new \LogicException( + $this->getTranslator()->trans("No %obj was updated.", array('%obj', $this->objectName))); + + // Log object modification + if (null !== $changedObject = $this->getObjectFromEvent($changeEvent)) { + $this->adminLogAppend(sprintf("%s %s (ID %s) modified", ucfirst($this->objectName), $this->getObjectLabel($changedObject), $this->getObjectId($changedObject))); + } + + // If we have to stay on the same page, do not redirect to the succesUrl, + // just redirect to the edit page again. + if ($this->getRequest()->get('save_mode') == 'stay') { + $this->redirectToEditionTemplate($this->getRequest()); + } + + // Redirect to the success URL + $this->redirect($changeForm->getSuccessUrl()); + } + catch (FormValidationException $ex) { + // Form cannot be validated + $error_msg = $this->createStandardFormValidationErrorMessage($ex); + } + catch (\Exception $ex) { + // Any other error + $error_msg = $ex->getMessage(); + } + + $this->setupFormErrorContext( + $this->getTranslator()->trans("%obj modification", array('%obj' => $this->objectName)), $error_msg, $changeForm, $ex); + + // At this point, the form has errors, and should be redisplayed. + return $this->renderEditionTemplate(); + } + + /** + * Update object position (only for objects whichsupport that) + */ + public function updatePositionAction() + { + // Check current user authorization + if (null !== $response = $this->checkAuth($this->updatePermissionIdentifier)) return $response; + + try { + $mode = $this->getRequest()->get('mode', null); + + if ($mode == 'up') + $mode = UpdatePositionEvent::POSITION_UP; + else if ($mode == 'down') + $mode = UpdatePositionEvent::POSITION_DOWN; + else + $mode = UpdatePositionEvent::POSITION_ABSOLUTE; + + $position = $this->getRequest()->get('position', null); + + $event = $this->createUpdatePositionEvent($mode, $position); + + $this->dispatch($this->changePositionEventIdentifier, $event); + } + catch (\Exception $ex) { + // Any error + return $this->errorPage($ex); + } + + $this->redirectToListTemplate(); + } + + /** + * Online status toggle (only for object which support it) + */ + public function setToggleVisibilityAction() + { + // Check current user authorization + if (null !== $response = $this->checkAuth($this->updatePermissionIdentifier)) return $response; + + $changeEvent = $this->createToggleVisibilityEvent($this->getRequest()); + + // Create and dispatch the change event + $changeEvent->setIsDefault(true); + + try { + $this->dispatch($this->visibilityToggleEventIdentifier, $changeEvent); + } catch (\Exception $ex) { + // Any error + return $this->errorPage($ex); + } + + $this->redirectToRoute('admin.categories.default'); + } + + /** + * Delete an object + * + * @return Symfony\Component\HttpFoundation\Response the response + */ + public function deleteAction() + { + // Check current user authorization + if (null !== $response = $this->checkAuth($this->deletePermissionIdentifier)) return $response; + + // Get the currency id, and dispatch the delet request + $deleteEvent = $this->getDeleteEvent(); + + $this->dispatch($this->deleteEventIdentifier, $deleteEvent); + + if (null !== $deletedObject = $this->getObjectFromEvent($deleteEvent)) { + $this->adminLogAppend( + sprintf("%s %s (ID %s) deleted", ucfirst($this->objectName), $this->getObjectLabel($deletedObject), $this->getObjectId($deletedObject))); + } + + $this->redirectToListTemplate(); + } +} diff --git a/core/lib/Thelia/Controller/Admin/AttributeController.php b/core/lib/Thelia/Controller/Admin/AttributeController.php index 0e1633210..d775c97c6 100644 --- a/core/lib/Thelia/Controller/Admin/AttributeController.php +++ b/core/lib/Thelia/Controller/Admin/AttributeController.php @@ -1,7 +1,7 @@ . */ +/* along with this program. If not, see . */ /* */ /*************************************************************************************/ @@ -25,361 +25,140 @@ namespace Thelia\Controller\Admin; use Thelia\Core\Event\AttributeDeleteEvent; use Thelia\Core\Event\TheliaEvents; -use Thelia\Tools\URL; use Thelia\Core\Event\AttributeUpdateEvent; use Thelia\Core\Event\AttributeCreateEvent; -use Thelia\Log\Tlog; -use Thelia\Form\Exception\FormValidationException; -use Thelia\Core\Security\Exception\AuthorizationException; use Thelia\Model\AttributeQuery; use Thelia\Form\AttributeModificationForm; use Thelia\Form\AttributeCreationForm; -use Thelia\Core\Event\AttributeUpdatePositionEvent; -use Thelia\Form\AttributeValueCreationForm; -use Thelia\Core\Event\AttributeValueCreateEvent; -use Thelia\Core\Event\AttributeValueDeleteEvent; +use Thelia\Core\Event\UpdatePositionEvent; /** - * Manages product attributes + * Manages attributes sent by mail * * @author Franck Allimant */ -class AttributeController extends BaseAdminController +class AttributeController extends AbstractCrudController { - /** - * Render the attributes list, ensuring the sort order is set. - * - * @return Symfony\Component\HttpFoundation\Response the response - */ - protected function renderList() { + public function __construct() { + parent::__construct( + 'attribute', + 'manual', - // Find the current order - $order = $this->getRequest()->get( - 'order', - $this->getSession()->get('admin.attribute_order', 'manual') + 'admin.configuration.attributes.view', + 'admin.configuration.attributes.create', + 'admin.configuration.attributes.update', + 'admin.configuration.attributes.delete', + + TheliaEvents::ATTRIBUTE_CREATE, + TheliaEvents::ATTRIBUTE_UPDATE, + TheliaEvents::ATTRIBUTE_DELETE, + null, // No visibility toggle + TheliaEvents::ATTRIBUTE_UPDATE_POSITION + ); + } + + protected function getCreationForm() { + return new AttributeCreationForm($this->getRequest()); + } + + protected function getUpdateForm() { + return new AttributeModificationForm($this->getRequest()); + } + + protected function getCreationEvent($formData) { + $createEvent = new AttributeCreateEvent(); + + $createEvent + ->setTitle($formData['title']) + ->setLocale($formData["locale"]) + ->setAddToAllTemplates($formData['add_to_all']) + ; + + return $createEvent; + } + + protected function getUpdateEvent($formData) { + + $changeEvent = new AttributeUpdateEvent($formData['id']); + + // Create and dispatch the change event + $changeEvent + ->setLocale($formData["locale"]) + ->setTitle($formData['title']) + ->setChapo($formData['chapo']) + ->setDescription($formData['description']) + ->setPostscriptum($formData['postscriptum']) + ; + + return $changeEvent; + } + + protected function createUpdatePositionEvent($positionChangeMode, $positionValue) { + + return new UpdatePositionEvent( + $this->getRequest()->get('attribute_id', null), + $positionChangeMode, + $positionValue + ); + } + + protected function getDeleteEvent() { + return new AttributeDeleteEvent($this->getRequest()->get('attribute_id')); + } + + protected function eventContainsObject($event) { + return $event->hasAttribute(); + } + + protected function hydrateObjectForm($object) { + + $data = array( + 'id' => $object->getId(), + 'locale' => $object->getLocale(), + 'title' => $object->getTitle(), + 'chapo' => $object->getChapo(), + 'description' => $object->getDescription(), + 'postscriptum' => $object->getPostscriptum() ); - // Store the current sort order in session - $this->getSession()->set('admin.attribute_order', $order); - - return $this->render('attributes', array('order' => $order)); + // Setup the object form + $changeForm = new AttributeModificationForm($this->getRequest(), "form", $data); } - /** - * The default action is displaying the product attributes list. - * - * @return Symfony\Component\HttpFoundation\Response the response - */ - public function defaultAction() { - - if (null !== $response = $this->checkAuth("admin.configuration.attributes.view")) return $response; - - return $this->renderList(); + protected function getObjectFromEvent($event) { + return $event->hasAttribute() ? $event->getAttribute() : null; } - /** - * Create a new product attribute object - * - * @return Symfony\Component\HttpFoundation\Response the response - */ - public function createAction() { - - // Check current user authorization - if (null !== $response = $this->checkAuth("admin.configuration.attributes.create")) return $response; - - $error_msg = false; - - // Create the Creation Form - $creationForm = new AttributeCreationForm($this->getRequest()); - - try { - - // Validate the form, create the AttributeCreation event and dispatch it. - $form = $this->validateForm($creationForm, "POST"); - - $data = $form->getData(); - - $createEvent = new AttributeCreateEvent(); - - $createEvent - ->setTitle($data['title']) - ->setLocale($data["locale"]) - ->setAddToAllTemplates($data['add_to_all']) - ; - - $this->dispatch(TheliaEvents::ATTRIBUTE_CREATE, $createEvent); - - if (! $createEvent->hasAttribute()) throw new \LogicException($this->getTranslator()->trans("No product attribute was created.")); - - $createdObject = $createEvent->getAttribute(); - - // Log product attribute creation - $this->adminLogAppend(sprintf("Attribute %s (ID %s) created", $createdObject->getTitle(), $createdObject->getId())); - - // Substitute _ID_ in the URL with the ID of the created object - $successUrl = str_replace('_ID_', $createdObject->getId(), $creationForm->getSuccessUrl()); - - // Redirect to the success URL - $this->redirect($successUrl); - } - catch (FormValidationException $ex) { - // Form cannot be validated - $error_msg = $this->createStandardFormValidationErrorMessage($ex); - } - catch (\Exception $ex) { - // Any other error - $error_msg = $ex->getMessage(); - } - - $this->setupFormErrorContext("product attribute creation", $error_msg, $creationForm, $ex); - - // At this point, the form has error, and should be redisplayed. - return $this->renderList(); + protected function getExistingObject() { + return AttributeQuery::create() + ->joinWithI18n($this->getCurrentEditionLocale()) + ->findOneById($this->getRequest()->get('attribute_id')); } - /** - * Create a new product attribute value object - * - * @return Symfony\Component\HttpFoundation\Response the response - */ - public function createValueAction() { + protected function getObjectLabel($object) { + return $object->getName(); + } - // Check current user authorization - if (null !== $response = $this->checkAuth("admin.configuration.attribute-values.create")) return $response; + protected function getObjectId($object) { + return $object->getId(); + } - $error_msg = false; + protected function renderListTemplate($currentOrder) { + return $this->render('attributes', array('order' => $currentOrder)); + } - // Create the Creation Form - $creationForm = new AttributeValueCreationForm($this->getRequest()); - - try { - - // Validate the form, create the AttributeCreation event and dispatch it. - $form = $this->validateForm($creationForm, "POST"); - - $data = $form->getData(); - - $createEvent = new AttributeValueCreateEvent(); - - $createEvent - ->setTitle($data['title']) - ->setLocale($data["locale"]) - ->setAttributeId($data["attribute_id"]) - ; - - $this->dispatch(TheliaEvents::ATTRIBUTE_VALUE_CREATE, $createEvent); - - if (! $createEvent->hasAttribute()) throw new \LogicException($this->getTranslator()->trans("No product attribute value was created.")); - - $createdObject = $createEvent->getAttributeValue(); - - // Log product attribute creation - $this->adminLogAppend(sprintf("Attribute value %s (ID %s) created", $createdObject->getTitle(), $createdObject->getId())); - - // Redirect to the success URL - $this->redirect($creationForm->getSuccessUrl()); - } - catch (FormValidationException $ex) { - // Form cannot be validated - $error_msg = $this->createStandardFormValidationErrorMessage($ex); - } - catch (\Exception $ex) { - // Any other error - $error_msg = $ex->getMessage(); - } - - $this->setupFormErrorContext("product attribute value creation", $error_msg, $creationForm, $ex); - - // At this point, the form has error, and should be redisplayed on the edition page + protected function renderEditionTemplate() { return $this->render('attribute-edit', array('attribute_id' => $this->getRequest()->get('attribute_id'))); } - /** - * Load a product attribute object for modification, and display the edit template. - * - * @return Symfony\Component\HttpFoundation\Response the response - */ - public function changeAction() { - - // Check current user authorization - if (null !== $response = $this->checkAuth("admin.configuration.attributes.update")) return $response; - - // Load the product attribute object - $attribute = AttributeQuery::create() - ->joinWithI18n($this->getCurrentEditionLocale()) - ->findOneById($this->getRequest()->get('attribute_id')); - - if ($attribute != null) { - - // Prepare the data that will hydrate the form - $data = array( - 'id' => $attribute->getId(), - 'locale' => $attribute->getLocale(), - 'title' => $attribute->getTitle(), - 'chapo' => $attribute->getChapo(), - 'description' => $attribute->getDescription(), - 'postscriptum' => $attribute->getPostscriptum() - ); - - // Setup the object form - $changeForm = new AttributeModificationForm($this->getRequest(), "form", $data); - - // Pass it to the parser - $this->getParserContext()->addForm($changeForm); - } - - // Render the edition template. - return $this->render('attribute-edit', array('attribute_id' => $this->getRequest()->get('attribute_id'))); + protected function redirectToEditionTemplate() { + $this->redirectToRoute( + "admin.configuration.attributes.update", + array('attribute_id' => $this->getRequest()->get('attribute_id')) + ); } - /** - * Save changes on a modified product attribute object, and either go back to the product attribute list, or stay on the edition page. - * - * @return Symfony\Component\HttpFoundation\Response the response - */ - public function saveChangeAction() { - - // Check current user authorization - if (null !== $response = $this->checkAuth("admin.configuration.attributes.update")) return $response; - - $error_msg = false; - - // Create the form from the request - $changeForm = new AttributeModificationForm($this->getRequest()); - - // Get the attribute ID - $attribute_id = $this->getRequest()->get('attribute_id'); - - try { - - // Check the form against constraints violations - $form = $this->validateForm($changeForm, "POST"); - - // Get the form field values - $data = $form->getData(); - - $changeEvent = new AttributeUpdateEvent($data['id']); - - // Create and dispatch the change event - $changeEvent - ->setLocale($data["locale"]) - ->setTitle($data['title']) - ->setChapo($data['chapo']) - ->setDescription($data['description']) - ->setPostscriptum($data['postscriptum']) - ; - - $this->dispatch(TheliaEvents::ATTRIBUTE_UPDATE, $changeEvent); - - if (! $changeEvent->hasAttribute()) throw new \LogicException($this->getTranslator()->trans("No product attribute was updated.")); - - // Log product attribute modification - $changedObject = $changeEvent->getAttribute(); - - $this->adminLogAppend(sprintf("Attribute %s (ID %s) modified", $changedObject->getTitle(), $changedObject->getId())); - - // If we have to stay on the same page, do not redirect to the succesUrl, - // just redirect to the edit page again. - if ($this->getRequest()->get('save_mode') == 'stay') { - $this->redirectToRoute( - "admin.configuration.attributes.update", - array('attribute_id' => $attribute_id) - ); - } - - // Redirect to the success URL - $this->redirect($changeForm->getSuccessUrl()); - } - catch (FormValidationException $ex) { - // Form cannot be validated - $error_msg = $this->createStandardFormValidationErrorMessage($ex); - } - catch (\Exception $ex) { - // Any other error - $error_msg = $ex->getMessage(); - } - - $this->setupFormErrorContext("product attribute modification", $error_msg, $changeForm, $ex); - - // At this point, the form has errors, and should be redisplayed. - return $this->render('attribute-edit', array('attribute_id' => $attribute_id)); - } - - /** - * Update product attribute position - */ - public function updatePositionAction() { - // Check current user authorization - if (null !== $response = $this->checkAuth("admin.configuration.attributes.update")) return $response; - - try { - $mode = $this->getRequest()->get('mode', null); - - if ($mode == 'up') - $mode = AttributeUpdatePositionEvent::POSITION_UP; - else if ($mode == 'down') - $mode = AttributeUpdatePositionEvent::POSITION_DOWN; - else - $mode = AttributeUpdatePositionEvent::POSITION_ABSOLUTE; - - $position = $this->getRequest()->get('position', null); - - $event = new AttributeUpdatePositionEvent( - $this->getRequest()->get('attribute_id', null), - $mode, - $this->getRequest()->get('position', null) - ); - - $this->dispatch(TheliaEvents::ATTRIBUTE_UPDATE_POSITION, $event); - } - catch (\Exception $ex) { - // Any error - return $this->errorPage($ex); - } - - $this->redirectToRoute('admin.configuration.attributes.default'); - } - - - /** - * Delete a product attribute object - * - * @return Symfony\Component\HttpFoundation\Response the response - */ - public function deleteAction() { - - // Check current user authorization - if (null !== $response = $this->checkAuth("admin.configuration.product attributes.delete")) return $response; - - // Get the product attribute id, and dispatch the delet request - $event = new AttributeDeleteEvent($this->getRequest()->get('attribute_id')); - - $this->dispatch(TheliaEvents::ATTRIBUTE_DELETE, $event); - - if ($event->hasAttribute()) - $this->adminLogAppend(sprintf("Attribute %s (ID %s) deleted", $event->getAttribute()->getTitle(), $event->getAttribute()->getId())); - - $this->redirectToRoute('admin.configuration.attributes.default'); - } - - /** - * Delete a product attribute value object - * - * @return Symfony\Component\HttpFoundation\Response the response - */ - public function deleteValueAction() { - - // Check current user authorization - if (null !== $response = $this->checkAuth("admin.configuration.product attribute-values.delete")) return $response; - - // Get the product attribute id, and dispatch the delet request - $event = new AttributeValueDeleteEvent($this->getRequest()->get('value_id')); - - $this->dispatch(TheliaEvents::ATTRIBUTE_VALUE_DELETE, $event); - - if ($event->hasAttributeValue()) - $this->adminLogAppend(sprintf("Attribute value %s (ID %s) deleted", $event->getAttributeValue()->getTitle(), $event->getAttributeValue()->getId())); - + protected function redirectToListTemplate() { $this->redirectToRoute('admin.configuration.attributes.default'); } } \ No newline at end of file diff --git a/core/lib/Thelia/Controller/Admin/ConfigController.php b/core/lib/Thelia/Controller/Admin/ConfigController.php index 785920562..ee88e99e0 100644 --- a/core/lib/Thelia/Controller/Admin/ConfigController.php +++ b/core/lib/Thelia/Controller/Admin/ConfigController.php @@ -25,228 +25,144 @@ namespace Thelia\Controller\Admin; use Thelia\Core\Event\ConfigDeleteEvent; use Thelia\Core\Event\TheliaEvents; -use Thelia\Tools\URL; use Thelia\Core\Event\ConfigUpdateEvent; use Thelia\Core\Event\ConfigCreateEvent; -use Thelia\Form\Exception\FormValidationException; use Thelia\Model\ConfigQuery; use Thelia\Form\ConfigModificationForm; use Thelia\Form\ConfigCreationForm; +use Thelia\Core\Event\UpdatePositionEvent; /** - * Manages Thelmia system variables, aka Config objects. + * Manages variables sent by mail * * @author Franck Allimant */ -class ConfigController extends BaseAdminController +class ConfigController extends AbstractCrudController { - /** - * Render the currencies list, ensuring the sort order is set. - * - * @return Symfony\Component\HttpFoundation\Response the response - */ - protected function renderList() - { - // Find the current order - $order = $this->getRequest()->get( - 'order', - $this->getSession()->get('admin.variables_order', 'name') + public function __construct() { + parent::__construct( + 'variable', + 'name', + + 'admin.configuration.variables.view', + 'admin.configuration.variables.create', + 'admin.configuration.variables.update', + 'admin.configuration.variables.delete', + + TheliaEvents::CONFIG_CREATE, + TheliaEvents::CONFIG_UPDATE, + TheliaEvents::CONFIG_DELETE, + null, // No visibility toggle + null // no position change + ); + } + + protected function getCreationForm() { + return new ConfigCreationForm($this->getRequest()); + } + + protected function getUpdateForm() { + return new ConfigModificationForm($this->getRequest()); + } + + protected function getCreationEvent($data) { + $createEvent = new ConfigCreateEvent(); + + $createEvent + ->setEventName($data['name']) + ->setValue($data['value']) + ->setLocale($data["locale"]) + ->setTitle($data['title']) + ->setHidden($data['hidden']) + ->setSecured($data['secured']) + ; + + + return $createEvent; + } + + protected function getUpdateEvent($data) { + $changeEvent = new ConfigUpdateEvent($data['id']); + + // Create and dispatch the change event + $changeEvent + ->setEventName($data['name']) + ->setValue($data['value']) + ->setHidden($data['hidden']) + ->setSecured($data['secured']) + ->setLocale($data["locale"]) + ->setTitle($data['title']) + ->setChapo($data['chapo']) + ->setDescription($data['description']) + ->setPostscriptum($data['postscriptum']) + ; + + return $changeEvent; + } + + protected function getDeleteEvent() { + return new ConfigDeleteEvent($this->getRequest()->get('variable_id')); + } + + protected function eventContainsObject($event) { + return $event->hasConfig(); + } + + protected function hydrateObjectForm($object) { + + // Prepare the data that will hydrate the form + $data = array( + 'id' => $object->getId(), + 'name' => $object->getName(), + 'value' => $object->getValue(), + 'hidden' => $object->getHidden(), + 'secured' => $object->getSecured(), + 'locale' => $object->getLocale(), + 'title' => $object->getTitle(), + 'chapo' => $object->getChapo(), + 'description' => $object->getDescription(), + 'postscriptum' => $object->getPostscriptum() ); - // Store the current sort order in session - $this->getSession()->set('admin.variables_order', $order); - - return $this->render('variables', array('order' => $order)); + // Setup the object form + return new ConfigModificationForm($this->getRequest(), "form", $data); } - /** - * The default action is displaying the variables list. - * - * @return Symfony\Component\HttpFoundation\Response the response - */ - public function defaultAction() - { - if (null !== $response = $this->checkAuth("admin.configuration.variables.view")) return $response; - return $this->renderList(); + protected function getObjectFromEvent($event) { + return $event->hasConfig() ? $event->getConfig() : null; } - /** - * Create a new config object - * - * @return Symfony\Component\HttpFoundation\Response the response - */ - public function createAction() - { - // Check current user authorization - if (null !== $response = $this->checkAuth("admin.configuration.variables.create")) return $response; - - $message = false; - - // Create the Creation Form - $creationForm = new ConfigCreationForm($this->getRequest()); - - try { - - // Validate the form, create the ConfigCreation event and dispatch it. - $form = $this->validateForm($creationForm, "POST"); - - $data = $form->getData(); - - $createEvent = new ConfigCreateEvent(); - - $createEvent - ->setEventName($data['name']) - ->setValue($data['value']) - ->setLocale($data["locale"]) - ->setTitle($data['title']) - ->setHidden($data['hidden']) - ->setSecured($data['secured']) - ; - - $this->dispatch(TheliaEvents::CONFIG_CREATE, $createEvent); - - if (! $createEvent->hasConfig()) throw new \LogicException($this->getTranslator()->trans("No variable was created.")); - - $createdObject = $createEvent->getConfig(); - - // Log config creation - $this->adminLogAppend(sprintf("Variable %s (ID %s) created", $createdObject->getName(), $createdObject->getId())); - - // Substitute _ID_ in the URL with the ID of the created object - $successUrl = str_replace('_ID_', $createdObject->getId(), $creationForm->getSuccessUrl()); - - // Redirect to the success URL - $this->redirect($successUrl); - } catch (FormValidationException $ex) { - // Form cannot be validated - $message = $this->createStandardFormValidationErrorMessage($ex); - } catch (\Exception $ex) { - // Any other error - $message = $ex->getMessage(); - } - - $this->setupFormErrorContext("variable creation", $message, $creationForm, $ex); - - // At this point, the form has error, and should be redisplayed. - return $this->renderList(); + protected function getExistingObject() { + return ConfigQuery::create() + ->joinWithI18n($this->getCurrentEditionLocale()) + ->findOneById($this->getRequest()->get('variable_id')); } - /** - * Load a config object for modification, and display the edit template. - * - * @return Symfony\Component\HttpFoundation\Response the response - */ - public function changeAction() - { - // Check current user authorization - if (null !== $response = $this->checkAuth("admin.configuration.variables.update")) return $response; + protected function getObjectLabel($object) { + return $object->getName(); + } - // Load the config object - $config = ConfigQuery::create() - ->joinWithI18n($this->getCurrentEditionLocale()) - ->findOneById($this->getRequest()->get('variable_id')); + protected function getObjectId($object) { + return $object->getId(); + } - if ($config != null) { + protected function renderListTemplate($currentOrder) { + return $this->render('variables', array('order' => $currentOrder)); + } - // Prepare the data that will hydrate the form - $data = array( - 'id' => $config->getId(), - 'name' => $config->getName(), - 'value' => $config->getValue(), - 'hidden' => $config->getHidden(), - 'secured' => $config->getSecured(), - 'locale' => $config->getLocale(), - 'title' => $config->getTitle(), - 'chapo' => $config->getChapo(), - 'description' => $config->getDescription(), - 'postscriptum' => $config->getPostscriptum() - ); - - // Setup the object form - $changeForm = new ConfigModificationForm($this->getRequest(), "form", $data); - - // Pass it to the parser - $this->getParserContext()->addForm($changeForm); - } - - // Render the edition template. + protected function renderEditionTemplate() { return $this->render('variable-edit', array('variable_id' => $this->getRequest()->get('variable_id'))); } - /** - * Save changes on a modified config object, and either go back to the variable list, or stay on the edition page. - * - * @return Symfony\Component\HttpFoundation\Response the response - */ - public function saveChangeAction() - { - // Check current user authorization - if (null !== $response = $this->checkAuth("admin.configuration.variables.update")) return $response; + protected function redirectToEditionTemplate() { + $this->redirectToRoute( + "admin.configuration.variables.update", + array('variable_id' => $this->getRequest()->get('variable_id')) + ); + } - $message = false; - - // Create the form from the request - $changeForm = new ConfigModificationForm($this->getRequest()); - - // Get the variable ID - $variable_id = $this->getRequest()->get('variable_id'); - - try { - - // Check the form against constraints violations - $form = $this->validateForm($changeForm, "POST"); - - // Get the form field values - $data = $form->getData(); - - $changeEvent = new ConfigUpdateEvent($data['id']); - - // Create and dispatch the change event - $changeEvent - ->setEventName($data['name']) - ->setValue($data['value']) - ->setHidden($data['hidden']) - ->setSecured($data['secured']) - ->setLocale($data["locale"]) - ->setTitle($data['title']) - ->setChapo($data['chapo']) - ->setDescription($data['description']) - ->setPostscriptum($data['postscriptum']) - ; - - $this->dispatch(TheliaEvents::CONFIG_UPDATE, $changeEvent); - - if (! $changeEvent->hasConfig()) throw new \LogicException($this->getTranslator()->trans("No variable was updated.")); - - // Log config modification - $changedObject = $changeEvent->getConfig(); - - $this->adminLogAppend(sprintf("Variable %s (ID %s) modified", $changedObject->getName(), $changedObject->getId())); - - // If we have to stay on the same page, do not redirect to the succesUrl, - // just redirect to the edit page again. - if ($this->getRequest()->get('save_mode') == 'stay') { - - $this->redirectToRoute( - "admin.configuration.variables.update", - array('variable_id' => $variable_id) - ); - } - - // Redirect to the success URL - $this->redirect($changeForm->getSuccessUrl()); - } catch (FormValidationException $ex) { - // Form cannot be validated - $message = $this->createStandardFormValidationErrorMessage($ex); - } catch (\Exception $ex) { - // Any other error - $message = $ex->getMessage(); - } - - $this->setupFormErrorContext("variable edition", $message, $changeForm, $ex); - - // At this point, the form has errors, and should be redisplayed. - return $this->render('variable-edit', array('variable_id' => $variable_id)); + protected function redirectToListTemplate() { + $this->redirectToRoute('admin.configuration.variables.default'); } /** @@ -271,25 +187,4 @@ class ConfigController extends BaseAdminController $this->redirectToRoute('admin.configuration.variables.default'); } - - /** - * Delete a config object - * - * @return Symfony\Component\HttpFoundation\Response the response - */ - public function deleteAction() - { - // Check current user authorization - if (null !== $response = $this->checkAuth("admin.configuration.variables.delete")) return $response; - - // Get the config id, and dispatch the delet request - $event = new ConfigDeleteEvent($this->getRequest()->get('variable_id')); - - $this->dispatch(TheliaEvents::CONFIG_DELETE, $event); - - if ($event->hasConfig()) - $this->adminLogAppend(sprintf("Variable %s (ID %s) deleted", $event->getConfig()->getName(), $event->getConfig()->getId())); - - $this->redirectToRoute('admin.configuration.variables.default'); - } -} +} \ No newline at end of file diff --git a/core/lib/Thelia/Controller/Admin/CurrencyController.php b/core/lib/Thelia/Controller/Admin/CurrencyController.php index ae1005432..2df950984 100644 --- a/core/lib/Thelia/Controller/Admin/CurrencyController.php +++ b/core/lib/Thelia/Controller/Admin/CurrencyController.php @@ -103,11 +103,6 @@ class CurrencyController extends AbstractCrudController ); } - protected function createToggleVisibilityEvent() { - - return new ToggleVisibilityEvent($this->getRequest()->get('currency_id', null)); - } - protected function getDeleteEvent() { return new CurrencyDeleteEvent($this->getRequest()->get('currency_id')); } diff --git a/core/lib/Thelia/Controller/Admin/MessageController.php b/core/lib/Thelia/Controller/Admin/MessageController.php index d2d319255..f87218116 100644 --- a/core/lib/Thelia/Controller/Admin/MessageController.php +++ b/core/lib/Thelia/Controller/Admin/MessageController.php @@ -24,11 +24,8 @@ namespace Thelia\Controller\Admin; use Thelia\Core\Event\MessageDeleteEvent; -use Thelia\Core\Event\TheliaEvents; -use Thelia\Tools\URL; -use Thelia\Core\Event\MessageUpdateEvent; +use Thelia\Core\Event\TheliaEvents;use Thelia\Core\Event\MessageUpdateEvent; use Thelia\Core\Event\MessageCreateEvent; -use Thelia\Form\Exception\FormValidationException; use Thelia\Model\MessageQuery; use Thelia\Form\MessageModificationForm; use Thelia\Form\MessageCreationForm; @@ -38,217 +35,124 @@ use Thelia\Form\MessageCreationForm; * * @author Franck Allimant */ -class MessageController extends BaseAdminController +class MessageController extends AbstractCrudController { - /** - * Render the messages list - * - * @return Symfony\Component\HttpFoundation\Response the response - */ - protected function renderList() - { + public function __construct() { + parent::__construct( + 'message', + null, + + 'admin.configuration.messages.view', + 'admin.configuration.messages.create', + 'admin.configuration.messages.update', + 'admin.configuration.messages.delete', + + TheliaEvents::MESSAGE_CREATE, + TheliaEvents::MESSAGE_UPDATE, + TheliaEvents::MESSAGE_DELETE, + null, // No visibility toggle + null // No position update + ); + } + + protected function getCreationForm() { + return new MessageCreationForm($this->getRequest()); + } + + protected function getUpdateForm() { + return new MessageModificationForm($this->getRequest()); + } + + protected function getCreationEvent($formData) { + $createEvent = new MessageCreateEvent(); + + $createEvent + ->setMessageName($formData['name']) + ->setLocale($formData["locale"]) + ->setTitle($formData['title']) + ->setSecured($formData['secured']) + ; + + return $createEvent; + } + + protected function getUpdateEvent($formData) { + $changeEvent = new MessageUpdateEvent($formData['id']); + + // Create and dispatch the change event + $changeEvent + ->setMessageName($formData['name']) + ->setSecured($formData['secured']) + ->setLocale($formData["locale"]) + ->setTitle($formData['title']) + ->setSubject($formData['subject']) + ->setHtmlMessage($formData['html_message']) + ->setTextMessage($formData['text_message']) + ; + + return $changeEvent; + } + + protected function getDeleteEvent() { + return new MessageDeleteEvent($this->getRequest()->get('message_id')); + } + + protected function eventContainsObject($event) { + return $event->hasMessage(); + } + + protected function hydrateObjectForm($object) { + + // Prepare the data that will hydrate the form + $data = array( + 'id' => $object->getId(), + 'name' => $object->getName(), + 'secured' => $object->getSecured(), + 'locale' => $object->getLocale(), + 'title' => $object->getTitle(), + 'subject' => $object->getSubject(), + 'html_message' => $object->getHtmlMessage(), + 'text_message' => $object->getTextMessage() + ); + + // Setup the object form + return new MessageModificationForm($this->getRequest(), "form", $data); + } + + protected function getObjectFromEvent($event) { + return $event->hasMessage() ? $event->getMessage() : null; + } + + protected function getExistingObject() { + return MessageQuery::create() + ->joinWithI18n($this->getCurrentEditionLocale()) + ->findOneById($this->getRequest()->get('message_id')); + } + + protected function getObjectLabel($object) { + return $object->getName(); + } + + protected function getObjectId($object) { + return $object->getId(); + } + + protected function renderListTemplate($currentOrder) { return $this->render('messages'); } - /** - * The default action is displaying the messages list. - * - * @return Symfony\Component\HttpFoundation\Response the response - */ - public function defaultAction() - { - if (null !== $response = $this->checkAuth("admin.configuration.messages.view")) return $response; - return $this->renderList(); - } - - /** - * Create a new message object - * - * @return Symfony\Component\HttpFoundation\Response the response - */ - public function createAction() - { - // Check current user authorization - if (null !== $response = $this->checkAuth("admin.configuration.messages.create")) return $response; - - $message = false; - - // Create the creation Form - $creationForm = new MessageCreationForm($this->getRequest()); - - try { - - // Validate the form, create the MessageCreation event and dispatch it. - $form = $this->validateForm($creationForm, "POST"); - - $data = $form->getData(); - - $createEvent = new MessageCreateEvent(); - - $createEvent - ->setMessageName($data['name']) - ->setLocale($data["locale"]) - ->setTitle($data['title']) - ->setSecured($data['secured']) - ; - - $this->dispatch(TheliaEvents::MESSAGE_CREATE, $createEvent); - - if (! $createEvent->hasMessage()) throw new \LogicException($this->getTranslator()->trans("No message was created.")); - - $createdObject = $createEvent->getMessage(); - - $this->adminLogAppend(sprintf("Message %s (ID %s) created", $createdObject->getName(), $createdObject->getId())); - - // Substitute _ID_ in the URL with the ID of the created object - $successUrl = str_replace('_ID_', $createdObject->getId(), $creationForm->getSuccessUrl()); - - // Redirect to the success URL - $this->redirect($successUrl); - } catch (FormValidationException $ex) { - // Form cannot be validated - $message = $this->createStandardFormValidationErrorMessage($ex); - } catch (\Exception $ex) { - // Any other error - $message = $ex->getMessage(); - } - - $this->setupFormErrorContext("message modification", $message, $creationForm, $ex); - - // At this point, the form has error, and should be redisplayed. - return $this->render('messages'); - } - - /** - * Load a message object for modification, and display the edit template. - * - * @return Symfony\Component\HttpFoundation\Response the response - */ - public function changeAction() - { - // Check current user authorization - if (null !== $response = $this->checkAuth("admin.configuration.messages.update")) return $response; - - // Load the message object - $message = MessageQuery::create() - ->joinWithI18n($this->getCurrentEditionLocale()) - ->findOneById($this->getRequest()->get('message_id')); - - if ($message != null) { - - // Prepare the data that will hydrate the form - $data = array( - 'id' => $message->getId(), - 'name' => $message->getName(), - 'secured' => $message->getSecured(), - 'locale' => $message->getLocale(), - 'title' => $message->getTitle(), - 'subject' => $message->getSubject(), - 'html_message' => $message->getHtmlMessage(), - 'text_message' => $message->getTextMessage() - ); - - // Setup the object form - $changeForm = new MessageModificationForm($this->getRequest(), "form", $data); - - // Pass it to the parser - $this->getParserContext()->addForm($changeForm); - } - - // Render the edition template. + protected function renderEditionTemplate() { return $this->render('message-edit', array('message_id' => $this->getRequest()->get('message_id'))); } - /** - * Save changes on a modified message object, and either go back to the message list, or stay on the edition page. - * - * @return Symfony\Component\HttpFoundation\Response the response - */ - public function saveChangeAction() - { - // Check current user authorization - if (null !== $response = $this->checkAuth("admin.configuration.messages.update")) return $response; - - $message = false; - - // Create the form from the request - $changeForm = new MessageModificationForm($this->getRequest()); - - // Get the message ID - $message_id = $this->getRequest()->get('message_id'); - - try { - - // Check the form against constraints violations - $form = $this->validateForm($changeForm, "POST"); - - // Get the form field values - $data = $form->getData(); - - $changeEvent = new MessageUpdateEvent($data['id']); - - // Create and dispatch the change event - $changeEvent - ->setMessageName($data['name']) - ->setSecured($data['secured']) - ->setLocale($data["locale"]) - ->setTitle($data['title']) - ->setSubject($data['subject']) - ->setHtmlMessage($data['html_message']) - ->setTextMessage($data['text_message']) - ; - - $this->dispatch(TheliaEvents::MESSAGE_UPDATE, $changeEvent); - - if (! $changeEvent->hasMessage()) throw new \LogicException($this->getTranslator()->trans("No message was updated.")); - - $changedObject = $changeEvent->getMessage(); - - $this->adminLogAppend(sprintf("Variable %s (ID %s) modified", $changedObject->getName(), $changedObject->getId())); - - // If we have to stay on the same page, do not redirect to the succesUrl, - // just redirect to the edit page again. - if ($this->getRequest()->get('save_mode') == 'stay') { - $this->redirectToRoute( - "admin.configuration.messages.update", - array('message_id' => $message_id) - ); - } - - // Redirect to the success URL - $this->redirect($changeForm->getSuccessUrl()); - } catch (FormValidationException $ex) { - // Form cannot be validated - $message = $this->createStandardFormValidationErrorMessage($ex); - } catch (\Exception $ex) { - // Any other error - $message = $ex->getMessage(); - } - - $this->setupFormErrorContext("message modification", $message, $changeForm, $ex); - - // At this point, the form has errors, and should be redisplayed. - return $this->render('message-edit', array('message_id' => $message_id)); + protected function redirectToEditionTemplate() { + $this->redirectToRoute( + "admin.configuration.messages.update", + array('message_id' => $this->getRequest()->get('message_id')) + ); } - /** - * Delete a message object - * - * @return Symfony\Component\HttpFoundation\Response the response - */ - public function deleteAction() - { - // Check current user authorization - if (null !== $response = $this->checkAuth("admin.configuration.messages.delete")) return $response; - - // Get the message id, and dispatch the delet request - $event = new MessageDeleteEvent($this->getRequest()->get('message_id')); - - $this->dispatch(TheliaEvents::MESSAGE_DELETE, $event); - - if ($event->hasMessage()) - $this->adminLogAppend(sprintf("Message %s (ID %s) deleted", $event->getMessage()->getName(), $event->getMessage()->getId())); - + protected function redirectToListTemplate() { $this->redirectToRoute('admin.configuration.messages.default'); } } diff --git a/core/lib/Thelia/Core/Event/AttributeCreateEvent.php b/core/lib/Thelia/Core/Event/AttributeCreateEvent.php new file mode 100644 index 000000000..0787b34e3 --- /dev/null +++ b/core/lib/Thelia/Core/Event/AttributeCreateEvent.php @@ -0,0 +1,68 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; + +class AttributeCreateEvent extends AttributeEvent +{ + protected $title; + protected $locale; + protected $add_to_all_templates; + + public function getLocale() + { + return $this->locale; + } + + public function setLocale($locale) + { + $this->locale = $locale; + + return $this; + } + + public function getTitle() + { + return $this->title; + } + + public function setTitle($title) + { + $this->title = $title; + + return $this; + } + + public function getAddToAllTemplates() + { + return $this->add_to_all_templates; + } + + public function setAddToAllTemplates($add_to_all_templates) + { + $this->add_to_all_templates = $add_to_all_templates; + + return $this; + } + +} diff --git a/core/lib/Thelia/Core/Event/CategoryToggleVisibilityEvent.php b/core/lib/Thelia/Core/Event/AttributeDeleteEvent.php similarity index 74% rename from core/lib/Thelia/Core/Event/CategoryToggleVisibilityEvent.php rename to core/lib/Thelia/Core/Event/AttributeDeleteEvent.php index 506904ec8..d7f359f9a 100644 --- a/core/lib/Thelia/Core/Event/CategoryToggleVisibilityEvent.php +++ b/core/lib/Thelia/Core/Event/AttributeDeleteEvent.php @@ -1,7 +1,7 @@ . */ +/* along with this program. If not, see . */ /* */ /*************************************************************************************/ namespace Thelia\Core\Event; -class CategoryToggleVisibilityEvent extends BaseToggleVisibilityEvent +class AttributeDeleteEvent extends AttributeEvent { + protected $attribute_id; + + public function __construct($attribute_id) + { + $this->setAttributeId($attribute_id); + } + + public function getAttributeId() + { + return $this->attribute_id; + } + + public function setAttributeId($attribute_id) + { + $this->attribute_id = $attribute_id; + + return $this; + } } diff --git a/core/lib/Thelia/Core/Event/AttributeEvent.php b/core/lib/Thelia/Core/Event/AttributeEvent.php new file mode 100644 index 000000000..7ce78938c --- /dev/null +++ b/core/lib/Thelia/Core/Event/AttributeEvent.php @@ -0,0 +1,52 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; +use Thelia\Model\Attribute; + +class AttributeEvent extends ActionEvent +{ + protected $attribute = null; + + public function __construct(Attribute $attribute = null) + { + $this->attribute = $attribute; + } + + public function hasAttribute() + { + return ! is_null($this->attribute); + } + + public function getAttribute() + { + return $this->attribute; + } + + public function setAttribute($attribute) + { + $this->attribute = $attribute; + + return $this; + } +} diff --git a/core/lib/Thelia/Core/Event/AttributeUpdateEvent.php b/core/lib/Thelia/Core/Event/AttributeUpdateEvent.php new file mode 100644 index 000000000..a1bf124d9 --- /dev/null +++ b/core/lib/Thelia/Core/Event/AttributeUpdateEvent.php @@ -0,0 +1,86 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; + +class AttributeUpdateEvent extends AttributeCreateEvent +{ + protected $attribute_id; + + protected $description; + protected $chapo; + protected $postscriptum; + + public function __construct($attribute_id) + { + $this->setAttributeId($attribute_id); + } + + public function getAttributeId() + { + return $this->attribute_id; + } + + public function setAttributeId($attribute_id) + { + $this->attribute_id = $attribute_id; + + return $this; + } + + public function getDescription() + { + return $this->description; + } + + public function setDescription($description) + { + $this->description = $description; + + return $this; + } + + public function getChapo() + { + return $this->chapo; + } + + public function setChapo($chapo) + { + $this->chapo = $chapo; + + return $this; + } + + public function getPostscriptum() + { + return $this->postscriptum; + } + + public function setPostscriptum($postscriptum) + { + $this->postscriptum = $postscriptum; + + return $this; + } +} diff --git a/core/lib/Thelia/Core/Event/AttributeValueCreateEvent.php b/core/lib/Thelia/Core/Event/AttributeValueCreateEvent.php new file mode 100644 index 000000000..6f02257b6 --- /dev/null +++ b/core/lib/Thelia/Core/Event/AttributeValueCreateEvent.php @@ -0,0 +1,68 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; + +class AttributeValueCreateEvent extends AttributeValueEvent +{ + protected $title; + protected $locale; + protected $attribute_id; + + public function getLocale() + { + return $this->locale; + } + + public function setLocale($locale) + { + $this->locale = $locale; + + return $this; + } + + public function getTitle() + { + return $this->title; + } + + public function setTitle($title) + { + $this->title = $title; + + return $this; + } + + public function getAttributeId() + { + return $this->attribute_id; + } + + public function setAttributeId($attribute_id) + { + $this->attribute_id = $attribute_id; + + return $this; + } + +} diff --git a/core/lib/Thelia/Core/Event/AttributeValueDeleteEvent.php b/core/lib/Thelia/Core/Event/AttributeValueDeleteEvent.php new file mode 100644 index 000000000..c69218bd1 --- /dev/null +++ b/core/lib/Thelia/Core/Event/AttributeValueDeleteEvent.php @@ -0,0 +1,46 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; + +class AttributeValueDeleteEvent extends AttributeValueEvent +{ + protected $attributeValue_id; + + public function __construct($attributeValue_id) + { + $this->setAttributeValueId($attributeValue_id); + } + + public function getAttributeValueId() + { + return $this->attributeValue_id; + } + + public function setAttributeValueId($attributeValue_id) + { + $this->attributeValue_id = $attributeValue_id; + + return $this; + } +} diff --git a/core/lib/Thelia/Core/Event/AttributeValueEvent.php b/core/lib/Thelia/Core/Event/AttributeValueEvent.php new file mode 100644 index 000000000..5b783ebe9 --- /dev/null +++ b/core/lib/Thelia/Core/Event/AttributeValueEvent.php @@ -0,0 +1,52 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; +use Thelia\Model\AttributeAv; + +class AttributeValueEvent extends ActionEvent +{ + protected $attributeValue = null; + + public function __construct(AttributeAv $attributeValue = null) + { + $this->attributeValue = $attributeValue; + } + + public function hasAttributeValue() + { + return ! is_null($this->attributeValue); + } + + public function getAttributeValue() + { + return $this->attributeValue; + } + + public function setAttributeValue($attributeValue) + { + $this->attributeValue = $attributeValue; + + return $this; + } +} diff --git a/core/lib/Thelia/Core/Event/AttributeValueUpdateEvent.php b/core/lib/Thelia/Core/Event/AttributeValueUpdateEvent.php new file mode 100644 index 000000000..f81082dc5 --- /dev/null +++ b/core/lib/Thelia/Core/Event/AttributeValueUpdateEvent.php @@ -0,0 +1,86 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; + +class AttributeValueUpdateEvent extends AttributeValueCreateEvent +{ + protected $attributeValue_id; + + protected $description; + protected $chapo; + protected $postscriptum; + + public function __construct($attributeValue_id) + { + $this->setAttributeValueId($attributeValue_id); + } + + public function getAttributeValueId() + { + return $this->attributeValue_id; + } + + public function setAttributeValueId($attributeValue_id) + { + $this->attributeValue_id = $attributeValue_id; + + return $this; + } + + public function getDescription() + { + return $this->description; + } + + public function setDescription($description) + { + $this->description = $description; + + return $this; + } + + public function getChapo() + { + return $this->chapo; + } + + public function setChapo($chapo) + { + $this->chapo = $chapo; + + return $this; + } + + public function getPostscriptum() + { + return $this->postscriptum; + } + + public function setPostscriptum($postscriptum) + { + $this->postscriptum = $postscriptum; + + return $this; + } +} diff --git a/core/lib/Thelia/Form/AttributeCreationForm.php b/core/lib/Thelia/Form/AttributeCreationForm.php new file mode 100644 index 000000000..a4c6d402f --- /dev/null +++ b/core/lib/Thelia/Form/AttributeCreationForm.php @@ -0,0 +1,66 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form; + +use Symfony\Component\Validator\Constraints; +use Thelia\Model\CurrencyQuery; +use Symfony\Component\Validator\ExecutionContextInterface; +use Symfony\Component\Validator\Constraints\NotBlank; +use Thelia\Core\Translation\Translator; + +class AttributeCreationForm extends BaseForm +{ + protected function buildForm() + { + $this->formBuilder + ->add("title" , "text" , array( + "constraints" => array( + new NotBlank() + ), + "label" => Translator::getInstance()->trans("Title *"), + "label_attr" => array( + "for" => "title" + )) + ) + ->add("locale" , "text" , array( + "constraints" => array( + new NotBlank() + )) + ) + ->add("add_to_all" , "checkbox" , array( + "constraints" => array( + new NotBlank() + ), + "label" => Translator::getInstance()->trans("Add to all product templates"), + "label_attr" => array( + "for" => "add_to_all" + )) + ) + ; + } + + public function getName() + { + return "thelia_attribute_creation"; + } +} diff --git a/core/lib/Thelia/Form/AttributeModificationForm.php b/core/lib/Thelia/Form/AttributeModificationForm.php new file mode 100644 index 000000000..922ec489b --- /dev/null +++ b/core/lib/Thelia/Form/AttributeModificationForm.php @@ -0,0 +1,56 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form; + +use Symfony\Component\Validator\Constraints; +use Thelia\Model\CurrencyQuery; +use Symfony\Component\Validator\ExecutionContextInterface; +use Symfony\Component\Validator\Constraints\NotBlank; +use Thelia\Core\Translation\Translator; +use Symfony\Component\Validator\Constraints\GreaterThan; + +class AttributeModificationForm extends AttributeCreationForm +{ + use StandardDescriptionFieldsTrait; + + protected function buildForm() + { + $this->formBuilder + ->add("id", "hidden", array( + "constraints" => array( + new GreaterThan( + array('value' => 0) + ) + ) + )) + ; + + // Add standard description fields + $this->addStandardDescFields(); + } + + public function getName() + { + return "thelia_attribute_modification"; + } +} diff --git a/core/lib/Thelia/Form/AttributeValueCreationForm.php b/core/lib/Thelia/Form/AttributeValueCreationForm.php new file mode 100644 index 000000000..dc9de681d --- /dev/null +++ b/core/lib/Thelia/Form/AttributeValueCreationForm.php @@ -0,0 +1,62 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form; + +use Symfony\Component\Validator\Constraints; +use Thelia\Model\CurrencyQuery; +use Symfony\Component\Validator\ExecutionContextInterface; +use Symfony\Component\Validator\Constraints\NotBlank; +use Thelia\Core\Translation\Translator; + +class AttributeValueCreationForm extends BaseForm +{ + protected function buildForm() + { + $this->formBuilder + ->add("title" , "text" , array( + "constraints" => array( + new NotBlank() + ), + "label" => Translator::getInstance()->trans("Title *"), + "label_attr" => array( + "for" => "title" + )) + ) + ->add("locale" , "text" , array( + "constraints" => array( + new NotBlank() + )) + ) + ->add("attribute_id", "hidden", array( + "constraints" => array( + new NotBlank() + )) + ) + ; + } + + public function getName() + { + return "thelia_attribute_value_creation"; + } +} \ No newline at end of file diff --git a/templates/admin/default/attribute-edit.html b/templates/admin/default/attribute-edit.html new file mode 100644 index 000000000..900045fc7 --- /dev/null +++ b/templates/admin/default/attribute-edit.html @@ -0,0 +1,306 @@ +{extends file="admin-layout.tpl"} + +{block name="page-title"}{intl l='Edit an attribute'}{/block} + +{block name="check-permissions"}admin.configuration.attributes.edit{/block} + +{block name="main-content"} +
    + +
    + + {loop name="attribute_edit" type="attribute" id=$attribute_id backend_context="1" lang=$edit_language_id} + + + +
    +
    +
    + +
    + {intl l="Edit attribute $TITLE"} +
    + +
    +
    + + {include file="includes/inner-form-toolbar.html" close_url="{url path='/admin/configuration/attributes'}"} + +
    + +

    {intl l='Attribute information'}

    + + {form name="thelia.admin.attribute.modification"} +
    + + {* Be sure to get the attribute ID, even if the form could not be validated *} + + + {form_hidden_fields form=$form} + + {form_field form=$form field='success_url'} + + {/form_field} + + {form_field form=$form field='locale'} + + {/form_field} + + {if $form_error}
    {$form_error_message}
    {/if} + + {include file="includes/standard-description-form-fields.html"} + +
    + {/form} + +
    + +
    + +

    + + {intl l='Attribute values'} + + {loop type="auth" name="can_create" roles="ADMIN" permissions="admin.configuration.attribute-values.create"} + + + + + + {/loop} +

    + +
    + {intl l="Enter here all possible attribute values. If you don't enter any value, you will be able to set a free value to this attribute on the product form."} +
    + + + + + + + + + + + {module_include location='attributes_value_table_header'} + + + + + + + {loop name="list" type="attribute_availability" attribute=$attribute_id backend_context="1" lang=$edit_language_id order=$order} + + + + + + + + {module_include location='attributes_value_table_row'} + + + + {/loop} + + {elseloop rel="list"} + + + + {/elseloop} + +
    + {admin_sortable_header + current_order=$order + order='id' + reverse_order='id_reverse' + path={url path='/admin/configuration/attributes/update' attribute_id=$attribute_id} + label="{intl l='ID'}" + } + + {admin_sortable_header + current_order=$order + order='alpha' + reverse_order='alpha_reverse' + path={url path='/admin/configuration/attributes/update' attribute_id=$attribute_id} + label="{intl l='Value'}" + } + + {admin_sortable_header + current_order=$order + order='manual' + reverse_order='manual_reverse' + path={url path='/admin/configuration/attributes/update' attribute_id=$attribute_id} + label="{intl l="Position"}" + } + {intl l="Actions"}
    {$ID} + + + {admin_position_block + permission="admin.attributes.edit" + path="/admin/configuration/attributes/update-value-position" + url_parameter="attribute_id" + in_place_edit_class="positionChange" + position="$POSITION" + id="$ID" + } + +
    + +
    +
    +
    + {intl l="No product attribute has been created yet. Click the + button to create one."} +
    +
    +
    +
    +
    +
    +
    + +
    + + {/loop} + + {elseloop rel="attribute_edit"} +
    +
    +
    + {intl l="Sorry, attribute ID=$attribute_id was not found."} +
    +
    +
    + {/elseloop} + +
    +
    + +{* Adding a new attribute *} + +{form name="thelia.admin.attribute-value.creation"} + + {* Capture the dialog body, to pass it to the generic dialog *} + + {capture "creation_dialog"} + {form_hidden_fields form=$form} + + {* Be sure to get the attribute ID, even if the form could not be validated *} + + + {form_field form=$form field='success_url'} + {* on success, redirect to this page *} + + {/form_field} + + {form_field form=$form field='attribute_id'} + + {/form_field} + + {form_field form=$form field='title'} +
    + + + {loop type="lang" name="current-edit-lang" id="$edit_language_id"} +
    + + {intl l=$TITLE} +
    + +
    {intl l="Enter here the value in the current edit language ($TITLE)"}
    + + {form_field form=$form field='locale'} + + {/form_field} + {/loop} +
    + {/form_field} + + {module_include location='attribute_value_create_form'} + + {/capture} + + {include + file = "includes/generic-create-dialog.html" + + dialog_id = "creation_dialog" + dialog_title = {intl l="Create a new attribute value"} + dialog_body = {$smarty.capture.creation_dialog nofilter} + + dialog_ok_label = {intl l="Create this value"} + + form_action = {url path='/admin/configuration/attributes/create-value'} + form_enctype = {form_enctype form=$form} + form_error_message = $form_error_message + } +{/form} + +{* Delete value confirmation dialog *} + +{capture "delete_dialog"} + +{/capture} + +{include + file = "includes/generic-confirm-dialog.html" + + dialog_id = "delete_dialog" + dialog_title = {intl l="Delete attribute value"} + dialog_message = {intl l="Do you really want to delete this attribute value ?"} + + form_action = {url path='/admin/configuration/attributes/delete-value'} + form_content = {$smarty.capture.delete_dialog nofilter} +} + +{/block} + +{block name="javascript-initialization"} + + {javascripts file='assets/js/bootstrap-editable/bootstrap-editable.js'} + + {/javascripts} + + +{/block} \ No newline at end of file diff --git a/templates/admin/default/includes/thelia_news_feed.html b/templates/admin/default/includes/thelia_news_feed.html index 6b957c426..6b9d2b5a9 100755 --- a/templates/admin/default/includes/thelia_news_feed.html +++ b/templates/admin/default/includes/thelia_news_feed.html @@ -3,8 +3,8 @@ {loop type="feed" name="thelia_feeds" url="http://thelia.net/Flux-rss.html?id_rubrique=8" limit="3"}

    {$DATE}

    -

    {$TITLE|strip_tags}

    -

    {$DESCRIPTION|strip_tags|truncate:250:"...":true}

    +

    {$TITLE|strip_tags nofilter}

    +

    {$DESCRIPTION|strip_tags|truncate:250:"...":true nofilter}

    {intl l='Lire la suite »'}

    {/loop} From 83f4e8b356026193fb07fbcc3255f2bc52af2beb Mon Sep 17 00:00:00 2001 From: franck Date: Thu, 12 Sep 2013 14:20:23 +0200 Subject: [PATCH 25/45] Using "update" instead of "change" --- .../{AttributeValue.php => AttributeAv.php} | 50 +++-- core/lib/Thelia/Config/Resources/action.xml | 5 + .../Thelia/Config/Resources/routing/admin.xml | 54 +++-- .../Admin/AbstractCrudController.php | 49 +++-- .../Controller/Admin/AttributeController.php | 4 +- ...teEvent.php => AttributeAvCreateEvent.php} | 2 +- ...teEvent.php => AttributeAvDeleteEvent.php} | 16 +- ...uteValueEvent.php => AttributeAvEvent.php} | 20 +- ...teEvent.php => AttributeAvUpdateEvent.php} | 16 +- core/lib/Thelia/Core/Event/TheliaEvents.php | 20 +- templates/admin/default/attribute-edit.html | 199 +++++++++--------- 11 files changed, 237 insertions(+), 198 deletions(-) rename core/lib/Thelia/Action/{AttributeValue.php => AttributeAv.php} (73%) rename core/lib/Thelia/Core/Event/{AttributeValueCreateEvent.php => AttributeAvCreateEvent.php} (97%) rename core/lib/Thelia/Core/Event/{AttributeValueDeleteEvent.php => AttributeAvDeleteEvent.php} (82%) rename core/lib/Thelia/Core/Event/{AttributeValueEvent.php => AttributeAvEvent.php} (80%) rename core/lib/Thelia/Core/Event/{AttributeValueUpdateEvent.php => AttributeAvUpdateEvent.php} (86%) diff --git a/core/lib/Thelia/Action/AttributeValue.php b/core/lib/Thelia/Action/AttributeAv.php similarity index 73% rename from core/lib/Thelia/Action/AttributeValue.php rename to core/lib/Thelia/Action/AttributeAv.php index 8524f6054..53df7aa72 100644 --- a/core/lib/Thelia/Action/AttributeValue.php +++ b/core/lib/Thelia/Action/AttributeAv.php @@ -25,29 +25,27 @@ namespace Thelia\Action; use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Thelia\Model\AttributeQuery; -use Thelia\Model\Attribute as AttributeModel; +use Thelia\Model\AttributeAvQuery; +use Thelia\Model\AttributeAv as AttributeAvModel; use Thelia\Core\Event\TheliaEvents; -use Thelia\Core\Event\AttributeUpdateEvent; -use Thelia\Core\Event\AttributeCreateEvent; -use Thelia\Core\Event\AttributeDeleteEvent; +use Thelia\Core\Event\AttributeAvUpdateEvent; +use Thelia\Core\Event\AttributeAvCreateEvent; +use Thelia\Core\Event\AttributeAvDeleteEvent; use Thelia\Model\ConfigQuery; -use Thelia\Model\AttributeAv; -use Thelia\Model\AttributeAvQuery; use Thelia\Core\Event\UpdatePositionEvent; -class Attribute extends BaseAction implements EventSubscriberInterface +class AttributeAv extends BaseAction implements EventSubscriberInterface { /** * Create a new attribute entry * - * @param AttributeCreateEvent $event + * @param AttributeAvCreateEvent $event */ - public function create(AttributeCreateEvent $event) + public function create(AttributeAvCreateEvent $event) { - $attribute = new AttributeModel(); + $attribute = new AttributeAvModel(); $attribute ->setDispatcher($this->getDispatcher()) @@ -58,7 +56,7 @@ class Attribute extends BaseAction implements EventSubscriberInterface ->save() ; - $event->setAttribute($attribute); + $event->setAttributeAv($attribute); // Add atribute to all product templates if required if ($event->getAddToAllTemplates() != 0) { @@ -69,13 +67,13 @@ class Attribute extends BaseAction implements EventSubscriberInterface /** * Change a product attribute * - * @param AttributeUpdateEvent $event + * @param AttributeAvUpdateEvent $event */ - public function update(AttributeUpdateEvent $event) + public function update(AttributeAvUpdateEvent $event) { - $search = AttributeQuery::create(); + $search = AttributeAvQuery::create(); - if (null !== $attribute = AttributeQuery::create()->findPk($event->getAttributeId())) { + if (null !== $attribute = AttributeAvQuery::create()->findPk($event->getAttributeAvId())) { $attribute ->setDispatcher($this->getDispatcher()) @@ -88,26 +86,26 @@ class Attribute extends BaseAction implements EventSubscriberInterface ->save(); - $event->setAttribute($attribute); + $event->setAttributeAv($attribute); } } /** * Delete a product attribute entry * - * @param AttributeDeleteEvent $event + * @param AttributeAvDeleteEvent $event */ - public function delete(AttributeDeleteEvent $event) + public function delete(AttributeAvDeleteEvent $event) { - if (null !== ($attribute = AttributeQuery::create()->findPk($event->getAttributeId()))) { + if (null !== ($attribute = AttributeAvQuery::create()->findPk($event->getAttributeAvId()))) { $attribute ->setDispatcher($this->getDispatcher()) ->delete() ; - $event->setAttribute($attribute); + $event->setAttributeAv($attribute); } } @@ -118,7 +116,7 @@ class Attribute extends BaseAction implements EventSubscriberInterface */ public function updatePosition(UpdatePositionEvent $event) { - if (null !== $attribute = AttributeQuery::create()->findPk($event->getObjectId())) { + if (null !== $attribute = AttributeAvQuery::create()->findPk($event->getObjectId())) { $attribute->setDispatcher($this->getDispatcher()); @@ -140,10 +138,10 @@ class Attribute extends BaseAction implements EventSubscriberInterface public static function getSubscribedEvents() { return array( - TheliaEvents::ATTRIBUTE_CREATE => array("create", 128), - TheliaEvents::ATTRIBUTE_UPDATE => array("update", 128), - TheliaEvents::ATTRIBUTE_DELETE => array("delete", 128), - TheliaEvents::ATTRIBUTE_UPDATE_POSITION => array("updatePosition", 128), + TheliaEvents::ATTRIBUTE_AV_CREATE => array("create", 128), + TheliaEvents::ATTRIBUTE_AV_UPDATE => array("update", 128), + TheliaEvents::ATTRIBUTE_AV_DELETE => array("delete", 128), + TheliaEvents::ATTRIBUTE_AV_UPDATE_POSITION => array("updatePosition", 128), ); } } \ No newline at end of file diff --git a/core/lib/Thelia/Config/Resources/action.xml b/core/lib/Thelia/Config/Resources/action.xml index 07e4637ee..842acdc6f 100755 --- a/core/lib/Thelia/Config/Resources/action.xml +++ b/core/lib/Thelia/Config/Resources/action.xml @@ -62,6 +62,11 @@ + + + + + diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index 75d9b0984..69958f115 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -48,7 +48,7 @@ Thelia\Controller\Admin\OrderController::indexAction - + Thelia\Controller\Admin\OrderController::viewAction @@ -68,11 +68,11 @@ - Thelia\Controller\Admin\CategoryController::changeAction + Thelia\Controller\Admin\CategoryController::updateAction - Thelia\Controller\Admin\CategoryController::saveChangeAction + Thelia\Controller\Admin\CategoryController::processUpdateAction @@ -129,11 +129,11 @@ - Thelia\Controller\Admin\ConfigController::changeAction + Thelia\Controller\Admin\ConfigController::updateAction - Thelia\Controller\Admin\ConfigController::saveChangeAction + Thelia\Controller\Admin\ConfigController::processUpdateAction @@ -151,11 +151,11 @@ - Thelia\Controller\Admin\MessageController::changeAction + Thelia\Controller\Admin\MessageController::updateAction - Thelia\Controller\Admin\MessageController::saveChangeAction + Thelia\Controller\Admin\MessageController::processUpdateAction @@ -173,11 +173,11 @@ - Thelia\Controller\Admin\CurrencyController::changeAction + Thelia\Controller\Admin\CurrencyController::updateAction - Thelia\Controller\Admin\CurrencyController::saveChangeAction + Thelia\Controller\Admin\CurrencyController::processUpdateAction @@ -200,7 +200,8 @@ Thelia\Controller\Admin\CurrencyController::updatePositionAction - + + Thelia\Controller\Admin\AttributeController::defaultAction @@ -210,30 +211,43 @@ Thelia\Controller\Admin\AttributeController::createAction - - Thelia\Controller\Admin\AttributeController::createValueAction - - - Thelia\Controller\Admin\AttributeController::changeAction + Thelia\Controller\Admin\AttributeController::updateAction - Thelia\Controller\Admin\AttributeController::saveChangeAction + Thelia\Controller\Admin\AttributeController::processUpdateAction Thelia\Controller\Admin\AttributeController::deleteAction - - Thelia\Controller\Admin\AttributeController::deleteValueAction - - Thelia\Controller\Admin\AttributeController::updatePositionAction + + + Thelia\Controller\Admin\AttributeAvController::createAction + + + + Thelia\Controller\Admin\AttributeAvController::updateAction + + + + Thelia\Controller\Admin\AttributeAvController::processUpdateAction + + + + Thelia\Controller\Admin\AttributeAvController::deleteAction + + + + Thelia\Controller\Admin\AttributeAvController::updatePositionAction + + diff --git a/core/lib/Thelia/Controller/Admin/AbstractCrudController.php b/core/lib/Thelia/Controller/Admin/AbstractCrudController.php index 6d32220b7..1dcbca01f 100644 --- a/core/lib/Thelia/Controller/Admin/AbstractCrudController.php +++ b/core/lib/Thelia/Controller/Admin/AbstractCrudController.php @@ -28,7 +28,7 @@ use Thelia\Core\Event\UpdatePositionEvent; use Thelia\Core\Event\ToggleVisibilityEvent; /** - * Manages currencies sent by mail + * An abstract CRUD controller for Thelia ADMIN, to manage basic CRUD operations on a givent object. * * @author Franck Allimant */ @@ -53,6 +53,23 @@ abstract class AbstractCrudController extends BaseAdminController protected $changePositionEventIdentifier; + /** + * @param string $objectName the lower case object name. Example. "message" + * + * @param string $defaultListOrder the default object list order, or null if list is not sortable. Example: manual + * + * @param string $viewPermissionIdentifier the 'view' permission identifier. Example: "admin.configuration.message.view" + * @param string $createPermissionIdentifier the 'create' permission identifier. Example: "admin.configuration.message.create" + * @param string $updatePermissionIdentifier the 'update' permission identifier. Example: "admin.configuration.message.update" + * @param string $deletePermissionIdentifier the 'delete' permission identifier. Example: "admin.configuration.message.delete" + * + * @param string $createEventIdentifier the dispatched create TheliaEvent identifier. Example: TheliaEvents::MESSAGE_CREATE + * @param string $updateEventIdentifier the dispatched update TheliaEvent identifier. Example: TheliaEvents::MESSAGE_UPDATE + * @param string $deleteEventIdentifier the dispatched delete TheliaEvent identifier. Example: TheliaEvents::MESSAGE_DELETE + * + * @param string $visibilityToggleEventIdentifier the dispatched visibility toggle TheliaEvent identifier, or null if the object has no visible options. Example: TheliaEvents::MESSAGE_TOGGLE_VISIBILITY + * @param string $changePositionEventIdentifier the dispatched position change TheliaEvent identifier, or null if the object has no position. Example: TheliaEvents::MESSAGE_UPDATE_POSITION + */ public function __construct( $objectName, @@ -187,15 +204,14 @@ abstract class AbstractCrudController extends BaseAdminController } /** - * Render the object list, ensuring the sort order is set. - * - * @return Symfony\Component\HttpFoundation\Response the response + * Return the current list order identifier, updating it in the same time. */ - protected function renderList() - { + protected function getCurrentListOrder($update_session = true) { + $order = null; - if ($this->defaultListOrder != null) { + if ($this->defaultListOrder) { + $orderSessionIdentifier = sprintf("admin.%s.currentListOrder", $this->objectName); // Find the current order @@ -204,11 +220,20 @@ abstract class AbstractCrudController extends BaseAdminController $this->getSession()->get($orderSessionIdentifier, $this->defaultListOrder) ); - // Store the current sort order in session - $this->getSession()->set($orderSessionIdentifier, $order); + if ($update_session) $this->getSession()->set($orderSessionIdentifier, $order); } - return $this->renderListTemplate($order); + return $order; + } + + /** + * Render the object list, ensuring the sort order is set. + * + * @return Symfony\Component\HttpFoundation\Response the response + */ + protected function renderList() + { + return $this->renderListTemplate($this->getCurrentListOrder()); } /** @@ -286,7 +311,7 @@ abstract class AbstractCrudController extends BaseAdminController * * @return Symfony\Component\HttpFoundation\Response the response */ - public function changeAction() + public function updateAction() { // Check current user authorization if (null !== $response = $this->checkAuth($this->updatePermissionIdentifier)) return $response; @@ -312,7 +337,7 @@ abstract class AbstractCrudController extends BaseAdminController * * @return Symfony\Component\HttpFoundation\Response the response */ - public function saveChangeAction() + public function processUpdateAction() { // Check current user authorization if (null !== $response = $this->checkAuth($this->updatePermissionIdentifier)) return $response; diff --git a/core/lib/Thelia/Controller/Admin/AttributeController.php b/core/lib/Thelia/Controller/Admin/AttributeController.php index d775c97c6..f6b76c0df 100644 --- a/core/lib/Thelia/Controller/Admin/AttributeController.php +++ b/core/lib/Thelia/Controller/Admin/AttributeController.php @@ -122,7 +122,7 @@ class AttributeController extends AbstractCrudController ); // Setup the object form - $changeForm = new AttributeModificationForm($this->getRequest(), "form", $data); + return new AttributeModificationForm($this->getRequest(), "form", $data); } protected function getObjectFromEvent($event) { @@ -136,7 +136,7 @@ class AttributeController extends AbstractCrudController } protected function getObjectLabel($object) { - return $object->getName(); + return $object->getTitle(); } protected function getObjectId($object) { diff --git a/core/lib/Thelia/Core/Event/AttributeValueCreateEvent.php b/core/lib/Thelia/Core/Event/AttributeAvCreateEvent.php similarity index 97% rename from core/lib/Thelia/Core/Event/AttributeValueCreateEvent.php rename to core/lib/Thelia/Core/Event/AttributeAvCreateEvent.php index 6f02257b6..81d22cfb9 100644 --- a/core/lib/Thelia/Core/Event/AttributeValueCreateEvent.php +++ b/core/lib/Thelia/Core/Event/AttributeAvCreateEvent.php @@ -23,7 +23,7 @@ namespace Thelia\Core\Event; -class AttributeValueCreateEvent extends AttributeValueEvent +class AttributeAvCreateEvent extends AttributeAvEvent { protected $title; protected $locale; diff --git a/core/lib/Thelia/Core/Event/AttributeValueDeleteEvent.php b/core/lib/Thelia/Core/Event/AttributeAvDeleteEvent.php similarity index 82% rename from core/lib/Thelia/Core/Event/AttributeValueDeleteEvent.php rename to core/lib/Thelia/Core/Event/AttributeAvDeleteEvent.php index c69218bd1..d710dc23f 100644 --- a/core/lib/Thelia/Core/Event/AttributeValueDeleteEvent.php +++ b/core/lib/Thelia/Core/Event/AttributeAvDeleteEvent.php @@ -23,23 +23,23 @@ namespace Thelia\Core\Event; -class AttributeValueDeleteEvent extends AttributeValueEvent +class AttributeAvDeleteEvent extends AttributeAvEvent { - protected $attributeValue_id; + protected $attributeAv_id; - public function __construct($attributeValue_id) + public function __construct($attributeAv_id) { - $this->setAttributeValueId($attributeValue_id); + $this->setAttributeAvId($attributeAv_id); } - public function getAttributeValueId() + public function getAttributeAvId() { - return $this->attributeValue_id; + return $this->attributeAv_id; } - public function setAttributeValueId($attributeValue_id) + public function setAttributeAvId($attributeAv_id) { - $this->attributeValue_id = $attributeValue_id; + $this->attributeAv_id = $attributeAv_id; return $this; } diff --git a/core/lib/Thelia/Core/Event/AttributeValueEvent.php b/core/lib/Thelia/Core/Event/AttributeAvEvent.php similarity index 80% rename from core/lib/Thelia/Core/Event/AttributeValueEvent.php rename to core/lib/Thelia/Core/Event/AttributeAvEvent.php index 5b783ebe9..c6c1726bd 100644 --- a/core/lib/Thelia/Core/Event/AttributeValueEvent.php +++ b/core/lib/Thelia/Core/Event/AttributeAvEvent.php @@ -24,28 +24,28 @@ namespace Thelia\Core\Event; use Thelia\Model\AttributeAv; -class AttributeValueEvent extends ActionEvent +class AttributeAvEvent extends ActionEvent { - protected $attributeValue = null; + protected $attributeAv = null; - public function __construct(AttributeAv $attributeValue = null) + public function __construct(AttributeAv $attributeAv = null) { - $this->attributeValue = $attributeValue; + $this->attributeAv = $attributeAv; } - public function hasAttributeValue() + public function hasAttributeAv() { - return ! is_null($this->attributeValue); + return ! is_null($this->attributeAv); } - public function getAttributeValue() + public function getAttributeAv() { - return $this->attributeValue; + return $this->attributeAv; } - public function setAttributeValue($attributeValue) + public function setAttributeAv($attributeAv) { - $this->attributeValue = $attributeValue; + $this->attributeAv = $attributeAv; return $this; } diff --git a/core/lib/Thelia/Core/Event/AttributeValueUpdateEvent.php b/core/lib/Thelia/Core/Event/AttributeAvUpdateEvent.php similarity index 86% rename from core/lib/Thelia/Core/Event/AttributeValueUpdateEvent.php rename to core/lib/Thelia/Core/Event/AttributeAvUpdateEvent.php index f81082dc5..c76198954 100644 --- a/core/lib/Thelia/Core/Event/AttributeValueUpdateEvent.php +++ b/core/lib/Thelia/Core/Event/AttributeAvUpdateEvent.php @@ -23,27 +23,27 @@ namespace Thelia\Core\Event; -class AttributeValueUpdateEvent extends AttributeValueCreateEvent +class AttributeAvUpdateEvent extends AttributeAvCreateEvent { - protected $attributeValue_id; + protected $attributeAv_id; protected $description; protected $chapo; protected $postscriptum; - public function __construct($attributeValue_id) + public function __construct($attributeAv_id) { - $this->setAttributeValueId($attributeValue_id); + $this->setAttributeAvId($attributeAv_id); } - public function getAttributeValueId() + public function getAttributeAvId() { - return $this->attributeValue_id; + return $this->attributeAv_id; } - public function setAttributeValueId($attributeValue_id) + public function setAttributeAvId($attributeAv_id) { - $this->attributeValue_id = $attributeValue_id; + $this->attributeAv_id = $attributeAv_id; return $this; } diff --git a/core/lib/Thelia/Core/Event/TheliaEvents.php b/core/lib/Thelia/Core/Event/TheliaEvents.php index 507b32bb8..178226188 100755 --- a/core/lib/Thelia/Core/Event/TheliaEvents.php +++ b/core/lib/Thelia/Core/Event/TheliaEvents.php @@ -365,17 +365,17 @@ final class TheliaEvents // -- Attributes values management ---------------------------------------- - const ATTRIBUTE_VALUE_CREATE = "action.createAttributeValue"; - const ATTRIBUTE_VALUE_UPDATE = "action.updateAttributeValue"; - const ATTRIBUTE_VALUE_DELETE = "action.deleteAttributeValue"; - const ATTRIBUTE_VALUE_UPDATE_POSITION = "action.updateAttributeValuePosition"; + const ATTRIBUTE_AV_CREATE = "action.createAttributeAv"; + const ATTRIBUTE_AV_UPDATE = "action.updateAttributeAv"; + const ATTRIBUTE_AV_DELETE = "action.deleteAttributeAv"; + const ATTRIBUTE_AV_UPDATE_POSITION = "action.updateAttributeAvPosition"; - const BEFORE_CREATEATTRIBUTE_VALUE = "action.before_createAttributeValue"; - const AFTER_CREATEATTRIBUTE_VALUE = "action.after_createAttributeValue"; + const BEFORE_CREATEATTRIBUTE_AV = "action.before_createAttributeAv"; + const AFTER_CREATEATTRIBUTE_AV = "action.after_createAttributeAv"; - const BEFORE_UPDATEATTRIBUTE_VALUE = "action.before_updateAttributeValue"; - const AFTER_UPDATEATTRIBUTE_VALUE = "action.after_updateAttributeValue"; + const BEFORE_UPDATEATTRIBUTE_AV = "action.before_updateAttributeAv"; + const AFTER_UPDATEATTRIBUTE_AV = "action.after_updateAttributeAv"; - const BEFORE_DELETEATTRIBUTE_VALUE = "action.before_deleteAttributeValue"; - const AFTER_DELETEATTRIBUTE_VALUE = "action.after_deleteAttributeValue"; + const BEFORE_DELETEATTRIBUTE_AV = "action.before_deleteAttributeAv"; + const AFTER_DELETEATTRIBUTE_AV = "action.after_deleteAttributeAv"; } diff --git a/templates/admin/default/attribute-edit.html b/templates/admin/default/attribute-edit.html index 900045fc7..58933cc9a 100644 --- a/templates/admin/default/attribute-edit.html +++ b/templates/admin/default/attribute-edit.html @@ -27,16 +27,15 @@
    -
    +
    + {form name="thelia.admin.attribute.modification"} +
    - {include file="includes/inner-form-toolbar.html" close_url="{url path='/admin/configuration/attributes'}"} + {include file="includes/inner-form-toolbar.html" close_url="{url path='/admin/configuration/attributes'}"} -
    +
    -

    {intl l='Attribute information'}

    - - {form name="thelia.admin.attribute.modification"} - +

    {intl l='Attribute information'}

    {* Be sure to get the attribute ID, even if the form could not be validated *} @@ -53,114 +52,112 @@ {if $form_error}
    {$form_error_message}
    {/if} - {include file="includes/standard-description-form-fields.html"} + {include file="includes/standard-description-form-fields.html"} +
    - - {/form} +
    -
    +

    -

    + {intl l='Attribute values'} -

    + {loop type="auth" name="can_create" roles="ADMIN" permissions="admin.configuration.attribute-values.create"} + + + + + + {/loop} +

    - {intl l='Attribute values'} +
    + {intl l="Enter here all possible attribute values."} +
    - {loop type="auth" name="can_create" roles="ADMIN" permissions="admin.configuration.attribute-values.create"} - - - - - - {/loop} -

    + + + + -
    - {intl l="Enter here all possible attribute values. If you don't enter any value, you will be able to set a free value to this attribute on the product form."} -
    + -
    + {admin_sortable_header + current_order=$order + order='id' + reverse_order='id_reverse' + path={url path='/admin/configuration/attributes/update' attribute_id=$attribute_id} + label="{intl l='ID'}" + } + + {admin_sortable_header + current_order=$order + order='alpha' + reverse_order='alpha_reverse' + path={url path='/admin/configuration/attributes/update' attribute_id=$attribute_id} + label="{intl l='Value'}" + } +
    - - - + - + {module_include location='attributes_value_table_header'} - + + + - {module_include location='attributes_value_table_header'} + + {loop name="list" type="attribute_availability" attribute=$attribute_id backend_context="1" lang=$edit_language_id order=$order} + + - - - + - - {loop name="list" type="attribute_availability" attribute=$attribute_id backend_context="1" lang=$edit_language_id order=$order} - - + - + {module_include location='attributes_value_table_row'} - + + + {/loop} - {module_include location='attributes_value_table_row'} - - - - {/loop} - - {elseloop rel="list"} - - - - {/elseloop} - -
    - {admin_sortable_header - current_order=$order - order='id' - reverse_order='id_reverse' - path={url path='/admin/configuration/attributes/update' attribute_id=$attribute_id} - label="{intl l='ID'}" - } - + {admin_sortable_header + current_order=$order + order='manual' + reverse_order='manual_reverse' + path={url path='/admin/configuration/attributes/update' attribute_id=$attribute_id} + label="{intl l="Position"}" + } + - {admin_sortable_header - current_order=$order - order='alpha' - reverse_order='alpha_reverse' - path={url path='/admin/configuration/attributes/update' attribute_id=$attribute_id} - label="{intl l='Value'}" - } - - {admin_sortable_header - current_order=$order - order='manual' - reverse_order='manual_reverse' - path={url path='/admin/configuration/attributes/update' attribute_id=$attribute_id} - label="{intl l="Position"}" - } - {intl l="Actions"}
    {$ID}{intl l="Actions"}
    + +
    {$ID} + {admin_position_block + permission="admin.attributes.edit" + path="/admin/configuration/attributes/update-value-position" + url_parameter="attribute_id" + in_place_edit_class="positionChange" + position="$POSITION" + id="$ID" + } + - - - {admin_position_block - permission="admin.attributes.edit" - path="/admin/configuration/attributes/update-value-position" - url_parameter="attribute_id" - in_place_edit_class="positionChange" - position="$POSITION" - id="$ID" - } - +
    + +
    +
    -
    - -
    -
    -
    - {intl l="No product attribute has been created yet. Click the + button to create one."} -
    -
    -
    -
    + {elseloop rel="list"} + + +
    + {intl l="No product attribute has been created yet. Click the + button to create one."} +
    + + + {/elseloop} + + +
    + + {/form} +
    @@ -235,7 +232,7 @@ dialog_ok_label = {intl l="Create this value"} - form_action = {url path='/admin/configuration/attributes/create-value'} + form_action = {url path='/admin/configuration/attributes-av'} form_enctype = {form_enctype form=$form} form_error_message = $form_error_message } @@ -254,7 +251,7 @@ dialog_title = {intl l="Delete attribute value"} dialog_message = {intl l="Do you really want to delete this attribute value ?"} - form_action = {url path='/admin/configuration/attributes/delete-value'} + form_action = {url path='/admin/configuration/attributes-av/delete'} form_content = {$smarty.capture.delete_dialog nofilter} } From c9e455e3ea5790f14889c2173aa47487059b74cf Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Thu, 12 Sep 2013 15:40:49 +0200 Subject: [PATCH 26/45] update cart model --- core/lib/Thelia/Model/Base/Cart.php | 95 +++++++++++++++++-- core/lib/Thelia/Model/Base/CartItem.php | 82 ++++++++++++++-- core/lib/Thelia/Model/Base/CartItemQuery.php | 47 ++++++++- core/lib/Thelia/Model/Base/CartQuery.php | 47 ++++++++- .../lib/Thelia/Model/Map/CartItemTableMap.php | 36 ++++--- core/lib/Thelia/Model/Map/CartTableMap.php | 36 ++++--- install/thelia.sql | 2 + local/config/schema.xml | 2 + 8 files changed, 299 insertions(+), 48 deletions(-) diff --git a/core/lib/Thelia/Model/Base/Cart.php b/core/lib/Thelia/Model/Base/Cart.php index 20a2d9a5c..2ef18297c 100644 --- a/core/lib/Thelia/Model/Base/Cart.php +++ b/core/lib/Thelia/Model/Base/Cart.php @@ -99,6 +99,13 @@ abstract class Cart implements ActiveRecordInterface */ protected $currency_id; + /** + * The value for the discount field. + * Note: this column has a database default value of: 0 + * @var double + */ + protected $discount; + /** * The value for the created_at field. * @var string @@ -151,11 +158,24 @@ abstract class Cart implements ActiveRecordInterface */ protected $cartItemsScheduledForDeletion = null; + /** + * Applies default values to this object. + * This method should be called from the object's constructor (or + * equivalent initialization method). + * @see __construct() + */ + public function applyDefaultValues() + { + $this->discount = 0; + } + /** * Initializes internal state of Thelia\Model\Base\Cart object. + * @see applyDefaults() */ public function __construct() { + $this->applyDefaultValues(); } /** @@ -471,6 +491,17 @@ abstract class Cart implements ActiveRecordInterface return $this->currency_id; } + /** + * Get the [discount] column value. + * + * @return double + */ + public function getDiscount() + { + + return $this->discount; + } + /** * Get the [optionally formatted] temporal [created_at] column value. * @@ -653,6 +684,27 @@ abstract class Cart implements ActiveRecordInterface return $this; } // setCurrencyId() + /** + * Set the value of [discount] column. + * + * @param double $v new value + * @return \Thelia\Model\Cart The current object (for fluent API support) + */ + public function setDiscount($v) + { + if ($v !== null) { + $v = (double) $v; + } + + if ($this->discount !== $v) { + $this->discount = $v; + $this->modifiedColumns[] = CartTableMap::DISCOUNT; + } + + + return $this; + } // setDiscount() + /** * Sets the value of [created_at] column to a normalized version of the date/time value specified. * @@ -705,6 +757,10 @@ abstract class Cart implements ActiveRecordInterface */ public function hasOnlyDefaultValues() { + if ($this->discount !== 0) { + return false; + } + // otherwise, everything was equal, so return TRUE return true; } // hasOnlyDefaultValues() @@ -750,13 +806,16 @@ abstract class Cart implements ActiveRecordInterface $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : CartTableMap::translateFieldName('CurrencyId', TableMap::TYPE_PHPNAME, $indexType)]; $this->currency_id = (null !== $col) ? (int) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : CartTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : CartTableMap::translateFieldName('Discount', TableMap::TYPE_PHPNAME, $indexType)]; + $this->discount = (null !== $col) ? (double) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : CartTableMap::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 ? 7 + $startcol : CartTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 8 + $startcol : CartTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } @@ -769,7 +828,7 @@ abstract class Cart implements ActiveRecordInterface $this->ensureConsistency(); } - return $startcol + 8; // 8 = CartTableMap::NUM_HYDRATE_COLUMNS. + return $startcol + 9; // 9 = CartTableMap::NUM_HYDRATE_COLUMNS. } catch (Exception $e) { throw new PropelException("Error populating \Thelia\Model\Cart object", 0, $e); @@ -1075,6 +1134,9 @@ abstract class Cart implements ActiveRecordInterface if ($this->isColumnModified(CartTableMap::CURRENCY_ID)) { $modifiedColumns[':p' . $index++] = 'CURRENCY_ID'; } + if ($this->isColumnModified(CartTableMap::DISCOUNT)) { + $modifiedColumns[':p' . $index++] = 'DISCOUNT'; + } if ($this->isColumnModified(CartTableMap::CREATED_AT)) { $modifiedColumns[':p' . $index++] = 'CREATED_AT'; } @@ -1110,6 +1172,9 @@ abstract class Cart implements ActiveRecordInterface case 'CURRENCY_ID': $stmt->bindValue($identifier, $this->currency_id, PDO::PARAM_INT); break; + case 'DISCOUNT': + $stmt->bindValue($identifier, $this->discount, 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; @@ -1197,9 +1262,12 @@ abstract class Cart implements ActiveRecordInterface return $this->getCurrencyId(); break; case 6: - return $this->getCreatedAt(); + return $this->getDiscount(); break; case 7: + return $this->getCreatedAt(); + break; + case 8: return $this->getUpdatedAt(); break; default: @@ -1237,8 +1305,9 @@ abstract class Cart implements ActiveRecordInterface $keys[3] => $this->getAddressDeliveryId(), $keys[4] => $this->getAddressInvoiceId(), $keys[5] => $this->getCurrencyId(), - $keys[6] => $this->getCreatedAt(), - $keys[7] => $this->getUpdatedAt(), + $keys[6] => $this->getDiscount(), + $keys[7] => $this->getCreatedAt(), + $keys[8] => $this->getUpdatedAt(), ); $virtualColumns = $this->virtualColumns; foreach($virtualColumns as $key => $virtualColumn) @@ -1315,9 +1384,12 @@ abstract class Cart implements ActiveRecordInterface $this->setCurrencyId($value); break; case 6: - $this->setCreatedAt($value); + $this->setDiscount($value); break; case 7: + $this->setCreatedAt($value); + break; + case 8: $this->setUpdatedAt($value); break; } // switch() @@ -1350,8 +1422,9 @@ abstract class Cart implements ActiveRecordInterface if (array_key_exists($keys[3], $arr)) $this->setAddressDeliveryId($arr[$keys[3]]); if (array_key_exists($keys[4], $arr)) $this->setAddressInvoiceId($arr[$keys[4]]); if (array_key_exists($keys[5], $arr)) $this->setCurrencyId($arr[$keys[5]]); - if (array_key_exists($keys[6], $arr)) $this->setCreatedAt($arr[$keys[6]]); - if (array_key_exists($keys[7], $arr)) $this->setUpdatedAt($arr[$keys[7]]); + if (array_key_exists($keys[6], $arr)) $this->setDiscount($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setCreatedAt($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setUpdatedAt($arr[$keys[8]]); } /** @@ -1369,6 +1442,7 @@ abstract class Cart implements ActiveRecordInterface if ($this->isColumnModified(CartTableMap::ADDRESS_DELIVERY_ID)) $criteria->add(CartTableMap::ADDRESS_DELIVERY_ID, $this->address_delivery_id); if ($this->isColumnModified(CartTableMap::ADDRESS_INVOICE_ID)) $criteria->add(CartTableMap::ADDRESS_INVOICE_ID, $this->address_invoice_id); if ($this->isColumnModified(CartTableMap::CURRENCY_ID)) $criteria->add(CartTableMap::CURRENCY_ID, $this->currency_id); + if ($this->isColumnModified(CartTableMap::DISCOUNT)) $criteria->add(CartTableMap::DISCOUNT, $this->discount); if ($this->isColumnModified(CartTableMap::CREATED_AT)) $criteria->add(CartTableMap::CREATED_AT, $this->created_at); if ($this->isColumnModified(CartTableMap::UPDATED_AT)) $criteria->add(CartTableMap::UPDATED_AT, $this->updated_at); @@ -1439,6 +1513,7 @@ abstract class Cart implements ActiveRecordInterface $copyObj->setAddressDeliveryId($this->getAddressDeliveryId()); $copyObj->setAddressInvoiceId($this->getAddressInvoiceId()); $copyObj->setCurrencyId($this->getCurrencyId()); + $copyObj->setDiscount($this->getDiscount()); $copyObj->setCreatedAt($this->getCreatedAt()); $copyObj->setUpdatedAt($this->getUpdatedAt()); @@ -1982,10 +2057,12 @@ abstract class Cart implements ActiveRecordInterface $this->address_delivery_id = null; $this->address_invoice_id = null; $this->currency_id = null; + $this->discount = null; $this->created_at = null; $this->updated_at = null; $this->alreadyInSave = false; $this->clearAllReferences(); + $this->applyDefaultValues(); $this->resetModified(); $this->setNew(true); $this->setDeleted(false); diff --git a/core/lib/Thelia/Model/Base/CartItem.php b/core/lib/Thelia/Model/Base/CartItem.php index 827a4c5ec..5dd573d39 100644 --- a/core/lib/Thelia/Model/Base/CartItem.php +++ b/core/lib/Thelia/Model/Base/CartItem.php @@ -109,6 +109,13 @@ abstract class CartItem implements ActiveRecordInterface */ protected $price_end_of_life; + /** + * The value for the discount field. + * Note: this column has a database default value of: 0 + * @var double + */ + protected $discount; + /** * The value for the created_at field. * @var string @@ -153,6 +160,7 @@ abstract class CartItem implements ActiveRecordInterface public function applyDefaultValues() { $this->quantity = 1; + $this->discount = 0; } /** @@ -508,6 +516,17 @@ abstract class CartItem implements ActiveRecordInterface } } + /** + * Get the [discount] column value. + * + * @return double + */ + public function getDiscount() + { + + return $this->discount; + } + /** * Get the [optionally formatted] temporal [created_at] column value. * @@ -728,6 +747,27 @@ abstract class CartItem implements ActiveRecordInterface return $this; } // setPriceEndOfLife() + /** + * Set the value of [discount] column. + * + * @param double $v new value + * @return \Thelia\Model\CartItem The current object (for fluent API support) + */ + public function setDiscount($v) + { + if ($v !== null) { + $v = (double) $v; + } + + if ($this->discount !== $v) { + $this->discount = $v; + $this->modifiedColumns[] = CartItemTableMap::DISCOUNT; + } + + + return $this; + } // setDiscount() + /** * Sets the value of [created_at] column to a normalized version of the date/time value specified. * @@ -784,6 +824,10 @@ abstract class CartItem implements ActiveRecordInterface return false; } + if ($this->discount !== 0) { + return false; + } + // otherwise, everything was equal, so return TRUE return true; } // hasOnlyDefaultValues() @@ -838,13 +882,16 @@ abstract class CartItem implements ActiveRecordInterface } $this->price_end_of_life = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 8 + $startcol : CartItemTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 8 + $startcol : CartItemTableMap::translateFieldName('Discount', TableMap::TYPE_PHPNAME, $indexType)]; + $this->discount = (null !== $col) ? (double) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 9 + $startcol : CartItemTableMap::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 ? 9 + $startcol : CartItemTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 10 + $startcol : CartItemTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } @@ -857,7 +904,7 @@ abstract class CartItem implements ActiveRecordInterface $this->ensureConsistency(); } - return $startcol + 10; // 10 = CartItemTableMap::NUM_HYDRATE_COLUMNS. + return $startcol + 11; // 11 = CartItemTableMap::NUM_HYDRATE_COLUMNS. } catch (Exception $e) { throw new PropelException("Error populating \Thelia\Model\CartItem object", 0, $e); @@ -1139,6 +1186,9 @@ abstract class CartItem implements ActiveRecordInterface if ($this->isColumnModified(CartItemTableMap::PRICE_END_OF_LIFE)) { $modifiedColumns[':p' . $index++] = 'PRICE_END_OF_LIFE'; } + if ($this->isColumnModified(CartItemTableMap::DISCOUNT)) { + $modifiedColumns[':p' . $index++] = 'DISCOUNT'; + } if ($this->isColumnModified(CartItemTableMap::CREATED_AT)) { $modifiedColumns[':p' . $index++] = 'CREATED_AT'; } @@ -1180,6 +1230,9 @@ abstract class CartItem implements ActiveRecordInterface case 'PRICE_END_OF_LIFE': $stmt->bindValue($identifier, $this->price_end_of_life ? $this->price_end_of_life->format("Y-m-d H:i:s") : null, PDO::PARAM_STR); break; + case 'DISCOUNT': + $stmt->bindValue($identifier, $this->discount, 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; @@ -1273,9 +1326,12 @@ abstract class CartItem implements ActiveRecordInterface return $this->getPriceEndOfLife(); break; case 8: - return $this->getCreatedAt(); + return $this->getDiscount(); break; case 9: + return $this->getCreatedAt(); + break; + case 10: return $this->getUpdatedAt(); break; default: @@ -1315,8 +1371,9 @@ abstract class CartItem implements ActiveRecordInterface $keys[5] => $this->getPrice(), $keys[6] => $this->getPromoPrice(), $keys[7] => $this->getPriceEndOfLife(), - $keys[8] => $this->getCreatedAt(), - $keys[9] => $this->getUpdatedAt(), + $keys[8] => $this->getDiscount(), + $keys[9] => $this->getCreatedAt(), + $keys[10] => $this->getUpdatedAt(), ); $virtualColumns = $this->virtualColumns; foreach($virtualColumns as $key => $virtualColumn) @@ -1393,9 +1450,12 @@ abstract class CartItem implements ActiveRecordInterface $this->setPriceEndOfLife($value); break; case 8: - $this->setCreatedAt($value); + $this->setDiscount($value); break; case 9: + $this->setCreatedAt($value); + break; + case 10: $this->setUpdatedAt($value); break; } // switch() @@ -1430,8 +1490,9 @@ abstract class CartItem implements ActiveRecordInterface if (array_key_exists($keys[5], $arr)) $this->setPrice($arr[$keys[5]]); if (array_key_exists($keys[6], $arr)) $this->setPromoPrice($arr[$keys[6]]); if (array_key_exists($keys[7], $arr)) $this->setPriceEndOfLife($arr[$keys[7]]); - if (array_key_exists($keys[8], $arr)) $this->setCreatedAt($arr[$keys[8]]); - if (array_key_exists($keys[9], $arr)) $this->setUpdatedAt($arr[$keys[9]]); + if (array_key_exists($keys[8], $arr)) $this->setDiscount($arr[$keys[8]]); + if (array_key_exists($keys[9], $arr)) $this->setCreatedAt($arr[$keys[9]]); + if (array_key_exists($keys[10], $arr)) $this->setUpdatedAt($arr[$keys[10]]); } /** @@ -1451,6 +1512,7 @@ abstract class CartItem implements ActiveRecordInterface if ($this->isColumnModified(CartItemTableMap::PRICE)) $criteria->add(CartItemTableMap::PRICE, $this->price); if ($this->isColumnModified(CartItemTableMap::PROMO_PRICE)) $criteria->add(CartItemTableMap::PROMO_PRICE, $this->promo_price); if ($this->isColumnModified(CartItemTableMap::PRICE_END_OF_LIFE)) $criteria->add(CartItemTableMap::PRICE_END_OF_LIFE, $this->price_end_of_life); + if ($this->isColumnModified(CartItemTableMap::DISCOUNT)) $criteria->add(CartItemTableMap::DISCOUNT, $this->discount); if ($this->isColumnModified(CartItemTableMap::CREATED_AT)) $criteria->add(CartItemTableMap::CREATED_AT, $this->created_at); if ($this->isColumnModified(CartItemTableMap::UPDATED_AT)) $criteria->add(CartItemTableMap::UPDATED_AT, $this->updated_at); @@ -1523,6 +1585,7 @@ abstract class CartItem implements ActiveRecordInterface $copyObj->setPrice($this->getPrice()); $copyObj->setPromoPrice($this->getPromoPrice()); $copyObj->setPriceEndOfLife($this->getPriceEndOfLife()); + $copyObj->setDiscount($this->getDiscount()); $copyObj->setCreatedAt($this->getCreatedAt()); $copyObj->setUpdatedAt($this->getUpdatedAt()); if ($makeNew) { @@ -1719,6 +1782,7 @@ abstract class CartItem implements ActiveRecordInterface $this->price = null; $this->promo_price = null; $this->price_end_of_life = null; + $this->discount = null; $this->created_at = null; $this->updated_at = null; $this->alreadyInSave = false; diff --git a/core/lib/Thelia/Model/Base/CartItemQuery.php b/core/lib/Thelia/Model/Base/CartItemQuery.php index d26ceb965..83705aeac 100644 --- a/core/lib/Thelia/Model/Base/CartItemQuery.php +++ b/core/lib/Thelia/Model/Base/CartItemQuery.php @@ -29,6 +29,7 @@ use Thelia\Model\Map\CartItemTableMap; * @method ChildCartItemQuery orderByPrice($order = Criteria::ASC) Order by the price column * @method ChildCartItemQuery orderByPromoPrice($order = Criteria::ASC) Order by the promo_price column * @method ChildCartItemQuery orderByPriceEndOfLife($order = Criteria::ASC) Order by the price_end_of_life column + * @method ChildCartItemQuery orderByDiscount($order = Criteria::ASC) Order by the discount column * @method ChildCartItemQuery orderByCreatedAt($order = Criteria::ASC) Order by the created_at column * @method ChildCartItemQuery orderByUpdatedAt($order = Criteria::ASC) Order by the updated_at column * @@ -40,6 +41,7 @@ use Thelia\Model\Map\CartItemTableMap; * @method ChildCartItemQuery groupByPrice() Group by the price column * @method ChildCartItemQuery groupByPromoPrice() Group by the promo_price column * @method ChildCartItemQuery groupByPriceEndOfLife() Group by the price_end_of_life column + * @method ChildCartItemQuery groupByDiscount() Group by the discount column * @method ChildCartItemQuery groupByCreatedAt() Group by the created_at column * @method ChildCartItemQuery groupByUpdatedAt() Group by the updated_at column * @@ -70,6 +72,7 @@ use Thelia\Model\Map\CartItemTableMap; * @method ChildCartItem findOneByPrice(double $price) Return the first ChildCartItem filtered by the price column * @method ChildCartItem findOneByPromoPrice(double $promo_price) Return the first ChildCartItem filtered by the promo_price column * @method ChildCartItem findOneByPriceEndOfLife(string $price_end_of_life) Return the first ChildCartItem filtered by the price_end_of_life column + * @method ChildCartItem findOneByDiscount(double $discount) Return the first ChildCartItem filtered by the discount column * @method ChildCartItem findOneByCreatedAt(string $created_at) Return the first ChildCartItem filtered by the created_at column * @method ChildCartItem findOneByUpdatedAt(string $updated_at) Return the first ChildCartItem filtered by the updated_at column * @@ -81,6 +84,7 @@ use Thelia\Model\Map\CartItemTableMap; * @method array findByPrice(double $price) Return ChildCartItem objects filtered by the price column * @method array findByPromoPrice(double $promo_price) Return ChildCartItem objects filtered by the promo_price column * @method array findByPriceEndOfLife(string $price_end_of_life) Return ChildCartItem objects filtered by the price_end_of_life column + * @method array findByDiscount(double $discount) Return ChildCartItem objects filtered by the discount column * @method array findByCreatedAt(string $created_at) Return ChildCartItem objects filtered by the created_at column * @method array findByUpdatedAt(string $updated_at) Return ChildCartItem objects filtered by the updated_at column * @@ -171,7 +175,7 @@ abstract class CartItemQuery extends ModelCriteria */ protected function findPkSimple($key, $con) { - $sql = 'SELECT ID, CART_ID, PRODUCT_ID, QUANTITY, PRODUCT_SALE_ELEMENTS_ID, PRICE, PROMO_PRICE, PRICE_END_OF_LIFE, CREATED_AT, UPDATED_AT FROM cart_item WHERE ID = :p0'; + $sql = 'SELECT ID, CART_ID, PRODUCT_ID, QUANTITY, PRODUCT_SALE_ELEMENTS_ID, PRICE, PROMO_PRICE, PRICE_END_OF_LIFE, DISCOUNT, CREATED_AT, UPDATED_AT FROM cart_item WHERE ID = :p0'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key, PDO::PARAM_INT); @@ -596,6 +600,47 @@ abstract class CartItemQuery extends ModelCriteria return $this->addUsingAlias(CartItemTableMap::PRICE_END_OF_LIFE, $priceEndOfLife, $comparison); } + /** + * Filter the query on the discount column + * + * Example usage: + * + * $query->filterByDiscount(1234); // WHERE discount = 1234 + * $query->filterByDiscount(array(12, 34)); // WHERE discount IN (12, 34) + * $query->filterByDiscount(array('min' => 12)); // WHERE discount > 12 + * + * + * @param mixed $discount The value to use as filter. + * 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 ChildCartItemQuery The current query, for fluid interface + */ + public function filterByDiscount($discount = null, $comparison = null) + { + if (is_array($discount)) { + $useMinMax = false; + if (isset($discount['min'])) { + $this->addUsingAlias(CartItemTableMap::DISCOUNT, $discount['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($discount['max'])) { + $this->addUsingAlias(CartItemTableMap::DISCOUNT, $discount['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(CartItemTableMap::DISCOUNT, $discount, $comparison); + } + /** * Filter the query on the created_at column * diff --git a/core/lib/Thelia/Model/Base/CartQuery.php b/core/lib/Thelia/Model/Base/CartQuery.php index 24473bd5a..2628aa893 100644 --- a/core/lib/Thelia/Model/Base/CartQuery.php +++ b/core/lib/Thelia/Model/Base/CartQuery.php @@ -27,6 +27,7 @@ use Thelia\Model\Map\CartTableMap; * @method ChildCartQuery orderByAddressDeliveryId($order = Criteria::ASC) Order by the address_delivery_id column * @method ChildCartQuery orderByAddressInvoiceId($order = Criteria::ASC) Order by the address_invoice_id column * @method ChildCartQuery orderByCurrencyId($order = Criteria::ASC) Order by the currency_id column + * @method ChildCartQuery orderByDiscount($order = Criteria::ASC) Order by the discount column * @method ChildCartQuery orderByCreatedAt($order = Criteria::ASC) Order by the created_at column * @method ChildCartQuery orderByUpdatedAt($order = Criteria::ASC) Order by the updated_at column * @@ -36,6 +37,7 @@ use Thelia\Model\Map\CartTableMap; * @method ChildCartQuery groupByAddressDeliveryId() Group by the address_delivery_id column * @method ChildCartQuery groupByAddressInvoiceId() Group by the address_invoice_id column * @method ChildCartQuery groupByCurrencyId() Group by the currency_id column + * @method ChildCartQuery groupByDiscount() Group by the discount column * @method ChildCartQuery groupByCreatedAt() Group by the created_at column * @method ChildCartQuery groupByUpdatedAt() Group by the updated_at column * @@ -72,6 +74,7 @@ use Thelia\Model\Map\CartTableMap; * @method ChildCart findOneByAddressDeliveryId(int $address_delivery_id) Return the first ChildCart filtered by the address_delivery_id column * @method ChildCart findOneByAddressInvoiceId(int $address_invoice_id) Return the first ChildCart filtered by the address_invoice_id column * @method ChildCart findOneByCurrencyId(int $currency_id) Return the first ChildCart filtered by the currency_id column + * @method ChildCart findOneByDiscount(double $discount) Return the first ChildCart filtered by the discount column * @method ChildCart findOneByCreatedAt(string $created_at) Return the first ChildCart filtered by the created_at column * @method ChildCart findOneByUpdatedAt(string $updated_at) Return the first ChildCart filtered by the updated_at column * @@ -81,6 +84,7 @@ use Thelia\Model\Map\CartTableMap; * @method array findByAddressDeliveryId(int $address_delivery_id) Return ChildCart objects filtered by the address_delivery_id column * @method array findByAddressInvoiceId(int $address_invoice_id) Return ChildCart objects filtered by the address_invoice_id column * @method array findByCurrencyId(int $currency_id) Return ChildCart objects filtered by the currency_id column + * @method array findByDiscount(double $discount) Return ChildCart objects filtered by the discount column * @method array findByCreatedAt(string $created_at) Return ChildCart objects filtered by the created_at column * @method array findByUpdatedAt(string $updated_at) Return ChildCart objects filtered by the updated_at column * @@ -171,7 +175,7 @@ abstract class CartQuery extends ModelCriteria */ protected function findPkSimple($key, $con) { - $sql = 'SELECT ID, TOKEN, CUSTOMER_ID, ADDRESS_DELIVERY_ID, ADDRESS_INVOICE_ID, CURRENCY_ID, CREATED_AT, UPDATED_AT FROM cart WHERE ID = :p0'; + $sql = 'SELECT ID, TOKEN, CUSTOMER_ID, ADDRESS_DELIVERY_ID, ADDRESS_INVOICE_ID, CURRENCY_ID, DISCOUNT, CREATED_AT, UPDATED_AT FROM cart WHERE ID = :p0'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key, PDO::PARAM_INT); @@ -502,6 +506,47 @@ abstract class CartQuery extends ModelCriteria return $this->addUsingAlias(CartTableMap::CURRENCY_ID, $currencyId, $comparison); } + /** + * Filter the query on the discount column + * + * Example usage: + * + * $query->filterByDiscount(1234); // WHERE discount = 1234 + * $query->filterByDiscount(array(12, 34)); // WHERE discount IN (12, 34) + * $query->filterByDiscount(array('min' => 12)); // WHERE discount > 12 + * + * + * @param mixed $discount The value to use as filter. + * 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 ChildCartQuery The current query, for fluid interface + */ + public function filterByDiscount($discount = null, $comparison = null) + { + if (is_array($discount)) { + $useMinMax = false; + if (isset($discount['min'])) { + $this->addUsingAlias(CartTableMap::DISCOUNT, $discount['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($discount['max'])) { + $this->addUsingAlias(CartTableMap::DISCOUNT, $discount['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(CartTableMap::DISCOUNT, $discount, $comparison); + } + /** * Filter the query on the created_at column * diff --git a/core/lib/Thelia/Model/Map/CartItemTableMap.php b/core/lib/Thelia/Model/Map/CartItemTableMap.php index 687b1cd68..7520b39c9 100644 --- a/core/lib/Thelia/Model/Map/CartItemTableMap.php +++ b/core/lib/Thelia/Model/Map/CartItemTableMap.php @@ -57,7 +57,7 @@ class CartItemTableMap extends TableMap /** * The total number of columns */ - const NUM_COLUMNS = 10; + const NUM_COLUMNS = 11; /** * The number of lazy-loaded columns @@ -67,7 +67,7 @@ class CartItemTableMap extends TableMap /** * The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */ - const NUM_HYDRATE_COLUMNS = 10; + const NUM_HYDRATE_COLUMNS = 11; /** * the column name for the ID field @@ -109,6 +109,11 @@ class CartItemTableMap extends TableMap */ const PRICE_END_OF_LIFE = 'cart_item.PRICE_END_OF_LIFE'; + /** + * the column name for the DISCOUNT field + */ + const DISCOUNT = 'cart_item.DISCOUNT'; + /** * the column name for the CREATED_AT field */ @@ -131,12 +136,12 @@ class CartItemTableMap extends TableMap * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ protected static $fieldNames = array ( - self::TYPE_PHPNAME => array('Id', 'CartId', 'ProductId', 'Quantity', 'ProductSaleElementsId', 'Price', 'PromoPrice', 'PriceEndOfLife', 'CreatedAt', 'UpdatedAt', ), - self::TYPE_STUDLYPHPNAME => array('id', 'cartId', 'productId', 'quantity', 'productSaleElementsId', 'price', 'promoPrice', 'priceEndOfLife', 'createdAt', 'updatedAt', ), - self::TYPE_COLNAME => array(CartItemTableMap::ID, CartItemTableMap::CART_ID, CartItemTableMap::PRODUCT_ID, CartItemTableMap::QUANTITY, CartItemTableMap::PRODUCT_SALE_ELEMENTS_ID, CartItemTableMap::PRICE, CartItemTableMap::PROMO_PRICE, CartItemTableMap::PRICE_END_OF_LIFE, CartItemTableMap::CREATED_AT, CartItemTableMap::UPDATED_AT, ), - self::TYPE_RAW_COLNAME => array('ID', 'CART_ID', 'PRODUCT_ID', 'QUANTITY', 'PRODUCT_SALE_ELEMENTS_ID', 'PRICE', 'PROMO_PRICE', 'PRICE_END_OF_LIFE', 'CREATED_AT', 'UPDATED_AT', ), - self::TYPE_FIELDNAME => array('id', 'cart_id', 'product_id', 'quantity', 'product_sale_elements_id', 'price', 'promo_price', 'price_end_of_life', 'created_at', 'updated_at', ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ) + self::TYPE_PHPNAME => array('Id', 'CartId', 'ProductId', 'Quantity', 'ProductSaleElementsId', 'Price', 'PromoPrice', 'PriceEndOfLife', 'Discount', 'CreatedAt', 'UpdatedAt', ), + self::TYPE_STUDLYPHPNAME => array('id', 'cartId', 'productId', 'quantity', 'productSaleElementsId', 'price', 'promoPrice', 'priceEndOfLife', 'discount', 'createdAt', 'updatedAt', ), + self::TYPE_COLNAME => array(CartItemTableMap::ID, CartItemTableMap::CART_ID, CartItemTableMap::PRODUCT_ID, CartItemTableMap::QUANTITY, CartItemTableMap::PRODUCT_SALE_ELEMENTS_ID, CartItemTableMap::PRICE, CartItemTableMap::PROMO_PRICE, CartItemTableMap::PRICE_END_OF_LIFE, CartItemTableMap::DISCOUNT, CartItemTableMap::CREATED_AT, CartItemTableMap::UPDATED_AT, ), + self::TYPE_RAW_COLNAME => array('ID', 'CART_ID', 'PRODUCT_ID', 'QUANTITY', 'PRODUCT_SALE_ELEMENTS_ID', 'PRICE', 'PROMO_PRICE', 'PRICE_END_OF_LIFE', 'DISCOUNT', 'CREATED_AT', 'UPDATED_AT', ), + self::TYPE_FIELDNAME => array('id', 'cart_id', 'product_id', 'quantity', 'product_sale_elements_id', 'price', 'promo_price', 'price_end_of_life', 'discount', 'created_at', 'updated_at', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ) ); /** @@ -146,12 +151,12 @@ class CartItemTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'CartId' => 1, 'ProductId' => 2, 'Quantity' => 3, 'ProductSaleElementsId' => 4, 'Price' => 5, 'PromoPrice' => 6, 'PriceEndOfLife' => 7, 'CreatedAt' => 8, 'UpdatedAt' => 9, ), - self::TYPE_STUDLYPHPNAME => array('id' => 0, 'cartId' => 1, 'productId' => 2, 'quantity' => 3, 'productSaleElementsId' => 4, 'price' => 5, 'promoPrice' => 6, 'priceEndOfLife' => 7, 'createdAt' => 8, 'updatedAt' => 9, ), - self::TYPE_COLNAME => array(CartItemTableMap::ID => 0, CartItemTableMap::CART_ID => 1, CartItemTableMap::PRODUCT_ID => 2, CartItemTableMap::QUANTITY => 3, CartItemTableMap::PRODUCT_SALE_ELEMENTS_ID => 4, CartItemTableMap::PRICE => 5, CartItemTableMap::PROMO_PRICE => 6, CartItemTableMap::PRICE_END_OF_LIFE => 7, CartItemTableMap::CREATED_AT => 8, CartItemTableMap::UPDATED_AT => 9, ), - self::TYPE_RAW_COLNAME => array('ID' => 0, 'CART_ID' => 1, 'PRODUCT_ID' => 2, 'QUANTITY' => 3, 'PRODUCT_SALE_ELEMENTS_ID' => 4, 'PRICE' => 5, 'PROMO_PRICE' => 6, 'PRICE_END_OF_LIFE' => 7, 'CREATED_AT' => 8, 'UPDATED_AT' => 9, ), - self::TYPE_FIELDNAME => array('id' => 0, 'cart_id' => 1, 'product_id' => 2, 'quantity' => 3, 'product_sale_elements_id' => 4, 'price' => 5, 'promo_price' => 6, 'price_end_of_life' => 7, 'created_at' => 8, 'updated_at' => 9, ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ) + self::TYPE_PHPNAME => array('Id' => 0, 'CartId' => 1, 'ProductId' => 2, 'Quantity' => 3, 'ProductSaleElementsId' => 4, 'Price' => 5, 'PromoPrice' => 6, 'PriceEndOfLife' => 7, 'Discount' => 8, 'CreatedAt' => 9, 'UpdatedAt' => 10, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'cartId' => 1, 'productId' => 2, 'quantity' => 3, 'productSaleElementsId' => 4, 'price' => 5, 'promoPrice' => 6, 'priceEndOfLife' => 7, 'discount' => 8, 'createdAt' => 9, 'updatedAt' => 10, ), + self::TYPE_COLNAME => array(CartItemTableMap::ID => 0, CartItemTableMap::CART_ID => 1, CartItemTableMap::PRODUCT_ID => 2, CartItemTableMap::QUANTITY => 3, CartItemTableMap::PRODUCT_SALE_ELEMENTS_ID => 4, CartItemTableMap::PRICE => 5, CartItemTableMap::PROMO_PRICE => 6, CartItemTableMap::PRICE_END_OF_LIFE => 7, CartItemTableMap::DISCOUNT => 8, CartItemTableMap::CREATED_AT => 9, CartItemTableMap::UPDATED_AT => 10, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'CART_ID' => 1, 'PRODUCT_ID' => 2, 'QUANTITY' => 3, 'PRODUCT_SALE_ELEMENTS_ID' => 4, 'PRICE' => 5, 'PROMO_PRICE' => 6, 'PRICE_END_OF_LIFE' => 7, 'DISCOUNT' => 8, 'CREATED_AT' => 9, 'UPDATED_AT' => 10, ), + self::TYPE_FIELDNAME => array('id' => 0, 'cart_id' => 1, 'product_id' => 2, 'quantity' => 3, 'product_sale_elements_id' => 4, 'price' => 5, 'promo_price' => 6, 'price_end_of_life' => 7, 'discount' => 8, 'created_at' => 9, 'updated_at' => 10, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ) ); /** @@ -178,6 +183,7 @@ class CartItemTableMap extends TableMap $this->addColumn('PRICE', 'Price', 'FLOAT', false, null, null); $this->addColumn('PROMO_PRICE', 'PromoPrice', 'FLOAT', false, null, null); $this->addColumn('PRICE_END_OF_LIFE', 'PriceEndOfLife', 'TIMESTAMP', false, null, null); + $this->addColumn('DISCOUNT', 'Discount', 'FLOAT', false, null, 0); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); } // initialize() @@ -351,6 +357,7 @@ class CartItemTableMap extends TableMap $criteria->addSelectColumn(CartItemTableMap::PRICE); $criteria->addSelectColumn(CartItemTableMap::PROMO_PRICE); $criteria->addSelectColumn(CartItemTableMap::PRICE_END_OF_LIFE); + $criteria->addSelectColumn(CartItemTableMap::DISCOUNT); $criteria->addSelectColumn(CartItemTableMap::CREATED_AT); $criteria->addSelectColumn(CartItemTableMap::UPDATED_AT); } else { @@ -362,6 +369,7 @@ class CartItemTableMap extends TableMap $criteria->addSelectColumn($alias . '.PRICE'); $criteria->addSelectColumn($alias . '.PROMO_PRICE'); $criteria->addSelectColumn($alias . '.PRICE_END_OF_LIFE'); + $criteria->addSelectColumn($alias . '.DISCOUNT'); $criteria->addSelectColumn($alias . '.CREATED_AT'); $criteria->addSelectColumn($alias . '.UPDATED_AT'); } diff --git a/core/lib/Thelia/Model/Map/CartTableMap.php b/core/lib/Thelia/Model/Map/CartTableMap.php index 80d371f66..d839b4e91 100644 --- a/core/lib/Thelia/Model/Map/CartTableMap.php +++ b/core/lib/Thelia/Model/Map/CartTableMap.php @@ -57,7 +57,7 @@ class CartTableMap extends TableMap /** * The total number of columns */ - const NUM_COLUMNS = 8; + const NUM_COLUMNS = 9; /** * The number of lazy-loaded columns @@ -67,7 +67,7 @@ class CartTableMap extends TableMap /** * The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */ - const NUM_HYDRATE_COLUMNS = 8; + const NUM_HYDRATE_COLUMNS = 9; /** * the column name for the ID field @@ -99,6 +99,11 @@ class CartTableMap extends TableMap */ const CURRENCY_ID = 'cart.CURRENCY_ID'; + /** + * the column name for the DISCOUNT field + */ + const DISCOUNT = 'cart.DISCOUNT'; + /** * the column name for the CREATED_AT field */ @@ -121,12 +126,12 @@ class CartTableMap extends TableMap * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ protected static $fieldNames = array ( - self::TYPE_PHPNAME => array('Id', 'Token', 'CustomerId', 'AddressDeliveryId', 'AddressInvoiceId', 'CurrencyId', 'CreatedAt', 'UpdatedAt', ), - self::TYPE_STUDLYPHPNAME => array('id', 'token', 'customerId', 'addressDeliveryId', 'addressInvoiceId', 'currencyId', 'createdAt', 'updatedAt', ), - self::TYPE_COLNAME => array(CartTableMap::ID, CartTableMap::TOKEN, CartTableMap::CUSTOMER_ID, CartTableMap::ADDRESS_DELIVERY_ID, CartTableMap::ADDRESS_INVOICE_ID, CartTableMap::CURRENCY_ID, CartTableMap::CREATED_AT, CartTableMap::UPDATED_AT, ), - self::TYPE_RAW_COLNAME => array('ID', 'TOKEN', 'CUSTOMER_ID', 'ADDRESS_DELIVERY_ID', 'ADDRESS_INVOICE_ID', 'CURRENCY_ID', 'CREATED_AT', 'UPDATED_AT', ), - self::TYPE_FIELDNAME => array('id', 'token', 'customer_id', 'address_delivery_id', 'address_invoice_id', 'currency_id', 'created_at', 'updated_at', ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, ) + self::TYPE_PHPNAME => array('Id', 'Token', 'CustomerId', 'AddressDeliveryId', 'AddressInvoiceId', 'CurrencyId', 'Discount', 'CreatedAt', 'UpdatedAt', ), + self::TYPE_STUDLYPHPNAME => array('id', 'token', 'customerId', 'addressDeliveryId', 'addressInvoiceId', 'currencyId', 'discount', 'createdAt', 'updatedAt', ), + self::TYPE_COLNAME => array(CartTableMap::ID, CartTableMap::TOKEN, CartTableMap::CUSTOMER_ID, CartTableMap::ADDRESS_DELIVERY_ID, CartTableMap::ADDRESS_INVOICE_ID, CartTableMap::CURRENCY_ID, CartTableMap::DISCOUNT, CartTableMap::CREATED_AT, CartTableMap::UPDATED_AT, ), + self::TYPE_RAW_COLNAME => array('ID', 'TOKEN', 'CUSTOMER_ID', 'ADDRESS_DELIVERY_ID', 'ADDRESS_INVOICE_ID', 'CURRENCY_ID', 'DISCOUNT', 'CREATED_AT', 'UPDATED_AT', ), + self::TYPE_FIELDNAME => array('id', 'token', 'customer_id', 'address_delivery_id', 'address_invoice_id', 'currency_id', 'discount', 'created_at', 'updated_at', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, ) ); /** @@ -136,12 +141,12 @@ class CartTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'Token' => 1, 'CustomerId' => 2, 'AddressDeliveryId' => 3, 'AddressInvoiceId' => 4, 'CurrencyId' => 5, 'CreatedAt' => 6, 'UpdatedAt' => 7, ), - self::TYPE_STUDLYPHPNAME => array('id' => 0, 'token' => 1, 'customerId' => 2, 'addressDeliveryId' => 3, 'addressInvoiceId' => 4, 'currencyId' => 5, 'createdAt' => 6, 'updatedAt' => 7, ), - self::TYPE_COLNAME => array(CartTableMap::ID => 0, CartTableMap::TOKEN => 1, CartTableMap::CUSTOMER_ID => 2, CartTableMap::ADDRESS_DELIVERY_ID => 3, CartTableMap::ADDRESS_INVOICE_ID => 4, CartTableMap::CURRENCY_ID => 5, CartTableMap::CREATED_AT => 6, CartTableMap::UPDATED_AT => 7, ), - self::TYPE_RAW_COLNAME => array('ID' => 0, 'TOKEN' => 1, 'CUSTOMER_ID' => 2, 'ADDRESS_DELIVERY_ID' => 3, 'ADDRESS_INVOICE_ID' => 4, 'CURRENCY_ID' => 5, 'CREATED_AT' => 6, 'UPDATED_AT' => 7, ), - self::TYPE_FIELDNAME => array('id' => 0, 'token' => 1, 'customer_id' => 2, 'address_delivery_id' => 3, 'address_invoice_id' => 4, 'currency_id' => 5, 'created_at' => 6, 'updated_at' => 7, ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, ) + self::TYPE_PHPNAME => array('Id' => 0, 'Token' => 1, 'CustomerId' => 2, 'AddressDeliveryId' => 3, 'AddressInvoiceId' => 4, 'CurrencyId' => 5, 'Discount' => 6, 'CreatedAt' => 7, 'UpdatedAt' => 8, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'token' => 1, 'customerId' => 2, 'addressDeliveryId' => 3, 'addressInvoiceId' => 4, 'currencyId' => 5, 'discount' => 6, 'createdAt' => 7, 'updatedAt' => 8, ), + self::TYPE_COLNAME => array(CartTableMap::ID => 0, CartTableMap::TOKEN => 1, CartTableMap::CUSTOMER_ID => 2, CartTableMap::ADDRESS_DELIVERY_ID => 3, CartTableMap::ADDRESS_INVOICE_ID => 4, CartTableMap::CURRENCY_ID => 5, CartTableMap::DISCOUNT => 6, CartTableMap::CREATED_AT => 7, CartTableMap::UPDATED_AT => 8, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'TOKEN' => 1, 'CUSTOMER_ID' => 2, 'ADDRESS_DELIVERY_ID' => 3, 'ADDRESS_INVOICE_ID' => 4, 'CURRENCY_ID' => 5, 'DISCOUNT' => 6, 'CREATED_AT' => 7, 'UPDATED_AT' => 8, ), + self::TYPE_FIELDNAME => array('id' => 0, 'token' => 1, 'customer_id' => 2, 'address_delivery_id' => 3, 'address_invoice_id' => 4, 'currency_id' => 5, 'discount' => 6, 'created_at' => 7, 'updated_at' => 8, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, ) ); /** @@ -166,6 +171,7 @@ class CartTableMap extends TableMap $this->addForeignKey('ADDRESS_DELIVERY_ID', 'AddressDeliveryId', 'INTEGER', 'address', 'ID', false, null, null); $this->addForeignKey('ADDRESS_INVOICE_ID', 'AddressInvoiceId', 'INTEGER', 'address', 'ID', false, null, null); $this->addForeignKey('CURRENCY_ID', 'CurrencyId', 'INTEGER', 'currency', 'ID', false, null, null); + $this->addColumn('DISCOUNT', 'Discount', 'FLOAT', false, null, 0); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); } // initialize() @@ -339,6 +345,7 @@ class CartTableMap extends TableMap $criteria->addSelectColumn(CartTableMap::ADDRESS_DELIVERY_ID); $criteria->addSelectColumn(CartTableMap::ADDRESS_INVOICE_ID); $criteria->addSelectColumn(CartTableMap::CURRENCY_ID); + $criteria->addSelectColumn(CartTableMap::DISCOUNT); $criteria->addSelectColumn(CartTableMap::CREATED_AT); $criteria->addSelectColumn(CartTableMap::UPDATED_AT); } else { @@ -348,6 +355,7 @@ class CartTableMap extends TableMap $criteria->addSelectColumn($alias . '.ADDRESS_DELIVERY_ID'); $criteria->addSelectColumn($alias . '.ADDRESS_INVOICE_ID'); $criteria->addSelectColumn($alias . '.CURRENCY_ID'); + $criteria->addSelectColumn($alias . '.DISCOUNT'); $criteria->addSelectColumn($alias . '.CREATED_AT'); $criteria->addSelectColumn($alias . '.UPDATED_AT'); } diff --git a/install/thelia.sql b/install/thelia.sql index 7f040ff50..dd0e9a79c 100755 --- a/install/thelia.sql +++ b/install/thelia.sql @@ -1153,6 +1153,7 @@ CREATE TABLE `cart` `address_delivery_id` INTEGER, `address_invoice_id` INTEGER, `currency_id` INTEGER, + `discount` FLOAT DEFAULT 0, `created_at` DATETIME, `updated_at` DATETIME, PRIMARY KEY (`id`), @@ -1191,6 +1192,7 @@ CREATE TABLE `cart_item` `price` FLOAT, `promo_price` FLOAT, `price_end_of_life` DATETIME, + `discount` FLOAT DEFAULT 0, `created_at` DATETIME, `updated_at` DATETIME, PRIMARY KEY (`id`), diff --git a/local/config/schema.xml b/local/config/schema.xml index 8759624a9..1d928bc7b 100755 --- a/local/config/schema.xml +++ b/local/config/schema.xml @@ -870,6 +870,7 @@ + @@ -908,6 +909,7 @@ + From 8ad0dc7b210cd76bb00b1b80f36c297221062e96 Mon Sep 17 00:00:00 2001 From: franck Date: Thu, 12 Sep 2013 15:43:37 +0200 Subject: [PATCH 27/45] AttributesAv management --- core/lib/Thelia/Action/AttributeAv.php | 6 +- core/lib/Thelia/Config/Resources/config.xml | 3 +- .../Admin/AttributeAvController.php | 180 ++++++++++++++++++ ...onForm.php => AttributeAvCreationForm.php} | 4 +- .../Thelia/Form/AttributeModificationForm.php | 4 + core/lib/Thelia/Model/AttributeAv.php | 31 ++- .../Model/Tools/PositionManagementTrait.php | 21 +- templates/admin/default/attribute-edit.html | 23 ++- 8 files changed, 228 insertions(+), 44 deletions(-) create mode 100644 core/lib/Thelia/Controller/Admin/AttributeAvController.php rename core/lib/Thelia/Form/{AttributeValueCreationForm.php => AttributeAvCreationForm.php} (96%) diff --git a/core/lib/Thelia/Action/AttributeAv.php b/core/lib/Thelia/Action/AttributeAv.php index 53df7aa72..a6b442fa2 100644 --- a/core/lib/Thelia/Action/AttributeAv.php +++ b/core/lib/Thelia/Action/AttributeAv.php @@ -50,6 +50,7 @@ class AttributeAv extends BaseAction implements EventSubscriberInterface $attribute ->setDispatcher($this->getDispatcher()) + ->setAttributeId($event->getAttributeId()) ->setLocale($event->getLocale()) ->setTitle($event->getTitle()) @@ -57,11 +58,6 @@ class AttributeAv extends BaseAction implements EventSubscriberInterface ; $event->setAttributeAv($attribute); - - // Add atribute to all product templates if required - if ($event->getAddToAllTemplates() != 0) { - // TODO: add to all product template - } } /** diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index 31f013c88..ddb32cf65 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -70,7 +70,8 @@
    - + + diff --git a/core/lib/Thelia/Controller/Admin/AttributeAvController.php b/core/lib/Thelia/Controller/Admin/AttributeAvController.php new file mode 100644 index 000000000..b7118b53a --- /dev/null +++ b/core/lib/Thelia/Controller/Admin/AttributeAvController.php @@ -0,0 +1,180 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Controller\Admin; + +use Thelia\Core\Event\AttributeAvDeleteEvent; +use Thelia\Core\Event\TheliaEvents; +use Thelia\Core\Event\AttributeAvUpdateEvent; +use Thelia\Core\Event\AttributeAvCreateEvent; +use Thelia\Model\AttributeAvQuery; +use Thelia\Form\AttributeAvModificationForm; +use Thelia\Form\AttributeAvCreationForm; +use Thelia\Core\Event\UpdatePositionEvent; + +/** + * Manages attributes-av sent by mail + * + * @author Franck Allimant + */ +class AttributeAvController extends AbstractCrudController +{ + public function __construct() { + parent::__construct( + 'attribute', + 'manual', + + 'admin.configuration.attributes-av.view', + 'admin.configuration.attributes-av.create', + 'admin.configuration.attributes-av.update', + 'admin.configuration.attributes-av.delete', + + TheliaEvents::ATTRIBUTE_AV_CREATE, + TheliaEvents::ATTRIBUTE_AV_UPDATE, + TheliaEvents::ATTRIBUTE_AV_DELETE, + null, // No visibility toggle + TheliaEvents::ATTRIBUTE_AV_UPDATE_POSITION + ); + } + + protected function getCreationForm() { + return new AttributeAvCreationForm($this->getRequest()); + } + + protected function getUpdateForm() { + return new AttributeAvModificationForm($this->getRequest()); + } + + protected function getCreationEvent($formData) { + $createEvent = new AttributeAvCreateEvent(); + + $createEvent + ->setAttributeId($formData['attribute_id']) + ->setTitle($formData['title']) + ->setLocale($formData["locale"]) + ; + + return $createEvent; + } + + protected function getUpdateEvent($formData) { + + $changeEvent = new AttributeAvUpdateEvent($formData['id']); + + // Create and dispatch the change event + $changeEvent + ->setLocale($formData["locale"]) + ->setTitle($formData['title']) + ->setChapo($formData['chapo']) + ->setDescription($formData['description']) + ->setPostscriptum($formData['postscriptum']) + ; + + return $changeEvent; + } + + protected function createUpdatePositionEvent($positionChangeMode, $positionValue) { + + return new UpdatePositionEvent( + $this->getRequest()->get('attributeav_id', null), + $positionChangeMode, + $positionValue + ); + } + + protected function getDeleteEvent() { + return new AttributeAvDeleteEvent($this->getRequest()->get('attributeav_id')); + } + + protected function eventContainsObject($event) { + return $event->hasAttributeAv(); + } + + protected function hydrateObjectForm($object) { + + $data = array( + 'id' => $object->getId(), + 'locale' => $object->getLocale(), + 'title' => $object->getTitle(), + 'chapo' => $object->getChapo(), + 'description' => $object->getDescription(), + 'postscriptum' => $object->getPostscriptum() + ); + + // Setup the object form + return new AttributeAvModificationForm($this->getRequest(), "form", $data); + } + + protected function getObjectFromEvent($event) { + return $event->hasAttributeAv() ? $event->getAttributeAv() : null; + } + + protected function getExistingObject() { + return AttributeAvQuery::create() + ->joinWithI18n($this->getCurrentEditionLocale()) + ->findOneById($this->getRequest()->get('attributeav_id')); + } + + protected function getObjectLabel($object) { + return $object->getTitle(); + } + + protected function getObjectId($object) { + return $object->getId(); + } + + protected function getViewArguments() { + return array( + 'attribute_id' => $this->getRequest()->get('attribute_id'), + 'order' => $this->getCurrentListOrder() + ); + } + + protected function renderListTemplate($currentOrder) { + // We always return to the attribute edition form + return $this->render( + 'attribute-edit', + $this->getViewArguments() + ); + } + + protected function renderEditionTemplate() { + // We always return to the attribute edition form + return $this->render('attribute-edit', $this->getViewArguments()); + } + + protected function redirectToEditionTemplate() { + // We always return to the attribute edition form + $this->redirectToRoute( + "admin.configuration.attributes.update", + $this->getViewArguments() + ); + } + + protected function redirectToListTemplate() { + $this->redirectToRoute( + "admin.configuration.attributes.update", + $this->getViewArguments() + ); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Form/AttributeValueCreationForm.php b/core/lib/Thelia/Form/AttributeAvCreationForm.php similarity index 96% rename from core/lib/Thelia/Form/AttributeValueCreationForm.php rename to core/lib/Thelia/Form/AttributeAvCreationForm.php index dc9de681d..2ad202e1d 100644 --- a/core/lib/Thelia/Form/AttributeValueCreationForm.php +++ b/core/lib/Thelia/Form/AttributeAvCreationForm.php @@ -28,7 +28,7 @@ use Symfony\Component\Validator\ExecutionContextInterface; use Symfony\Component\Validator\Constraints\NotBlank; use Thelia\Core\Translation\Translator; -class AttributeValueCreationForm extends BaseForm +class AttributeAvCreationForm extends BaseForm { protected function buildForm() { @@ -57,6 +57,6 @@ class AttributeValueCreationForm extends BaseForm public function getName() { - return "thelia_attribute_value_creation"; + return "thelia_attributeav_creation"; } } \ No newline at end of file diff --git a/core/lib/Thelia/Form/AttributeModificationForm.php b/core/lib/Thelia/Form/AttributeModificationForm.php index 922ec489b..62b0b707a 100644 --- a/core/lib/Thelia/Form/AttributeModificationForm.php +++ b/core/lib/Thelia/Form/AttributeModificationForm.php @@ -43,6 +43,10 @@ class AttributeModificationForm extends AttributeCreationForm ) ) )) + ->add('attribute_values', 'collection', array( + 'type' => 'text', + 'options' => array('required' => false) + )) ; // Add standard description fields diff --git a/core/lib/Thelia/Model/AttributeAv.php b/core/lib/Thelia/Model/AttributeAv.php index 2b70881d7..d45b16192 100755 --- a/core/lib/Thelia/Model/AttributeAv.php +++ b/core/lib/Thelia/Model/AttributeAv.php @@ -3,7 +3,7 @@ namespace Thelia\Model; use Thelia\Model\Base\AttributeAv as BaseAttributeAv; -use Thelia\Core\Event\AttributeValueEvent; +use Thelia\Core\Event\AttributeAvEvent; use Propel\Runtime\Connection\ConnectionInterface; use Thelia\Core\Event\TheliaEvents; use Propel\Runtime\ActiveQuery\Criteria; @@ -11,21 +11,14 @@ use Propel\Runtime\ActiveQuery\Criteria; class AttributeAv extends BaseAttributeAv { use \Thelia\Model\Tools\ModelEventDispatcherTrait; + use \Thelia\Model\Tools\PositionManagementTrait; /** - * Get the position of the next inserted object + * when dealing with position, be sure to work insite the current attribute. */ - public function getNextPosition($parent = null) { - - $last = $this->createQuery() - ->filterByAttributeId($this->getAttributeId()) - ->orderByPosition(Criteria::DESC) - ->limit(1) - ->findOne() - ; - - return $last != null ? $last->getPosition() + 1 : 1; + protected function addCriteriaToPositionQuery($query) { + $query->filterByAttributeId($this->getAttributeId()); } /** @@ -33,11 +26,11 @@ class AttributeAv extends BaseAttributeAv { */ public function preInsert(ConnectionInterface $con = null) { - $this->dispatchEvent(TheliaEvents::BEFORE_CREATEATTRIBUTE_VALUE, new AttributeValueEvent($this)); - // Set the current position for the new object $this->setPosition($this->getNextPosition()); + $this->dispatchEvent(TheliaEvents::BEFORE_CREATEATTRIBUTE_AV, new AttributeAvEvent($this)); + return true; } @@ -46,7 +39,7 @@ class AttributeAv extends BaseAttributeAv { */ public function postInsert(ConnectionInterface $con = null) { - $this->dispatchEvent(TheliaEvents::AFTER_CREATEATTRIBUTE_VALUE, new AttributeValueEvent($this)); + $this->dispatchEvent(TheliaEvents::AFTER_CREATEATTRIBUTE_AV, new AttributeAvEvent($this)); } /** @@ -54,7 +47,7 @@ class AttributeAv extends BaseAttributeAv { */ public function preUpdate(ConnectionInterface $con = null) { - $this->dispatchEvent(TheliaEvents::BEFORE_UPDATEATTRIBUTE_VALUE, new AttributeValueEvent($this)); + $this->dispatchEvent(TheliaEvents::BEFORE_UPDATEATTRIBUTE_AV, new AttributeAvEvent($this)); return true; } @@ -64,7 +57,7 @@ class AttributeAv extends BaseAttributeAv { */ public function postUpdate(ConnectionInterface $con = null) { - $this->dispatchEvent(TheliaEvents::AFTER_UPDATEATTRIBUTE_VALUE, new AttributeValueEvent($this)); + $this->dispatchEvent(TheliaEvents::AFTER_UPDATEATTRIBUTE_AV, new AttributeAvEvent($this)); } /** @@ -72,7 +65,7 @@ class AttributeAv extends BaseAttributeAv { */ public function preDelete(ConnectionInterface $con = null) { - $this->dispatchEvent(TheliaEvents::BEFORE_DELETEATTRIBUTE_VALUE, new AttributeValueEvent($this)); + $this->dispatchEvent(TheliaEvents::BEFORE_DELETEATTRIBUTE_AV, new AttributeAvEvent($this)); return true; } @@ -82,6 +75,6 @@ class AttributeAv extends BaseAttributeAv { */ public function postDelete(ConnectionInterface $con = null) { - $this->dispatchEvent(TheliaEvents::AFTER_DELETEATTRIBUTE_VALUE, new AttributeValueEvent($this)); + $this->dispatchEvent(TheliaEvents::AFTER_DELETEATTRIBUTE_AV, new AttributeAvEvent($this)); } } \ No newline at end of file diff --git a/core/lib/Thelia/Model/Tools/PositionManagementTrait.php b/core/lib/Thelia/Model/Tools/PositionManagementTrait.php index d5cc4ea63..70da830ac 100644 --- a/core/lib/Thelia/Model/Tools/PositionManagementTrait.php +++ b/core/lib/Thelia/Model/Tools/PositionManagementTrait.php @@ -45,29 +45,34 @@ trait PositionManagementTrait { return $class->getConstant('DATABASE_NAME'); } + /** + * Implementors may add some search criteria (e.g., parent id) to the queries + * used to change/get position by overloading this method. + */ + protected function addCriteriaToPositionQuery($query) { + // Add required criteria here... + } /** * Get the position of the next inserted object */ - public function getNextPosition($parent = null) { + public function getNextPosition() { $query = $this->createQuery() ->orderByPosition(Criteria::DESC) ->limit(1); - if ($parent !== null) $query->filterByParent($parent); + $this->addCriteriaToPositionQuery($query); - $last = $query->findOne() - ; + $last = $query->findOne(); - return $last != null ? $last->getPosition() + 1 : 1; + return $last != null ? $last->getPosition() + 1 : 1; } /** * Move up a object */ public function movePositionUp() { - echo "move up !"; $this->movePositionUpOrDown(true); } @@ -91,7 +96,7 @@ trait PositionManagementTrait { // Find object to exchange position with $search = $this->createQuery(); - if (method_exists($this, 'getParent')) $search->filterByParent($this->getParent()); + $this->addCriteriaToPositionQuery($search); // Up or down ? if ($up === true) { @@ -152,7 +157,7 @@ trait PositionManagementTrait { // Find categories to offset $search = $this->createQuery(); - if (method_exists($this, 'getParent')) $search->filterByParent($this->getParent()); + $this->addCriteriaToPositionQuery($search); if ($newPosition > $current_position) { // The new position is after the current position -> we will offset + 1 all categories located between us and the new position diff --git a/templates/admin/default/attribute-edit.html b/templates/admin/default/attribute-edit.html index 58933cc9a..1b290f222 100644 --- a/templates/admin/default/attribute-edit.html +++ b/templates/admin/default/attribute-edit.html @@ -61,7 +61,7 @@ {intl l='Attribute values'} - {loop type="auth" name="can_create" roles="ADMIN" permissions="admin.configuration.attribute-values.create"} + {loop type="auth" name="can_create" roles="ADMIN" permissions="admin.configuration.attribute-av.create"} @@ -125,8 +125,8 @@ {admin_position_block permission="admin.attributes.edit" - path="/admin/configuration/attributes/update-value-position" - url_parameter="attribute_id" + path={url path='/admin/configuration/attributes-av/update-position' attribute_id=$attribute_id} + url_parameter="attributeav_id" in_place_edit_class="positionChange" position="$POSITION" id="$ID" @@ -137,7 +137,11 @@
    - + {loop type="auth" name="can_create" roles="ADMIN" permissions="admin.configuration.attribute-av.delete"} + + + + {/loop}
    @@ -181,7 +185,7 @@ {* Adding a new attribute *} -{form name="thelia.admin.attribute-value.creation"} +{form name="thelia.admin.attributeav.creation"} {* Capture the dialog body, to pass it to the generic dialog *} @@ -232,7 +236,7 @@ dialog_ok_label = {intl l="Create this value"} - form_action = {url path='/admin/configuration/attributes-av'} + form_action = {url path='/admin/configuration/attributes-av/create'} form_enctype = {form_enctype form=$form} form_error_message = $form_error_message } @@ -241,7 +245,8 @@ {* Delete value confirmation dialog *} {capture "delete_dialog"} - + + {/capture} {include @@ -275,7 +280,7 @@ {include file = "includes/generic-js-dialog.html" dialog_id = "creation_dialog" - form_name = "thelia.admin.attribute-value.creation" + form_name = "thelia.admin.attributeav.creation" } {* Inline editing of object position using bootstrap-editable *} @@ -288,7 +293,7 @@ placement : 'left', success : function(response, newValue) { // The URL template - var url = "{url path='/admin/configuration/attributes/update-value-position' attribute_value_id='__ID__' position='__POS__'}"; + var url = "{url path='/admin/configuration/attributes-av/update-position' attributeav_id='__ID__' position='__POS__' attribute_id=$attribute_id}"; // Perform subtitutions url = url.replace('__ID__', $(this).data('id')).replace('__POS__', newValue); From 22f42c8d9cdebfb11a7e924e493ec3ffe2db1788 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Thu, 12 Sep 2013 16:21:01 +0200 Subject: [PATCH 28/45] don't delete address if this is address is a default one --- core/lib/Thelia/Model/Address.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/core/lib/Thelia/Model/Address.php b/core/lib/Thelia/Model/Address.php index 413797eeb..5ce697e8f 100755 --- a/core/lib/Thelia/Model/Address.php +++ b/core/lib/Thelia/Model/Address.php @@ -71,4 +71,14 @@ class Address extends BaseAddress { $this->dispatchEvent(TheliaEvents::AFTER_DELETEADDRESS, new AddressEvent($this)); } + public function preSave() + { + $valid = true; + if($this->getIsDefault()) { + $valid = false; + } + + return $valid; + } + } From 2bf6ee51e14d49a2d70202fc5f02d4b6096276cb Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Thu, 12 Sep 2013 16:45:32 +0200 Subject: [PATCH 29/45] add helper checkXmlHttpRequest --- .../{PageNotFound.php => HttpException.php} | 39 ++++++++++++------- core/lib/Thelia/Config/Resources/action.xml | 2 +- .../Thelia/Config/Resources/routing/front.xml | 11 +++++- core/lib/Thelia/Controller/BaseController.php | 13 +++++++ .../Controller/Front/AddressController.php | 9 +++++ templates/default/modal-address.html | 0 6 files changed, 57 insertions(+), 17 deletions(-) rename core/lib/Thelia/Action/{PageNotFound.php => HttpException.php} (77%) create mode 100644 templates/default/modal-address.html diff --git a/core/lib/Thelia/Action/PageNotFound.php b/core/lib/Thelia/Action/HttpException.php similarity index 77% rename from core/lib/Thelia/Action/PageNotFound.php rename to core/lib/Thelia/Action/HttpException.php index c6593ff7c..9cb9fab13 100755 --- a/core/lib/Thelia/Action/PageNotFound.php +++ b/core/lib/Thelia/Action/HttpException.php @@ -32,29 +32,38 @@ use Thelia\Model\ConfigQuery; /** * - * Class PageNotFound + * Class HttpException * @package Thelia\Action * @author Etienne Roudeix */ -class PageNotFound extends BaseAction implements EventSubscriberInterface +class HttpException extends BaseAction implements EventSubscriberInterface { - public function display404(GetResponseForExceptionEvent $event) + public function checkHttpException(GetResponseForExceptionEvent $event) { if ($event->getException() instanceof NotFoundHttpException) { - - $parser = $this->container->get("thelia.parser"); - - // Define the template thant shoud be used - $parser->setTemplate(ConfigQuery::getActiveTemplate()); - - //$event->getRequest()->attributes->set('_view', ConfigQuery::getPageNotFoundView()); - - $response = new Response($parser->render(ConfigQuery::getPageNotFoundView()), 404); - - $event->setResponse($response); + $this->display404($event); } } + protected function display404(GetResponseForExceptionEvent $event) + { + $parser = $this->container->get("thelia.parser"); + + // Define the template thant shoud be used + $parser->setTemplate(ConfigQuery::getActiveTemplate()); + + //$event->getRequest()->attributes->set('_view', ConfigQuery::getPageNotFoundView()); + + $response = new Response($parser->render(ConfigQuery::getPageNotFoundView()), 404); + + $event->setResponse($response); + } + + protected function display403(GetResponseForExceptionEvent $event) + { + $event->setResponse(new Response("You don't have access to this resources", 403)); + } + /** * Returns an array of event names this subscriber wants to listen to. * @@ -78,7 +87,7 @@ class PageNotFound extends BaseAction implements EventSubscriberInterface public static function getSubscribedEvents() { return array( - KernelEvents::EXCEPTION => array("display404", 128), + KernelEvents::EXCEPTION => array("checkHttpException", 128), ); } } diff --git a/core/lib/Thelia/Config/Resources/action.xml b/core/lib/Thelia/Config/Resources/action.xml index 842acdc6f..2b86ed33e 100755 --- a/core/lib/Thelia/Config/Resources/action.xml +++ b/core/lib/Thelia/Config/Resources/action.xml @@ -67,7 +67,7 @@ - + diff --git a/core/lib/Thelia/Config/Resources/routing/front.xml b/core/lib/Thelia/Config/Resources/routing/front.xml index 49713b938..c50fd97b9 100755 --- a/core/lib/Thelia/Config/Resources/routing/front.xml +++ b/core/lib/Thelia/Config/Resources/routing/front.xml @@ -66,12 +66,19 @@ Thelia\Controller\Front\DefaultController::noAction - address_edit + address-edit Thelia\Controller\Front\AddressController::updateAction + + + Thelia\Controller\Front\AddressController::generateModalAction + modal-address + \d+ + + @@ -94,6 +101,8 @@ cart + + Thelia\Controller\Front\DeliveryController::select diff --git a/core/lib/Thelia/Controller/BaseController.php b/core/lib/Thelia/Controller/BaseController.php index 988159be4..ee23eb8a2 100755 --- a/core/lib/Thelia/Controller/BaseController.php +++ b/core/lib/Thelia/Controller/BaseController.php @@ -25,6 +25,7 @@ namespace Thelia\Controller; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\DependencyInjection\ContainerAware; +use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\Routing\Exception\InvalidParameterException; use Symfony\Component\Routing\Exception\MissingMandatoryParametersException; use Symfony\Component\Routing\Exception\RouteNotFoundException; @@ -263,4 +264,16 @@ class BaseController extends ContainerAware { return $this->container->getParameter('kernel.debug'); } + + /** + * check if the current http request is a XmlHttpRequest. + * + * If not, send a + */ + protected function checkXmlHttpRequest() + { + if(false === $this->getRequest()->isXmlHttpRequest() && false === $this->isDebug()) { + throw new AccessDeniedHttpException(); + } + } } diff --git a/core/lib/Thelia/Controller/Front/AddressController.php b/core/lib/Thelia/Controller/Front/AddressController.php index 92d54695c..91f7d1a41 100644 --- a/core/lib/Thelia/Controller/Front/AddressController.php +++ b/core/lib/Thelia/Controller/Front/AddressController.php @@ -39,6 +39,15 @@ use Thelia\Tools\URL; class AddressController extends BaseFrontController { + /** + * Controller for generate modal containing update form + * Check if request is a XmlHttpRequest and address owner is the current customer + * @param $address_id + */ + public function generateModalAction($address_id) + { + $this->checkXmlHttpRequest(); + } /** * Create controller. * Check if customer is logged in diff --git a/templates/default/modal-address.html b/templates/default/modal-address.html new file mode 100644 index 000000000..e69de29bb From 0ca5af597ab350e13b4063b0ff398c267779f8f5 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Thu, 12 Sep 2013 16:50:13 +0200 Subject: [PATCH 30/45] add accessDenied method --- core/lib/Thelia/Controller/BaseController.php | 7 ++++++- core/lib/Thelia/Controller/Front/AddressController.php | 8 +++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/core/lib/Thelia/Controller/BaseController.php b/core/lib/Thelia/Controller/BaseController.php index ee23eb8a2..56118635b 100755 --- a/core/lib/Thelia/Controller/BaseController.php +++ b/core/lib/Thelia/Controller/BaseController.php @@ -265,6 +265,11 @@ class BaseController extends ContainerAware return $this->container->getParameter('kernel.debug'); } + protected function accessDenied() + { + throw new AccessDeniedHttpException(); + } + /** * check if the current http request is a XmlHttpRequest. * @@ -273,7 +278,7 @@ class BaseController extends ContainerAware protected function checkXmlHttpRequest() { if(false === $this->getRequest()->isXmlHttpRequest() && false === $this->isDebug()) { - throw new AccessDeniedHttpException(); + $this->accessDenied(); } } } diff --git a/core/lib/Thelia/Controller/Front/AddressController.php b/core/lib/Thelia/Controller/Front/AddressController.php index 91f7d1a41..5f3fb4799 100644 --- a/core/lib/Thelia/Controller/Front/AddressController.php +++ b/core/lib/Thelia/Controller/Front/AddressController.php @@ -46,7 +46,13 @@ class AddressController extends BaseFrontController */ public function generateModalAction($address_id) { + if ($this->getSecurityContext()->hasCustomerUser() === false) { + $this->accessDenied(); + } + $this->checkXmlHttpRequest(); + + } /** * Create controller. @@ -57,7 +63,7 @@ class AddressController extends BaseFrontController public function createAction() { if ($this->getSecurityContext()->hasCustomerUser() === false) { - $this->redirect(URL::getInstance()->getIndexPage()); + $this->accessDenied() } $addressCreate = new AddressCreateForm($this->getRequest()); From a73c9e1de40a7c7757c9a1c41253c69ec9e6835d Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Thu, 12 Sep 2013 17:20:33 +0200 Subject: [PATCH 31/45] fix current url bug + fix empty loop pagination exception --- .../Template/Smarty/Plugins/TheliaLoop.php | 18 ++++++------------ .../Thelia/Rewriting/RewritingRetriever.php | 6 ++++-- core/lib/Thelia/Tools/URL.php | 8 ++++---- templates/default_save/debug.html | 11 +++++++---- templates/default_save/index.html | 2 ++ 5 files changed, 23 insertions(+), 22 deletions(-) diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/TheliaLoop.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/TheliaLoop.php index 6ed09fe2b..37801f4c8 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/TheliaLoop.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/TheliaLoop.php @@ -67,12 +67,12 @@ class TheliaLoop extends AbstractSmartyPlugin * * @return \PropelModelPager */ - public static function getPagination($loopId) + public static function getPagination($loopName) { - if (!empty(self::$pagination[$loopId])) { - return self::$pagination[$loopId]; + if (array_key_exists($loopName, self::$pagination)) { + return self::$pagination[$loopName]; } else { - return null; + throw new \InvalidArgumentException("Loop $loopName is not defined"); } } @@ -242,16 +242,10 @@ class TheliaLoop extends AbstractSmartyPlugin if (null == $loopName) throw new \InvalidArgumentException("Missing 'rel' parameter in page loop"); - // Find loop results in the current template vars - /* $loopResults = $template->getTemplateVars($loopName); - if (empty($loopResults)) { - throw new \InvalidArgumentException("Loop $loopName is not defined."); - }*/ - // Find pagination $pagination = self::getPagination($loopName); - if ($pagination === null) { - throw new \InvalidArgumentException("Loop $loopName is not defined"); + if ($pagination === null) { // loop gas no result + return ''; } if ($pagination->getNbResults() == 0) { diff --git a/core/lib/Thelia/Rewriting/RewritingRetriever.php b/core/lib/Thelia/Rewriting/RewritingRetriever.php index 8289942f2..dfdbab05c 100755 --- a/core/lib/Thelia/Rewriting/RewritingRetriever.php +++ b/core/lib/Thelia/Rewriting/RewritingRetriever.php @@ -56,12 +56,14 @@ class RewritingRetriever * @param $viewLocale * @param null $viewId */ - public function loadViewUrl($view, $viewLocale, $viewId = null) + public function loadViewUrl($view, $viewLocale = null, $viewId = null) { $this->search = $this->rewritingUrlQuery->getViewUrlQuery($view, $viewLocale, $viewId); $allParametersWithoutView = array(); - $allParametersWithoutView['locale'] = $viewLocale; + if(null !== $viewId) { + $allParametersWithoutView['locale'] = $viewLocale; + } if(null !== $viewId) { $allParametersWithoutView[$view . '_id'] = $viewId; } diff --git a/core/lib/Thelia/Tools/URL.php b/core/lib/Thelia/Tools/URL.php index 05084c0c1..b415844cd 100755 --- a/core/lib/Thelia/Tools/URL.php +++ b/core/lib/Thelia/Tools/URL.php @@ -232,10 +232,10 @@ class URL $this->retriever->loadSpecificUrl($view, $viewLocale, $viewId, $allOtherParameters); } else { - $allParametersWithoutView = $viewOtherParameters; - $allParametersWithoutView['locale'] = $viewLocale; - if (null !== $viewId) { - $allParametersWithoutView[$view . '_id'] = $viewId; + $allParametersWithoutView = $request->query->all(); + $view = $request->attributes->get('_view'); + if(isset($allOtherParameters['view'])) { + unset($allOtherParameters['view']); } $this->retriever->rewrittenUrl = null; $this->retriever->url = URL::getInstance()->viewUrl($view, $allParametersWithoutView); diff --git a/templates/default_save/debug.html b/templates/default_save/debug.html index 5f2d2965d..a00acf9d3 100755 --- a/templates/default_save/debug.html +++ b/templates/default_save/debug.html @@ -1,5 +1,8 @@ -{*loop type="product" name="fsdq"} - {format_date date=$CREATE_DATE} -{/loop*} +

    Category page

    -::{product attr="createdAt" output="time" format='i'};;
    \ No newline at end of file +{loop type="category" name="categoryloop" id="500"} + TOTO +{/loop} + +{pageloop rel="categoryloop"} +{/pageloop} \ No newline at end of file diff --git a/templates/default_save/index.html b/templates/default_save/index.html index 53834febf..7ca21bccb 100755 --- a/templates/default_save/index.html +++ b/templates/default_save/index.html @@ -1,6 +1,8 @@ {include file="includes/header.html"}
    + Here you are : {navigate to="current"} + {loop type="auth" name="auth_test" context="front" roles="CUSTOMER"}

    Customer is authentified :-)

    From bad8a0439d72b7c15bfa2cbf9280736442a55ae7 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Thu, 12 Sep 2013 17:28:02 +0200 Subject: [PATCH 32/45] fix test suite --- .../Exception/NotFountHttpException.php | 46 +++++++++++++++++++ core/lib/Thelia/Model/Address.php | 14 ++---- core/lib/Thelia/Tests/Action/CustomerTest.php | 2 + 3 files changed, 52 insertions(+), 10 deletions(-) create mode 100644 core/lib/Thelia/Core/HttpKernel/Exception/NotFountHttpException.php diff --git a/core/lib/Thelia/Core/HttpKernel/Exception/NotFountHttpException.php b/core/lib/Thelia/Core/HttpKernel/Exception/NotFountHttpException.php new file mode 100644 index 000000000..a52f0eb86 --- /dev/null +++ b/core/lib/Thelia/Core/HttpKernel/Exception/NotFountHttpException.php @@ -0,0 +1,46 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Core\HttpKernel\Exceptions; + +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException as BaseNotFountHttpException; +/** + * Class NotFountHttpException + * @author Manuel Raynaud + */ +class NotFountHttpException extends BaseNotFountHttpException { + + protected $adminContext = false; + + public function __construct($message = null, \Exception $previous = null, $code = 0, $adminContext = false) + { + $this->adminContext = $adminContext; + + parent::__construct($message, $previous, $code); + } + + public function isAdminContext() + { + return $this->adminContext === true; + + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Model/Address.php b/core/lib/Thelia/Model/Address.php index 5ce697e8f..dbd334ba2 100755 --- a/core/lib/Thelia/Model/Address.php +++ b/core/lib/Thelia/Model/Address.php @@ -58,6 +58,10 @@ class Address extends BaseAddress { */ public function preDelete(ConnectionInterface $con = null) { + if($this->getIsDefault()) { + return false; + } + $this->dispatchEvent(TheliaEvents::BEFORE_DELETEADDRESS, new AddressEvent($this)); return true; } @@ -71,14 +75,4 @@ class Address extends BaseAddress { $this->dispatchEvent(TheliaEvents::AFTER_DELETEADDRESS, new AddressEvent($this)); } - public function preSave() - { - $valid = true; - if($this->getIsDefault()) { - $valid = false; - } - - return $valid; - } - } diff --git a/core/lib/Thelia/Tests/Action/CustomerTest.php b/core/lib/Thelia/Tests/Action/CustomerTest.php index b70d39428..10ba01587 100644 --- a/core/lib/Thelia/Tests/Action/CustomerTest.php +++ b/core/lib/Thelia/Tests/Action/CustomerTest.php @@ -86,6 +86,8 @@ class CustomerTest extends \PHPUnit_Framework_TestCase $addressCreated = $customerCreated->getDefaultAddress(); + $this->assertInstanceOf("Thelia\Model\Address", $addressCreated); + $this->assertEquals($customerCreateEvent->getFirstname(), $addressCreated->getFirstname()); $this->assertEquals($customerCreateEvent->getLastname(), $addressCreated->getLastname()); $this->assertEquals($customerCreateEvent->getTitle(), $addressCreated->getTitleId()); From d1d9892ae8b851c42c1588c396c53765bd91e68c Mon Sep 17 00:00:00 2001 From: franck Date: Thu, 12 Sep 2013 22:10:51 +0200 Subject: [PATCH 33/45] absoluteUrl prevetn duplicate parameters in generated URL --- core/lib/Thelia/Tools/URL.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/lib/Thelia/Tools/URL.php b/core/lib/Thelia/Tools/URL.php index 05084c0c1..650cb9de1 100755 --- a/core/lib/Thelia/Tools/URL.php +++ b/core/lib/Thelia/Tools/URL.php @@ -140,8 +140,14 @@ class URL if (! is_null($parameters)) { foreach ($parameters as $name => $value) { + + // Remove this parameter from base URL to prevent duplicate parameters + $base = preg_replace('/([?&])'.$name.'=([^&])*(&|$)/', '$1', $base); + $queryString .= sprintf("%s=%s&", urlencode($name), urlencode($value)); } + + $base = rtrim($base, '&'); } $sepChar = strstr($base, '?') === false ? '?' : '&'; From 6a66a3f99ac0a10e5bdf6db8b752c0c02bdaa9fa Mon Sep 17 00:00:00 2001 From: franck Date: Fri, 13 Sep 2013 00:16:29 +0200 Subject: [PATCH 34/45] Fixed duplication parameter check regexp --- core/lib/Thelia/Tools/URL.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/lib/Thelia/Tools/URL.php b/core/lib/Thelia/Tools/URL.php index 650cb9de1..5dc6c20c9 100755 --- a/core/lib/Thelia/Tools/URL.php +++ b/core/lib/Thelia/Tools/URL.php @@ -146,8 +146,6 @@ class URL $queryString .= sprintf("%s=%s&", urlencode($name), urlencode($value)); } - - $base = rtrim($base, '&'); } $sepChar = strstr($base, '?') === false ? '?' : '&'; From 316043d93a9e9231a31280112560814bb7a9f527 Mon Sep 17 00:00:00 2001 From: franck Date: Fri, 13 Sep 2013 00:18:19 +0200 Subject: [PATCH 35/45] Fixed action column alignment --- .../default/assets/less/thelia/tables.less | 7 +++ templates/admin/default/attribute-edit.html | 22 ++++--- templates/admin/default/attributes.html | 62 ++++++++++++++++++- templates/admin/default/categories.html | 2 +- templates/admin/default/currencies.html | 2 +- templates/admin/default/customers.html | 24 +++---- .../default/includes/inner-form-toolbar.html | 2 +- .../standard-description-form-fields.html | 8 +-- .../default/includes/thelia_news_feed.html | 3 +- templates/admin/default/orders.html | 14 ++--- 10 files changed, 111 insertions(+), 35 deletions(-) diff --git a/templates/admin/default/assets/less/thelia/tables.less b/templates/admin/default/assets/less/thelia/tables.less index d8b3a9e4e..5997840a8 100755 --- a/templates/admin/default/assets/less/thelia/tables.less +++ b/templates/admin/default/assets/less/thelia/tables.less @@ -55,6 +55,13 @@ .table-left-aligned { th, td { text-align: left; + + &.text-center { + text-align: center; + } + &.text-right { + text-align: right; + } } select, textarea, input[type="text"], input[type="password"], input[type="datetime"], input[type="datetime-local"], input[type="date"], input[type="month"], input[type="time"], input[type="week"], input[type="number"], input[type="email"], input[type="url"], input[type="search"], input[type="tel"], input[type="color"], .uneditable-input { diff --git a/templates/admin/default/attribute-edit.html b/templates/admin/default/attribute-edit.html index 1b290f222..882edd60c 100644 --- a/templates/admin/default/attribute-edit.html +++ b/templates/admin/default/attribute-edit.html @@ -37,6 +37,10 @@

    {intl l='Attribute information'}

    + {form_field form=$form field='id'} + + {/form_field} + {* Be sure to get the attribute ID, even if the form could not be validated *} @@ -52,7 +56,7 @@ {if $form_error}
    {$form_error_message}
    {/if} - {include file="includes/standard-description-form-fields.html"} + {include file="includes/standard-description-form-fields.html" form=$form}
    @@ -79,9 +83,10 @@ {admin_sortable_header - current_order=$order + current_order=$attributeav_order order='id' reverse_order='id_reverse' + request_parameter_name='attributeav_order' path={url path='/admin/configuration/attributes/update' attribute_id=$attribute_id} label="{intl l='ID'}" } @@ -89,9 +94,10 @@ {admin_sortable_header - current_order=$order + current_order=$attributeav_order order='alpha' reverse_order='alpha_reverse' + request_parameter_name='attributeav_order' path={url path='/admin/configuration/attributes/update' attribute_id=$attribute_id} label="{intl l='Value'}" } @@ -99,9 +105,10 @@ {admin_sortable_header - current_order=$order + current_order=$attributeav_order order='manual' reverse_order='manual_reverse' + request_parameter_name='attributeav_order' path={url path='/admin/configuration/attributes/update' attribute_id=$attribute_id} label="{intl l="Position"}" } @@ -114,12 +121,13 @@ - {loop name="list" type="attribute_availability" attribute=$attribute_id backend_context="1" lang=$edit_language_id order=$order} + {loop name="list" type="attribute_availability" attribute=$attribute_id backend_context="1" lang=$edit_language_id order=$attributeav_order} {$ID} - + {* FIXME : integrate this in the encolsing form to provide standard form processing *} + @@ -151,7 +159,7 @@
    - {intl l="No product attribute has been created yet. Click the + button to create one."} + {intl l="No value has been created yet. Click the + button to create one."}
    diff --git a/templates/admin/default/attributes.html b/templates/admin/default/attributes.html index eab4996ac..57fd9c256 100644 --- a/templates/admin/default/attributes.html +++ b/templates/admin/default/attributes.html @@ -97,6 +97,17 @@ {module_include location='attributes_table_row'} + {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.attributes.change"} + + {/loop} +
    {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.attributes.change"} @@ -213,10 +224,51 @@ dialog_title = {intl l="Delete attribute"} dialog_message = {intl l="Do you really want to delete this attribute ? It will be removed from all product templates."} - form_action = {url path='/admin/configuration/attributes/delete'} + form_action = {url path='/admin/configuration/attributes/remove_from-all-templates' attribute_id=$ID} form_content = {$smarty.capture.delete_dialog nofilter} } + +{* Add to all dialog *} + +{capture "add_to_all_dialog"} + + + {module_include location='attribute_add_to_all_form'} + +{/capture} + +{include + file = "includes/generic-confirm-dialog.html" + + dialog_id = "add_to_all_dialog" + dialog_title = {intl l="Add to all product templates"} + dialog_message = {intl l="Do you really want to add this attribute to all product templates ?"} + + form_action = {url path='/admin/configuration/attributes/add-to-all-templates'} + form_content = {$smarty.capture.add_to_all_dialog nofilter} +} + +{* Remove from all dialog *} + +{capture "remove_from_all_dialog"} + + + {module_include location='attribute_add_to_all_form'} + +{/capture} + +{include + file = "includes/generic-confirm-dialog.html" + + dialog_id = "remove_from_all_dialog" + dialog_title = {intl l="Remove from all product templates"} + dialog_message = {intl l="Do you really want to remove this attribute from all product templates ? You'll loose all product related data for this attribute."} + + form_action = {url path='/admin/configuration/attributes/remove-from-all-templates'} + form_content = {$smarty.capture.remove_from_all_dialog nofilter} +} + {/block} {block name="javascript-initialization"} @@ -233,6 +285,14 @@ $('#attribute_delete_id').val($(this).data('id')); }); + $('a.attribute-add-to-all').click(function(ev) { + $('#attribute_add_to_all_id').val($(this).data('id')); + }); + + $('a.attribute-remove-from-all').click(function(ev) { + $('#attribute_remove_from_all_id').val($(this).data('id')); + }); + // JS stuff for creation form {include file = "includes/generic-js-dialog.html" diff --git a/templates/admin/default/categories.html b/templates/admin/default/categories.html index 0423bcc66..6fe06f8bc 100755 --- a/templates/admin/default/categories.html +++ b/templates/admin/default/categories.html @@ -82,7 +82,7 @@ } - {intl l='Actions'} + {intl l='Actions'} diff --git a/templates/admin/default/currencies.html b/templates/admin/default/currencies.html index 72bf01e75..fe4cfe882 100644 --- a/templates/admin/default/currencies.html +++ b/templates/admin/default/currencies.html @@ -111,7 +111,7 @@ {module_include location='currencies_table_header'} - {intl l='Actions'} + {intl l='Actions'} diff --git a/templates/admin/default/customers.html b/templates/admin/default/customers.html index 799115bf3..72179f667 100644 --- a/templates/admin/default/customers.html +++ b/templates/admin/default/customers.html @@ -11,9 +11,9 @@
    - + @@ -58,7 +58,7 @@ {intl l='order amount'} - {intl l='Actions'} + {intl l='Actions'} @@ -154,23 +154,23 @@ {* on success, redirect to the edition page, _ID_ is replaced with the created object ID, see controller *} {/form_field} - + {form_field form=$form field='company'}
    {/form_field} - - {form_field form=$form field='title'} + + {form_field form=$form field='title'}
    - + +
    {/form_field} @@ -191,13 +191,13 @@ {form_field form=$form field='address1'}
    - +
    {form_field form=$form field='address2'} - {/form_field} + {/form_field}
    @@ -237,8 +237,8 @@
    - {/form_field} - + {/form_field} + {/capture} {include diff --git a/templates/admin/default/includes/inner-form-toolbar.html b/templates/admin/default/includes/inner-form-toolbar.html index 518c204e3..c142cbdd7 100755 --- a/templates/admin/default/includes/inner-form-toolbar.html +++ b/templates/admin/default/includes/inner-form-toolbar.html @@ -12,7 +12,7 @@
    {/form_field} @@ -25,7 +25,7 @@ {intl l="The détailed description."} - +
    {/form_field} @@ -36,6 +36,6 @@ {intl l="A short post-description information"} - +
    {/form_field} \ No newline at end of file diff --git a/templates/admin/default/includes/thelia_news_feed.html b/templates/admin/default/includes/thelia_news_feed.html index 6b9d2b5a9..09b3af020 100755 --- a/templates/admin/default/includes/thelia_news_feed.html +++ b/templates/admin/default/includes/thelia_news_feed.html @@ -4,7 +4,8 @@

    {$DATE}

    {$TITLE|strip_tags nofilter}

    -

    {$DESCRIPTION|strip_tags|truncate:250:"...":true nofilter}

    + {* we use unescape:"htmlall" to unescape var before truncate, to prevent a cut in the middel of an HTML entity, eg &ea... *} +

    {$DESCRIPTION|strip_tags|unescape:"htmlall"|truncate:250:"...":true nofilter}

    {intl l='Lire la suite »'}

    {/loop} diff --git a/templates/admin/default/orders.html b/templates/admin/default/orders.html index 947c615a3..4f9c6ecf8 100644 --- a/templates/admin/default/orders.html +++ b/templates/admin/default/orders.html @@ -17,7 +17,7 @@ {module_include location='orders_top'}
    -
    +
    - + {module_include location='orders_table_header'} - + - + @@ -116,7 +116,7 @@ - + - +
    @@ -36,14 +36,14 @@
    {intl l="Name"} {intl l="Amount"} {intl l="Status"}{intl l="Actions"}{intl l="Actions"}
    01230450123045
    -
    +
    From ca7d1f7c85de546fb754ac97b95070d4bd26d613 Mon Sep 17 00:00:00 2001 From: franck Date: Fri, 13 Sep 2013 00:19:53 +0200 Subject: [PATCH 36/45] Finished attributes management --- core/lib/Thelia/Action/Attribute.php | 24 +++ .../Thelia/Config/Resources/routing/admin.xml | 8 + .../Admin/AbstractCrudController.php | 74 +++++--- .../Admin/AttributeAvController.php | 60 +++--- .../Controller/Admin/AttributeController.php | 171 +++++++++++++++--- .../Controller/Admin/BaseAdminController.php | 33 +++- .../Controller/Admin/ConfigController.php | 1 + .../Controller/Admin/CurrencyController.php | 1 + .../Controller/Admin/MessageController.php | 52 ++++-- core/lib/Thelia/Core/Event/TheliaEvents.php | 3 + .../Template/Loop/AttributeAvailability.php | 8 +- .../Smarty/Plugins/AdminUtilities.php | 5 +- .../Core/Template/Smarty/Plugins/Form.php | 80 +++++--- .../Template/Smarty/Plugins/UrlGenerator.php | 1 + .../Thelia/Form/AttributeModificationForm.php | 2 + 15 files changed, 406 insertions(+), 117 deletions(-) diff --git a/core/lib/Thelia/Action/Attribute.php b/core/lib/Thelia/Action/Attribute.php index 8524f6054..2877ca388 100644 --- a/core/lib/Thelia/Action/Attribute.php +++ b/core/lib/Thelia/Action/Attribute.php @@ -37,6 +37,8 @@ use Thelia\Model\ConfigQuery; use Thelia\Model\AttributeAv; use Thelia\Model\AttributeAvQuery; use Thelia\Core\Event\UpdatePositionEvent; +use Thelia\Core\Event\CategoryEvent; +use Thelia\Core\Event\AttributeEvent; class Attribute extends BaseAction implements EventSubscriberInterface { @@ -133,6 +135,24 @@ class Attribute extends BaseAction implements EventSubscriberInterface } } + public function addToAllTemplates(AttributeEvent $event) + { + $templates = ProductTemplateAttributeQuery::create()->find(); + + foreach($templates as $template) { + $pat = new ProductTemplateAttribute(); + + $pat->setTemplate($template->getId()) + ->setAttributeId($event->getAttribute()->getId()) + ->save(); + } + } + + public function removeFromAllTemplates(AttributeEvent $event) + { + // Delete this attribute from all product templates + ProductTemplateAttributeQuery::create()->filterByAttributeId($event->getAttribute()->getId())->delete(); + } /** * {@inheritDoc} @@ -144,6 +164,10 @@ class Attribute extends BaseAction implements EventSubscriberInterface TheliaEvents::ATTRIBUTE_UPDATE => array("update", 128), TheliaEvents::ATTRIBUTE_DELETE => array("delete", 128), TheliaEvents::ATTRIBUTE_UPDATE_POSITION => array("updatePosition", 128), + + TheliaEvents::ATTRIBUTE_REMOVE_FROM_ALL_TEMPLATES => array("removeFromAllTemplates", 128), + TheliaEvents::ATTRIBUTE_ADD_TO_ALL_TEMPLATES => array("addToAllTemplates", 128), + ); } } \ No newline at end of file diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index c76e70eda..c16ee05bd 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -236,6 +236,14 @@ Thelia\Controller\Admin\AttributeController::updatePositionAction + + Thelia\Controller\Admin\AttributeController::removeFromAllTemplates + + + + Thelia\Controller\Admin\AttributeController::addToAllTemplates + + Thelia\Controller\Admin\AttributeAvController::createAction diff --git a/core/lib/Thelia/Controller/Admin/AbstractCrudController.php b/core/lib/Thelia/Controller/Admin/AbstractCrudController.php index 1dcbca01f..31f9ba72a 100644 --- a/core/lib/Thelia/Controller/Admin/AbstractCrudController.php +++ b/core/lib/Thelia/Controller/Admin/AbstractCrudController.php @@ -38,6 +38,7 @@ abstract class AbstractCrudController extends BaseAdminController // List ordering protected $defaultListOrder; + protected $orderRequestParameterName; // Permissions protected $viewPermissionIdentifier; @@ -74,6 +75,7 @@ abstract class AbstractCrudController extends BaseAdminController $objectName, $defaultListOrder = null, + $orderRequestParameterName = null, $viewPermissionIdentifier, $createPermissionIdentifier, @@ -89,8 +91,9 @@ abstract class AbstractCrudController extends BaseAdminController $this->objectName = $objectName; $this->defaultListOrder = $defaultListOrder; + $this->orderRequestParameterName = $orderRequestParameterName; - $this->viewPermissionIdentifier = $viewPermissionIdentifier; + $this->viewPermissionIdentifier = $viewPermissionIdentifier; $this->createPermissionIdentifier = $createPermissionIdentifier; $this->updatePermissionIdentifier = $updatePermissionIdentifier; $this->deletePermissionIdentifier = $deletePermissionIdentifier; @@ -194,36 +197,56 @@ abstract class AbstractCrudController extends BaseAdminController protected abstract function redirectToListTemplate(); - protected function createUpdatePositionEvent($positionChangeMode, $positionValue) { + protected function createUpdatePositionEvent($positionChangeMode, $positionValue) + { throw new \LogicException ("Position Update is not supported for this object"); } - protected function createToggleVisibilityEvent() { - + protected function createToggleVisibilityEvent() + { throw new \LogicException ("Toggle Visibility is not supported for this object"); } + /** + * Put in this method post object creation processing if required. + * + * @param unknown $createdObject the created object + */ + protected function performAdditionalCreateAction($createdObject) + { + // Nothing to do + } + + /** + * Put in this method post object update processing if required. + * + * @param unknown $updatedObject the updated object + */ + protected function performAdditionalUpdateAction($updatedObject) + { + // Nothing to do + } + + /** + * Put in this method post object delete processing if required. + * + * @param unknown $deletedObject the deleted object + */ + protected function performAdditionalDeleteAction($deletedObject) + { + // Nothing to do + } + /** * Return the current list order identifier, updating it in the same time. */ - protected function getCurrentListOrder($update_session = true) { - - $order = null; - - if ($this->defaultListOrder) { - - $orderSessionIdentifier = sprintf("admin.%s.currentListOrder", $this->objectName); - - // Find the current order - $order = $this->getRequest()->get( - 'order', - $this->getSession()->get($orderSessionIdentifier, $this->defaultListOrder) - ); - - if ($update_session) $this->getSession()->set($orderSessionIdentifier, $order); - } - - return $order; + protected function getCurrentListOrder($update_session = true) + { + return $this->getListOrderFromSession( + $this->objectName, + $this->orderRequestParameterName, + $this->defaultListOrder + ); } /** @@ -283,6 +306,8 @@ abstract class AbstractCrudController extends BaseAdminController $this->adminLogAppend(sprintf("%s %s (ID %s) created", ucfirst($this->objectName), $this->getObjectLabel($createdObject), $this->getObjectId($createdObject))); } + $this->performAdditionalCreateAction($createdObject); + // Substitute _ID_ in the URL with the ID of the created object $successUrl = str_replace('_ID_', $this->getObjectId($createdObject), $creationForm->getSuccessUrl()); @@ -317,7 +342,7 @@ abstract class AbstractCrudController extends BaseAdminController if (null !== $response = $this->checkAuth($this->updatePermissionIdentifier)) return $response; // Load the object - $object = $this->getExistingObject($this->getRequest()); + $object = $this->getExistingObject(); if ($object != null) { @@ -368,6 +393,8 @@ abstract class AbstractCrudController extends BaseAdminController $this->adminLogAppend(sprintf("%s %s (ID %s) modified", ucfirst($this->objectName), $this->getObjectLabel($changedObject), $this->getObjectId($changedObject))); } + $this->performAdditionalUpdateAction($changedObject); + // If we have to stay on the same page, do not redirect to the succesUrl, // just redirect to the edit page again. if ($this->getRequest()->get('save_mode') == 'stay') { @@ -467,6 +494,7 @@ abstract class AbstractCrudController extends BaseAdminController $this->adminLogAppend( sprintf("%s %s (ID %s) deleted", ucfirst($this->objectName), $this->getObjectLabel($deletedObject), $this->getObjectId($deletedObject))); } + $this->performAdditionalDeleteAction($deletedObject); $this->redirectToListTemplate(); } diff --git a/core/lib/Thelia/Controller/Admin/AttributeAvController.php b/core/lib/Thelia/Controller/Admin/AttributeAvController.php index b7118b53a..b3afa687d 100644 --- a/core/lib/Thelia/Controller/Admin/AttributeAvController.php +++ b/core/lib/Thelia/Controller/Admin/AttributeAvController.php @@ -39,10 +39,12 @@ use Thelia\Core\Event\UpdatePositionEvent; */ class AttributeAvController extends AbstractCrudController { - public function __construct() { + public function __construct() + { parent::__construct( - 'attribute', + 'attributeav', 'manual', + 'order', 'admin.configuration.attributes-av.view', 'admin.configuration.attributes-av.create', @@ -57,15 +59,18 @@ class AttributeAvController extends AbstractCrudController ); } - protected function getCreationForm() { + protected function getCreationForm() + { return new AttributeAvCreationForm($this->getRequest()); } - protected function getUpdateForm() { + protected function getUpdateForm() + { return new AttributeAvModificationForm($this->getRequest()); } - protected function getCreationEvent($formData) { + protected function getCreationEvent($formData) + { $createEvent = new AttributeAvCreateEvent(); $createEvent @@ -77,8 +82,8 @@ class AttributeAvController extends AbstractCrudController return $createEvent; } - protected function getUpdateEvent($formData) { - + protected function getUpdateEvent($formData) + { $changeEvent = new AttributeAvUpdateEvent($formData['id']); // Create and dispatch the change event @@ -93,8 +98,8 @@ class AttributeAvController extends AbstractCrudController return $changeEvent; } - protected function createUpdatePositionEvent($positionChangeMode, $positionValue) { - + protected function createUpdatePositionEvent($positionChangeMode, $positionValue) + { return new UpdatePositionEvent( $this->getRequest()->get('attributeav_id', null), $positionChangeMode, @@ -102,16 +107,18 @@ class AttributeAvController extends AbstractCrudController ); } - protected function getDeleteEvent() { + protected function getDeleteEvent() + { return new AttributeAvDeleteEvent($this->getRequest()->get('attributeav_id')); } - protected function eventContainsObject($event) { + protected function eventContainsObject($event) + { return $event->hasAttributeAv(); } - protected function hydrateObjectForm($object) { - + protected function hydrateObjectForm($object) + { $data = array( 'id' => $object->getId(), 'locale' => $object->getLocale(), @@ -125,32 +132,38 @@ class AttributeAvController extends AbstractCrudController return new AttributeAvModificationForm($this->getRequest(), "form", $data); } - protected function getObjectFromEvent($event) { + protected function getObjectFromEvent($event) + { return $event->hasAttributeAv() ? $event->getAttributeAv() : null; } - protected function getExistingObject() { + protected function getExistingObject() + { return AttributeAvQuery::create() ->joinWithI18n($this->getCurrentEditionLocale()) ->findOneById($this->getRequest()->get('attributeav_id')); } - protected function getObjectLabel($object) { + protected function getObjectLabel($object) + { return $object->getTitle(); } - protected function getObjectId($object) { + protected function getObjectId($object) + { return $object->getId(); } - protected function getViewArguments() { + protected function getViewArguments() + { return array( 'attribute_id' => $this->getRequest()->get('attribute_id'), 'order' => $this->getCurrentListOrder() ); } - protected function renderListTemplate($currentOrder) { + protected function renderListTemplate($currentOrder) + { // We always return to the attribute edition form return $this->render( 'attribute-edit', @@ -158,12 +171,14 @@ class AttributeAvController extends AbstractCrudController ); } - protected function renderEditionTemplate() { + protected function renderEditionTemplate() + { // We always return to the attribute edition form return $this->render('attribute-edit', $this->getViewArguments()); } - protected function redirectToEditionTemplate() { + protected function redirectToEditionTemplate() + { // We always return to the attribute edition form $this->redirectToRoute( "admin.configuration.attributes.update", @@ -171,7 +186,8 @@ class AttributeAvController extends AbstractCrudController ); } - protected function redirectToListTemplate() { + protected function redirectToListTemplate() + { $this->redirectToRoute( "admin.configuration.attributes.update", $this->getViewArguments() diff --git a/core/lib/Thelia/Controller/Admin/AttributeController.php b/core/lib/Thelia/Controller/Admin/AttributeController.php index f6b76c0df..0ae181900 100644 --- a/core/lib/Thelia/Controller/Admin/AttributeController.php +++ b/core/lib/Thelia/Controller/Admin/AttributeController.php @@ -31,6 +31,10 @@ use Thelia\Model\AttributeQuery; use Thelia\Form\AttributeModificationForm; use Thelia\Form\AttributeCreationForm; use Thelia\Core\Event\UpdatePositionEvent; +use Thelia\Model\AttributeAv; +use Thelia\Model\AttributeAvQuery; +use Thelia\Core\Event\AttributeAvUpdateEvent; +use Thelia\Core\Event\AttributeEvent; /** * Manages attributes sent by mail @@ -39,10 +43,12 @@ use Thelia\Core\Event\UpdatePositionEvent; */ class AttributeController extends AbstractCrudController { - public function __construct() { + public function __construct() + { parent::__construct( 'attribute', 'manual', + 'order', 'admin.configuration.attributes.view', 'admin.configuration.attributes.create', @@ -57,15 +63,18 @@ class AttributeController extends AbstractCrudController ); } - protected function getCreationForm() { + protected function getCreationForm() + { return new AttributeCreationForm($this->getRequest()); } - protected function getUpdateForm() { + protected function getUpdateForm() + { return new AttributeModificationForm($this->getRequest()); } - protected function getCreationEvent($formData) { + protected function getCreationEvent($formData) + { $createEvent = new AttributeCreateEvent(); $createEvent @@ -77,8 +86,8 @@ class AttributeController extends AbstractCrudController return $createEvent; } - protected function getUpdateEvent($formData) { - + protected function getUpdateEvent($formData) + { $changeEvent = new AttributeUpdateEvent($formData['id']); // Create and dispatch the change event @@ -93,8 +102,31 @@ class AttributeController extends AbstractCrudController return $changeEvent; } - protected function createUpdatePositionEvent($positionChangeMode, $positionValue) { + /** + * Process the attributes values (fix it in future version to integrate it in the attribute form as a collection) + * + * @see \Thelia\Controller\Admin\AbstractCrudController::performAdditionalUpdateAction() + */ + protected function performAdditionalUpdateAction($updatedObject) + { + $attr_values = $this->getRequest()->get('attribute_values', null); + if ($attr_values !== null) { + + foreach($attr_values as $id => $value) { + + $event = new AttributeAvUpdateEvent($id); + + $event->setTitle($value); + $event->setLocale($this->getCurrentEditionLocale()); + + $this->dispatch(TheliaEvents::ATTRIBUTE_AV_UPDATE, $event); + } + } + } + + protected function createUpdatePositionEvent($positionChangeMode, $positionValue) + { return new UpdatePositionEvent( $this->getRequest()->get('attribute_id', null), $positionChangeMode, @@ -102,15 +134,18 @@ class AttributeController extends AbstractCrudController ); } - protected function getDeleteEvent() { + protected function getDeleteEvent() + { return new AttributeDeleteEvent($this->getRequest()->get('attribute_id')); } - protected function eventContainsObject($event) { + protected function eventContainsObject($event) + { return $event->hasAttribute(); } - protected function hydrateObjectForm($object) { + protected function hydrateObjectForm($object) + { $data = array( 'id' => $object->getId(), @@ -121,44 +156,132 @@ class AttributeController extends AbstractCrudController 'postscriptum' => $object->getPostscriptum() ); + // Setup attributes values + /* + * FIXME : doesn't work. "We get a This form should not contain extra fields." error + $attr_av_list = AttributeAvQuery::create() + ->joinWithI18n($this->getCurrentEditionLocale()) + ->filterByAttributeId($object->getId()) + ->find(); + + $attr_array = array(); + + foreach($attr_av_list as $attr_av) { + $attr_array[$attr_av->getId()] = $attr_av->getTitle(); + } + + $data['attribute_values'] = $attr_array; + */ + // Setup the object form return new AttributeModificationForm($this->getRequest(), "form", $data); } - protected function getObjectFromEvent($event) { + protected function getObjectFromEvent($event) + { return $event->hasAttribute() ? $event->getAttribute() : null; } - protected function getExistingObject() { + protected function getExistingObject() + { return AttributeQuery::create() ->joinWithI18n($this->getCurrentEditionLocale()) ->findOneById($this->getRequest()->get('attribute_id')); } - protected function getObjectLabel($object) { + protected function getObjectLabel($object) + { return $object->getTitle(); } - protected function getObjectId($object) { + protected function getObjectId($object) + { return $object->getId(); } - protected function renderListTemplate($currentOrder) { + protected function renderListTemplate($currentOrder) + { return $this->render('attributes', array('order' => $currentOrder)); } - protected function renderEditionTemplate() { - return $this->render('attribute-edit', array('attribute_id' => $this->getRequest()->get('attribute_id'))); - } - - protected function redirectToEditionTemplate() { - $this->redirectToRoute( - "admin.configuration.attributes.update", - array('attribute_id' => $this->getRequest()->get('attribute_id')) + protected function renderEditionTemplate() + { + return $this->render( + 'attribute-edit', + array( + 'attribute_id' => $this->getRequest()->get('attribute_id'), + 'attributeav_order' => $this->getAttributeAvListOrder() + ) ); } - protected function redirectToListTemplate() { + protected function redirectToEditionTemplate() + { + $this->redirectToRoute( + "admin.configuration.attributes.update", + array( + 'attribute_id' => $this->getRequest()->get('attribute_id'), + 'attributeav_order' => $this->getAttributeAvListOrder() + ) + ); + } + + protected function redirectToListTemplate() + { $this->redirectToRoute('admin.configuration.attributes.default'); } + + /** + * Get the Attribute value list order. + * + * @return string the current list order + */ + protected function getAttributeAvListOrder() + { + return $this->getListOrderFromSession( + 'attributeav', + 'attributeav_order', + 'manual' + ); + } + + /** + * Add or Remove from all product templates + */ + protected function addRemoveFromAllTemplates($eventType) + { + // Check current user authorization + if (null !== $response = $this->checkAuth("admin.configuration.attributes.update")) return $response; + + try { + if (null !== $object = $this->getExistingObject()) { + + $event = new AttributeEvent($object); + + $this->dispatch($eventType, $event); + } + } + catch (\Exception $ex) { + // Any error + return $this->errorPage($ex); + } + + $this->redirectToListTemplate(); + } + + /** + * Remove from all product templates + */ + public function removeFromAllTemplates() + { + return $this->addRemoveFromAllTemplates(TheliaEvents::ATTRIBUTE_REMOVE_FROM_ALL_TEMPLATES); + } + + /** + * Add to all product templates + */ + public function addToAllTemplates() + { + return $this->addRemoveFromAllTemplates(TheliaEvents::ATTRIBUTE_ADD_TO_ALL_TEMPLATES); + } } \ No newline at end of file diff --git a/core/lib/Thelia/Controller/Admin/BaseAdminController.php b/core/lib/Thelia/Controller/Admin/BaseAdminController.php index 4fb8bf31e..6471dda81 100755 --- a/core/lib/Thelia/Controller/Admin/BaseAdminController.php +++ b/core/lib/Thelia/Controller/Admin/BaseAdminController.php @@ -97,7 +97,7 @@ class BaseAdminController extends BaseController protected function errorPage($message) { if ($message instanceof \Exception) { - $message = sprintf($this->getTranslator()->trans("Sorry, an error occured: %msg"), array('msg' => $message->getMessage())); + $message = $this->getTranslator()->trans("Sorry, an error occured: %msg", array('%msg' => $message->getMessage())); } return $this->render('general_error', array( @@ -273,6 +273,35 @@ class BaseAdminController extends BaseController return $this->getCurrentEditionLang()->getLocale(); } + + /** + * Return the current list order identifier for a given object name, + * updating in using the current request. + * + * @param unknown $objectName the object name (e.g. 'attribute', 'message') + * @param unknown $requestParameterName the name of the request parameter that defines the list order + * @param unknown $defaultListOrder the default order to use, if none is defined + * @param string $updateSession if true, the session will be updated with the current order. + * + * @return String the current liste order. + */ + protected function getListOrderFromSession($objectName, $requestParameterName, $defaultListOrder, $updateSession = true) { + + $order = $defaultListOrder; + + $orderSessionIdentifier = sprintf("admin.%s.currentListOrder", $objectName); + + // Find the current order + $order = $this->getRequest()->get( + $requestParameterName, + $this->getSession()->get($orderSessionIdentifier, $defaultListOrder) + ); + + if ($updateSession) $this->getSession()->set($orderSessionIdentifier, $order); + + return $order; + } + /** * Render the given template, and returns the result as an Http Response. * @@ -314,7 +343,7 @@ class BaseAdminController extends BaseController 'edit_language_id' => $edition_language->getId(), 'edit_language_locale' => $edition_language->getLocale(), - 'current_url' => htmlspecialchars($this->getRequest()->getUri()) + 'current_url' => $this->getRequest()->getUri() )); // Update the current edition language in session diff --git a/core/lib/Thelia/Controller/Admin/ConfigController.php b/core/lib/Thelia/Controller/Admin/ConfigController.php index ee88e99e0..ff0e4bb39 100644 --- a/core/lib/Thelia/Controller/Admin/ConfigController.php +++ b/core/lib/Thelia/Controller/Admin/ConfigController.php @@ -43,6 +43,7 @@ class ConfigController extends AbstractCrudController parent::__construct( 'variable', 'name', + 'order', 'admin.configuration.variables.view', 'admin.configuration.variables.create', diff --git a/core/lib/Thelia/Controller/Admin/CurrencyController.php b/core/lib/Thelia/Controller/Admin/CurrencyController.php index 2df950984..4f3fdaaea 100644 --- a/core/lib/Thelia/Controller/Admin/CurrencyController.php +++ b/core/lib/Thelia/Controller/Admin/CurrencyController.php @@ -43,6 +43,7 @@ class CurrencyController extends AbstractCrudController parent::__construct( 'currency', 'manual', + 'order', 'admin.configuration.currencies.view', 'admin.configuration.currencies.create', diff --git a/core/lib/Thelia/Controller/Admin/MessageController.php b/core/lib/Thelia/Controller/Admin/MessageController.php index f87218116..a55c9deca 100644 --- a/core/lib/Thelia/Controller/Admin/MessageController.php +++ b/core/lib/Thelia/Controller/Admin/MessageController.php @@ -37,10 +37,12 @@ use Thelia\Form\MessageCreationForm; */ class MessageController extends AbstractCrudController { - public function __construct() { + public function __construct() + { parent::__construct( 'message', - null, + null, // no sort order change + null, // no sort order change 'admin.configuration.messages.view', 'admin.configuration.messages.create', @@ -55,15 +57,18 @@ class MessageController extends AbstractCrudController ); } - protected function getCreationForm() { + protected function getCreationForm() + { return new MessageCreationForm($this->getRequest()); } - protected function getUpdateForm() { + protected function getUpdateForm() + { return new MessageModificationForm($this->getRequest()); } - protected function getCreationEvent($formData) { + protected function getCreationEvent($formData) + { $createEvent = new MessageCreateEvent(); $createEvent @@ -76,7 +81,8 @@ class MessageController extends AbstractCrudController return $createEvent; } - protected function getUpdateEvent($formData) { + protected function getUpdateEvent($formData) + { $changeEvent = new MessageUpdateEvent($formData['id']); // Create and dispatch the change event @@ -93,16 +99,18 @@ class MessageController extends AbstractCrudController return $changeEvent; } - protected function getDeleteEvent() { + protected function getDeleteEvent() + { return new MessageDeleteEvent($this->getRequest()->get('message_id')); } - protected function eventContainsObject($event) { + protected function eventContainsObject($event) + { return $event->hasMessage(); } - protected function hydrateObjectForm($object) { - + protected function hydrateObjectForm($object) + { // Prepare the data that will hydrate the form $data = array( 'id' => $object->getId(), @@ -119,40 +127,48 @@ class MessageController extends AbstractCrudController return new MessageModificationForm($this->getRequest(), "form", $data); } - protected function getObjectFromEvent($event) { + protected function getObjectFromEvent($event) + { return $event->hasMessage() ? $event->getMessage() : null; } - protected function getExistingObject() { + protected function getExistingObject() + { return MessageQuery::create() ->joinWithI18n($this->getCurrentEditionLocale()) ->findOneById($this->getRequest()->get('message_id')); } - protected function getObjectLabel($object) { + protected function getObjectLabel($object) + { return $object->getName(); } - protected function getObjectId($object) { + protected function getObjectId($object) + { return $object->getId(); } - protected function renderListTemplate($currentOrder) { + protected function renderListTemplate($currentOrder) + { return $this->render('messages'); } - protected function renderEditionTemplate() { + protected function renderEditionTemplate() + { return $this->render('message-edit', array('message_id' => $this->getRequest()->get('message_id'))); } - protected function redirectToEditionTemplate() { + protected function redirectToEditionTemplate() + { $this->redirectToRoute( "admin.configuration.messages.update", array('message_id' => $this->getRequest()->get('message_id')) ); } - protected function redirectToListTemplate() { + protected function redirectToListTemplate() + { $this->redirectToRoute('admin.configuration.messages.default'); } } diff --git a/core/lib/Thelia/Core/Event/TheliaEvents.php b/core/lib/Thelia/Core/Event/TheliaEvents.php index 78d84b758..97e140eb6 100755 --- a/core/lib/Thelia/Core/Event/TheliaEvents.php +++ b/core/lib/Thelia/Core/Event/TheliaEvents.php @@ -369,6 +369,9 @@ final class TheliaEvents const ATTRIBUTE_DELETE = "action.deleteAttribute"; const ATTRIBUTE_UPDATE_POSITION = "action.updateAttributePosition"; + const ATTRIBUTE_REMOVE_FROM_ALL_TEMPLATES = "action.addAttributeToAllTemplate"; + const ATTRIBUTE_ADD_TO_ALL_TEMPLATES = "action.removeAttributeFromAllTemplate"; + const BEFORE_CREATEATTRIBUTE = "action.before_createAttribute"; const AFTER_CREATEATTRIBUTE = "action.after_createAttribute"; diff --git a/core/lib/Thelia/Core/Template/Loop/AttributeAvailability.php b/core/lib/Thelia/Core/Template/Loop/AttributeAvailability.php index 1d94e889e..e9a7d9eb8 100755 --- a/core/lib/Thelia/Core/Template/Loop/AttributeAvailability.php +++ b/core/lib/Thelia/Core/Template/Loop/AttributeAvailability.php @@ -59,7 +59,7 @@ class AttributeAvailability extends BaseI18nLoop new Argument( 'order', new TypeCollection( - new Type\EnumListType(array('alpha', 'alpha_reverse', 'manual', 'manual_reverse')) + new Type\EnumListType(array('id', 'id_reverse', 'alpha', 'alpha_reverse', 'manual', 'manual_reverse')) ), 'manual' ) @@ -100,6 +100,12 @@ class AttributeAvailability extends BaseI18nLoop 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; diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/AdminUtilities.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/AdminUtilities.php index 5608fc168..a56bbff1c 100644 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/AdminUtilities.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/AdminUtilities.php @@ -106,6 +106,9 @@ class AdminUtilities extends AbstractSmartyPlugin // The column label $label = $this->getParam($params, 'label'); + // The request parameter + $request_parameter_name = $this->getParam($params, 'request_parameter_name', 'order'); + if ($current_order == $order) { $icon = 'up'; $order_change = $reverse_order; @@ -121,7 +124,7 @@ class AdminUtilities extends AbstractSmartyPlugin else $output = ''; - return sprintf('%s%s', $output, URL::getInstance()->absoluteUrl($path, array('order' => $order_change)), $label); + return sprintf('%s%s', $output, URL::getInstance()->absoluteUrl($path, array($request_parameter_name => $order_change)), $label); } /** diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php index 9ae840019..2d5324644 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php @@ -112,6 +112,37 @@ class Form extends AbstractSmartyPlugin } } + protected function assignFieldValues($template, $fieldName, $fieldValue, $fieldVars) + { + $template->assign("name", $fieldName); + + $template->assign("value", $fieldValue); + + // If Checkbox input type + if ($fieldVars['checked'] !== null) { + $this->renderFormFieldCheckBox($template, $formFieldView['checked']); + } + + $template->assign("label", $fieldVars["label"]); + $template->assign("label_attr", $fieldVars["label_attr"]); + + $errors = $fieldVars["errors"]; + + $template->assign("error", empty($errors) ? false : true); + + if (! empty($errors)) { + $this->assignFieldErrorVars($template, $errors); + } + + $attr = array(); + + foreach ($fieldVars["attr"] as $key => $value) { + $attr[] = sprintf('%s="%s"', $key, $value); + } + + $template->assign("attr", implode(" ", $attr)); + } + public function renderFormField($params, $content, \Smarty_Internal_Template $template, &$repeat) { if ($repeat) { @@ -120,32 +151,29 @@ class Form extends AbstractSmartyPlugin $template->assign("options", $formFieldView->vars); - $template->assign("name", $formFieldView->vars["full_name"]); - $template->assign("value", $formFieldView->vars["value"]); + $value = $formFieldView->vars["value"]; +/* FIXME: doesnt work. We got "This form should not contain extra fields." error. + // We have a collection + if (is_array($value)) { - // If Checkbox input type - if ($formFieldView->vars['checked'] !== null) { - $this->renderFormFieldCheckBox($template, $formFieldView); + $key = $this->getParam($params, 'value_key'); + + if ($key != null) { + + if (isset($value[$key])) { + + $name = sprintf("%s[%s]", $formFieldView->vars["full_name"], $key); + $val = $value[$key]; + + $this->assignFieldValues($template, $name, $val, $formFieldView->vars); + } + } } - - $template->assign("label", $formFieldView->vars["label"]); - $template->assign("label_attr", $formFieldView->vars["label_attr"]); - - $errors = $formFieldView->vars["errors"]; - - $template->assign("error", empty($errors) ? false : true); - - if (! empty($errors)) { - $this->assignFieldErrorVars($template, $errors); + else { + $this->assignFieldValues($template, $formFieldView->vars["full_name"], $fieldVars["value"], $formFieldView->vars); } - - $attr = array(); - - foreach ($formFieldView->vars["attr"] as $key => $value) { - $attr[] = sprintf('%s="%s"', $key, $value); - } - - $template->assign("attr", implode(" ", $attr)); +*/ + $this->assignFieldValues($template, $formFieldView->vars["full_name"], $formFieldView->vars["value"], $formFieldView->vars); $formFieldView->setRendered(); } else { @@ -275,12 +303,12 @@ class Form extends AbstractSmartyPlugin * @param \Smarty_Internal_Template $template * @param $formFieldView */ - public function renderFormFieldCheckBox(\Smarty_Internal_Template $template, $formFieldView) + public function renderFormFieldCheckBox(\Smarty_Internal_Template $template, $isChecked) { $template->assign("value", 0); - if ($formFieldView->vars['checked']) { + if ($isChecked) { $template->assign("value", 1); } - $template->assign("value", $formFieldView->vars['checked']); + $template->assign("value", $isChecked); } } diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/UrlGenerator.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/UrlGenerator.php index 905c5bb5b..56c853d00 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/UrlGenerator.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/UrlGenerator.php @@ -54,6 +54,7 @@ class UrlGenerator extends AbstractSmartyPlugin $url = URL::getInstance()->absoluteUrl($path, $this->getArgsFromParam($params, array('path', 'target'))); if ($target != null) $url .= '#'.$target; + return $url; } diff --git a/core/lib/Thelia/Form/AttributeModificationForm.php b/core/lib/Thelia/Form/AttributeModificationForm.php index 62b0b707a..45dab7b28 100644 --- a/core/lib/Thelia/Form/AttributeModificationForm.php +++ b/core/lib/Thelia/Form/AttributeModificationForm.php @@ -43,10 +43,12 @@ class AttributeModificationForm extends AttributeCreationForm ) ) )) +/* FIXME: doesn't work ->add('attribute_values', 'collection', array( 'type' => 'text', 'options' => array('required' => false) )) +*/ ; // Add standard description fields From 275b20ac7751e2330fc0816e45d51453a01a49b6 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Fri, 13 Sep 2013 10:17:45 +0200 Subject: [PATCH 37/45] allow to make an address as default on update action --- core/lib/Thelia/Action/Address.php | 4 ++++ .../Thelia/Config/Resources/routing/front.xml | 7 ++++++- .../Controller/Front/AddressController.php | 18 +++++++----------- .../Controller/Front/BaseFrontController.php | 7 +++++++ .../Core/Event/AddressCreateOrUpdateEvent.php | 18 +++++++++++++++++- core/lib/Thelia/Form/AddressCreateForm.php | 10 ++++++++-- core/lib/Thelia/Model/Address.php | 14 ++++++++++++++ templates/default/account.html | 3 ++- templates/default/register.html | 4 ++-- 9 files changed, 67 insertions(+), 18 deletions(-) diff --git a/core/lib/Thelia/Action/Address.php b/core/lib/Thelia/Action/Address.php index 278f71a5b..27d46a4b7 100644 --- a/core/lib/Thelia/Action/Address.php +++ b/core/lib/Thelia/Action/Address.php @@ -73,6 +73,10 @@ class Address extends BaseAction implements EventSubscriberInterface ->save() ; + if($event->getIsDefault()) { + $addressModel->makeItDefault(); + } + $event->setAddress($addressModel); } diff --git a/core/lib/Thelia/Config/Resources/routing/front.xml b/core/lib/Thelia/Config/Resources/routing/front.xml index c50fd97b9..c30e576b9 100755 --- a/core/lib/Thelia/Config/Resources/routing/front.xml +++ b/core/lib/Thelia/Config/Resources/routing/front.xml @@ -59,7 +59,12 @@ - + + Thelia\Controller\Front\DefaultController::noAction + address + + + Thelia\Controller\Front\AddressController::createAction address diff --git a/core/lib/Thelia/Controller/Front/AddressController.php b/core/lib/Thelia/Controller/Front/AddressController.php index 5f3fb4799..c4a40d951 100644 --- a/core/lib/Thelia/Controller/Front/AddressController.php +++ b/core/lib/Thelia/Controller/Front/AddressController.php @@ -46,14 +46,13 @@ class AddressController extends BaseFrontController */ public function generateModalAction($address_id) { - if ($this->getSecurityContext()->hasCustomerUser() === false) { - $this->accessDenied(); - } - + $this->checkAuth(); $this->checkXmlHttpRequest(); } + + /** * Create controller. * Check if customer is logged in @@ -62,9 +61,7 @@ class AddressController extends BaseFrontController */ public function createAction() { - if ($this->getSecurityContext()->hasCustomerUser() === false) { - $this->accessDenied() - } + $this->checkAuth(); $addressCreate = new AddressCreateForm($this->getRequest()); @@ -98,11 +95,9 @@ class AddressController extends BaseFrontController public function updateAction() { + $this->checkAuth(); $request = $this->getRequest(); - if ($this->getSecurityContext()->hasCustomerUser() === false) { - $this->redirectToRoute("home"); - } if (null === $address_id = $request->get("address_id")) { $this->redirectToRoute("home"); @@ -164,7 +159,8 @@ class AddressController extends BaseFrontController $form->get("country")->getData(), $form->get("cellphone")->getData(), $form->get("phone")->getData(), - $form->get("company")->getData() + $form->get("company")->getData(), + $form->get("is_default")->getData() ); } } diff --git a/core/lib/Thelia/Controller/Front/BaseFrontController.php b/core/lib/Thelia/Controller/Front/BaseFrontController.php index cf83e865d..1c4a13977 100755 --- a/core/lib/Thelia/Controller/Front/BaseFrontController.php +++ b/core/lib/Thelia/Controller/Front/BaseFrontController.php @@ -50,4 +50,11 @@ class BaseFrontController extends BaseController { $this->redirect(URL::getInstance()->absoluteUrl($this->getRoute($routeId, array(), $referenceType), $urlParameters)); } + + public function checkAuth() + { + if($this->getSecurityContext()->hasCustomerUser() === false) { + $this->redirectToRoute("customer.login.view"); + } + } } diff --git a/core/lib/Thelia/Core/Event/AddressCreateOrUpdateEvent.php b/core/lib/Thelia/Core/Event/AddressCreateOrUpdateEvent.php index af69ae0b4..01e615ff6 100644 --- a/core/lib/Thelia/Core/Event/AddressCreateOrUpdateEvent.php +++ b/core/lib/Thelia/Core/Event/AddressCreateOrUpdateEvent.php @@ -108,7 +108,12 @@ class AddressCreateOrUpdateEvent extends ActionEvent */ protected $address; - public function __construct($label, $title, $firstname, $lastname, $address1, $address2, $address3, $zipcode, $city, $country, $cellphone, $phone, $company) + /** + * @var int + */ + protected $isDefault; + + public function __construct($label, $title, $firstname, $lastname, $address1, $address2, $address3, $zipcode, $city, $country, $cellphone, $phone, $company, $isDefault = 0) { $this->address1 = $address1; $this->address2 = $address2; @@ -123,6 +128,7 @@ class AddressCreateOrUpdateEvent extends ActionEvent $this->phone = $phone; $this->title = $title; $this->zipcode = $zipcode; + $this->isDefault = $isDefault; } /** @@ -229,6 +235,16 @@ class AddressCreateOrUpdateEvent extends ActionEvent return $this->zipcode; } + /** + * @return int + */ + public function getIsDefault() + { + return $this->isDefault; + } + + + /** * @param \Thelia\Model\Customer $customer */ diff --git a/core/lib/Thelia/Form/AddressCreateForm.php b/core/lib/Thelia/Form/AddressCreateForm.php index ed1750047..483366a1f 100644 --- a/core/lib/Thelia/Form/AddressCreateForm.php +++ b/core/lib/Thelia/Form/AddressCreateForm.php @@ -60,7 +60,7 @@ class AddressCreateForm extends BaseForm "constraints" => array( new NotBlank() ), - "label" => Translator::getInstance()->trans("Address label *"), + "label" => Translator::getInstance()->trans("Address label"), "label_attr" => array( "for" => "label_create" ), @@ -154,11 +154,17 @@ class AddressCreateForm extends BaseForm ) )) ->add("company", "text", array( - "label" => Translator::getInstance()->trans("Compagny"), + "label" => Translator::getInstance()->trans("Company"), "label_attr" => array( "for" => "company_create" ) )) + ->add("is_default", "integer", array( + "label" => Translator::getInstance()->trans("Make this address has my primary address"), + "label_attr" => array( + "for" => "default_address" + ) + )) ; } diff --git a/core/lib/Thelia/Model/Address.php b/core/lib/Thelia/Model/Address.php index dbd334ba2..9c2a390b5 100755 --- a/core/lib/Thelia/Model/Address.php +++ b/core/lib/Thelia/Model/Address.php @@ -7,10 +7,24 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Thelia\Core\Event\AddressEvent; use Thelia\Core\Event\TheliaEvents; use Thelia\Model\Base\Address as BaseAddress; +use Thelia\Model\AddressQuery; class Address extends BaseAddress { use \Thelia\Model\Tools\ModelEventDispatcherTrait; + /** + * put the the current address as default one + */ + public function makeItDefault() + { + + AddressQuery::create()->filterByCustomerId($this->getCustomerId()) + ->update(array('isDefault' => '0')); + + $this->setIsDefault(1); + $this->save(); + } + /** * Code to be run before inserting to database * @param ConnectionInterface $con diff --git a/templates/default/account.html b/templates/default/account.html index c7edeb449..b67d6424c 100644 --- a/templates/default/account.html +++ b/templates/default/account.html @@ -1,3 +1,4 @@ +{check_auth context="front" roles="CUSTOMER" login_tpl="login"} {extends file="layout.tpl"} {block name="breadcrumb"} @@ -74,7 +75,7 @@
    - {intl l="Add a new address"} + {intl l="Add a new address"} {loop type="address" name="customer.addresses"} diff --git a/templates/default/register.html b/templates/default/register.html index 7100737bc..a3448932b 100644 --- a/templates/default/register.html +++ b/templates/default/register.html @@ -96,7 +96,7 @@
    - + {if $error } {$message} {elseif $value != "" && !$error} @@ -109,7 +109,7 @@
    - + {if $error } {$message} {elseif $value != "" && !$error} From 2d8656e45b0dea6aa8254285e8d601faa1556f16 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Fri, 13 Sep 2013 10:55:45 +0200 Subject: [PATCH 38/45] allow to create a new address --- core/lib/Thelia/Action/Address.php | 58 ++++--- core/lib/Thelia/Model/Address.php | 2 +- templates/default/address.html | 247 +++++++++++++++++++++++++++++ 3 files changed, 283 insertions(+), 24 deletions(-) create mode 100644 templates/default/address.html diff --git a/core/lib/Thelia/Action/Address.php b/core/lib/Thelia/Action/Address.php index 27d46a4b7..0aee9a6f5 100644 --- a/core/lib/Thelia/Action/Address.php +++ b/core/lib/Thelia/Action/Address.php @@ -22,10 +22,13 @@ /*************************************************************************************/ namespace Thelia\Action; +use Propel\Runtime\Exception\PropelException; +use Propel\Runtime\Propel; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Thelia\Core\Event\AddressCreateOrUpdateEvent; use Thelia\Core\Event\TheliaEvents; use Thelia\Model\Address as AddressModel; +use Thelia\Model\Map\AddressTableMap; /** * Class Address @@ -52,32 +55,41 @@ class Address extends BaseAction implements EventSubscriberInterface protected function createOrUpdate(AddressModel $addressModel, AddressCreateOrUpdateEvent $event) { $addressModel->setDispatcher($this->getDispatcher()); + $con = Propel::getWriteConnection(AddressTableMap::DATABASE_NAME); + $con->beginTransaction(); + try { + if ($addressModel->isNew()) { + $addressModel->setLabel($event->getLabel()); + } - if ($addressModel->isNew()) { - $addressModel->setLabel($event->getLabel()); + $addressModel + ->setTitleId($event->getTitle()) + ->setFirstname($event->getFirstname()) + ->setLastname($event->getLastname()) + ->setAddress1($event->getAddress1()) + ->setAddress2($event->getAddress2()) + ->setAddress3($event->getAddress3()) + ->setZipcode($event->getZipcode()) + ->setCity($event->getCity()) + ->setCountryId($event->getCountry()) + ->setCellphone($event->getCellphone()) + ->setPhone($event->getPhone()) + ->setCompany($event->getCompany()) + ->save() + ; + + if($event->getIsDefault()) { + $addressModel->makeItDefault(); + } + + $event->setAddress($addressModel); + $con->commit(); + + } catch(PropelException $e) { + $con->rollback(); + throw $e; } - $addressModel - ->setTitleId($event->getTitle()) - ->setFirstname($event->getFirstname()) - ->setLastname($event->getLastname()) - ->setAddress1($event->getAddress1()) - ->setAddress2($event->getAddress2()) - ->setAddress3($event->getAddress3()) - ->setZipcode($event->getZipcode()) - ->setCity($event->getCity()) - ->setCountryId($event->getCountry()) - ->setCellphone($event->getCellphone()) - ->setPhone($event->getPhone()) - ->setCompany($event->getCompany()) - ->save() - ; - - if($event->getIsDefault()) { - $addressModel->makeItDefault(); - } - - $event->setAddress($addressModel); } /** diff --git a/core/lib/Thelia/Model/Address.php b/core/lib/Thelia/Model/Address.php index 9c2a390b5..8c9bd4552 100755 --- a/core/lib/Thelia/Model/Address.php +++ b/core/lib/Thelia/Model/Address.php @@ -19,7 +19,7 @@ class Address extends BaseAddress { { AddressQuery::create()->filterByCustomerId($this->getCustomerId()) - ->update(array('isDefault' => '0')); + ->update(array('IsDefault' => '0')); $this->setIsDefault(1); $this->save(); diff --git a/templates/default/address.html b/templates/default/address.html new file mode 100644 index 000000000..086a2b5ba --- /dev/null +++ b/templates/default/address.html @@ -0,0 +1,247 @@ +{check_auth context="front" roles="CUSTOMER" login_tpl="login"} +{extends file="layout.tpl"} + +{block name="breadcrumb"} + +{/block} + +{block name="main-content"} +
    + +
    + +

    {intl l="Create New Address"}

    + {form name="thelia.address.create"} + + {form_field form=$form field='success_url'} + {* the url the user is redirected to on login success *} + {/form_field} + + {form_field form=$form field='error_message'} + {* the url the user is redirected to on login success *} + {/form_field} + {form_hidden_fields form=$form} + {if $form_error}
    {$form_error_message}
    {/if} +
    +
    + {intl l="Address"} +
    + +
    + {form_field form=$form field="label"} +
    + + +
    + + {if $error } + {$message} + {elseif $value != "" && !$error} + + {/if} +
    +
    + + {/form_field} + + {form_field form=$form field="title"} +
    + +
    + + {if $error } + {$message} + {elseif $value != "" && !$error} + + {/if} +
    +
    + {/form_field} + + {form_field form=$form field="firstname"} +
    + + +
    + + {if $error } + {$message} + {elseif $value != "" && !$error} + + {/if} +
    +
    + + {/form_field} + + + {form_field form=$form field="lastname"} +
    + + +
    + + {if $error } + {$message} + {elseif $value != "" && !$error} + + {/if} +
    +
    + + {/form_field} + + {form_field form=$form field="address1"} +
    + + +
    + + {if $error } + {$message} + {elseif $value != "" && !$error} + + {/if} +
    +
    + + {/form_field} + + {form_field form=$form field="address2"} +
    + + +
    + + {if $error } + {$message} + {elseif $value != "" && !$error} + + {/if} +
    +
    + + {/form_field} + + {form_field form=$form field="zipcode"} +
    + + +
    + + {if $error } + {$message} + {elseif $value != "" && !$error} + + {/if} +
    +
    + + {/form_field} + + {form_field form=$form field="city"} +
    + + +
    + + {if $error } + {$message} + {elseif $value != "" && !$error} + + {/if} +
    +
    + + {/form_field} + + {form_field form=$form field="country"} +
    + +
    + + {if $error } + {$message} + {elseif $value != "" && !$error} + + {/if} +
    +
    + {/form_field} + + {form_field form=$form field="phone"} +
    + + +
    + + {if $error } + {$message} + {elseif $value != "" && !$error} + + {/if} +
    +
    + + {/form_field} + + {form_field form=$form field="cellphone"} +
    + + +
    + + {if $error } + {$message} + {elseif $value != "" && !$error} + + {/if} +
    +
    + + {/form_field} +
    +
    + + {form_field form=$form field="is_default"} +
    +
    +
    + +
    +
    +
    + + {/form_field} + +
    +
    + +
    +
    + + + {/form} +
    + +
    +{/block} \ No newline at end of file From ddf175f361542c335ed84b109c1445403a099771 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Fri, 13 Sep 2013 11:31:12 +0200 Subject: [PATCH 39/45] allow update customer address in front tempalte --- .../Thelia/Config/Resources/routing/front.xml | 11 +- .../Controller/Front/AddressController.php | 26 +- templates/default/account.html | 2 +- templates/default/address-update.html | 250 ++++++++++++++++++ templates/default/address.html | 4 +- 5 files changed, 277 insertions(+), 16 deletions(-) create mode 100644 templates/default/address-update.html diff --git a/core/lib/Thelia/Config/Resources/routing/front.xml b/core/lib/Thelia/Config/Resources/routing/front.xml index c30e576b9..da3c1bdb7 100755 --- a/core/lib/Thelia/Config/Resources/routing/front.xml +++ b/core/lib/Thelia/Config/Resources/routing/front.xml @@ -69,13 +69,14 @@ address - - Thelia\Controller\Front\DefaultController::noAction - address-edit + + Thelia\Controller\Front\AddressController::updateViewAction + address-update - - Thelia\Controller\Front\AddressController::updateAction + + Thelia\Controller\Front\AddressController::processUpdateAction + address-update diff --git a/core/lib/Thelia/Controller/Front/AddressController.php b/core/lib/Thelia/Controller/Front/AddressController.php index c4a40d951..33fa67069 100644 --- a/core/lib/Thelia/Controller/Front/AddressController.php +++ b/core/lib/Thelia/Controller/Front/AddressController.php @@ -27,7 +27,7 @@ use Thelia\Core\Event\TheliaEvents; use Thelia\Form\AddressCreateForm; use Thelia\Form\AddressUpdateForm; use Thelia\Form\Exception\FormValidationException; -use Thelia\Model\Base\AddressQuery; +use Thelia\Model\AddressQuery; use Thelia\Model\Customer; use Thelia\Tools\URL; @@ -93,18 +93,28 @@ class AddressController extends BaseFrontController } } - public function updateAction() + public function updateViewAction($address_id) + { + $this->checkAuth(); + + $customer = $this->getSecurityContext()->getCustomerUser(); + $address = AddressQuery::create()->findPk($address_id); + + if(!$address || $customer->getId() != $address->getCustomerId()) { + $this->redirectToRoute("home"); + } + + $this->getParserContext()->set("address_id", $address_id); + } + + public function processUpdateAction($address_id) { $this->checkAuth(); $request = $this->getRequest(); - - if (null === $address_id = $request->get("address_id")) { - $this->redirectToRoute("home"); - } - $addressUpdate = new AddressUpdateForm($request); + try { $customer = $this->getSecurityContext()->getCustomerUser(); @@ -131,7 +141,7 @@ class AddressController extends BaseFrontController } catch (\Exception $e) { $message = sprintf("Sorry, an error occured: %s", $e->getMessage()); } - + $this->getParserContext()->set("address_id", $address_id); if ($message !== false) { \Thelia\Log\Tlog::getInstance()->error(sprintf("Error during address creation process : %s", $message)); diff --git a/templates/default/account.html b/templates/default/account.html index b67d6424c..f3815e5c0 100644 --- a/templates/default/account.html +++ b/templates/default/account.html @@ -114,7 +114,7 @@
    {/loop} + + + + + {/ifloop}
    @@ -110,34 +142,6 @@ {module_include location='customer_bottom'} -
    -
    - -
      - {if $customer_page != 1} -
    • «
    • - {else} -
    • «
    • - {/if} - - {pageloop rel="customer_list"} - {if $PAGE != $CURRENT} -
    • {$PAGE}
    • - - {else} -
    • {$PAGE}
    • - {/if} - - {if $PAGE == $LAST && $LAST != $CURRENT} -
    • »
    • - {else} -
    • »
    • - {/if} - {/pageloop} -
    - -
    -
    {* Adding a new Category *} From 8367863b489de325ec04794bd5aecf59b71e417e Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Fri, 13 Sep 2013 12:33:13 +0200 Subject: [PATCH 41/45] allow address removal from front --- core/lib/Thelia/Action/Address.php | 11 +++++- .../Thelia/Config/Resources/routing/front.xml | 5 +++ .../Controller/Front/AddressController.php | 17 ++++++++ core/lib/Thelia/Core/Event/TheliaEvents.php | 5 +++ templates/default/account.html | 39 +++++++++++++++++-- 5 files changed, 73 insertions(+), 4 deletions(-) diff --git a/core/lib/Thelia/Action/Address.php b/core/lib/Thelia/Action/Address.php index 0aee9a6f5..a912888c8 100644 --- a/core/lib/Thelia/Action/Address.php +++ b/core/lib/Thelia/Action/Address.php @@ -26,6 +26,7 @@ use Propel\Runtime\Exception\PropelException; use Propel\Runtime\Propel; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Thelia\Core\Event\AddressCreateOrUpdateEvent; +use Thelia\Core\Event\AddressEvent; use Thelia\Core\Event\TheliaEvents; use Thelia\Model\Address as AddressModel; use Thelia\Model\Map\AddressTableMap; @@ -52,6 +53,13 @@ class Address extends BaseAction implements EventSubscriberInterface $this->createOrUpdate($addressModel, $event); } + public function delete(AddressEvent $event) + { + $address = $event->getAddress(); + + $address->delete(); + } + protected function createOrUpdate(AddressModel $addressModel, AddressCreateOrUpdateEvent $event) { $addressModel->setDispatcher($this->getDispatcher()); @@ -116,7 +124,8 @@ class Address extends BaseAction implements EventSubscriberInterface { return array( TheliaEvents::ADDRESS_CREATE => array("create", 128), - TheliaEvents::ADDRESS_UPDATE => array("update", 128) + TheliaEvents::ADDRESS_UPDATE => array("update", 128), + TheliaEvents::ADDRESS_DELETE => array("delete", 128) ); } } diff --git a/core/lib/Thelia/Config/Resources/routing/front.xml b/core/lib/Thelia/Config/Resources/routing/front.xml index da3c1bdb7..38afb7d7f 100755 --- a/core/lib/Thelia/Config/Resources/routing/front.xml +++ b/core/lib/Thelia/Config/Resources/routing/front.xml @@ -79,6 +79,11 @@ address-update + + Thelia\Controller\Front\AddressController::deleteAction + account + + Thelia\Controller\Front\AddressController::generateModalAction modal-address diff --git a/core/lib/Thelia/Controller/Front/AddressController.php b/core/lib/Thelia/Controller/Front/AddressController.php index 33fa67069..272fa6424 100644 --- a/core/lib/Thelia/Controller/Front/AddressController.php +++ b/core/lib/Thelia/Controller/Front/AddressController.php @@ -23,6 +23,7 @@ namespace Thelia\Controller\Front; use Thelia\Core\Event\AddressCreateOrUpdateEvent; +use Thelia\Core\Event\AddressEvent; use Thelia\Core\Event\TheliaEvents; use Thelia\Form\AddressCreateForm; use Thelia\Form\AddressUpdateForm; @@ -154,6 +155,22 @@ class AddressController extends BaseFrontController } } + public function deleteAction($address_id) + { + $this->checkAuth(); + + $customer = $this->getSecurityContext()->getCustomerUser(); + $address = AddressQuery::create()->findPk($address_id); + + if(!$address || $customer->getId() != $address->getCustomerId()) { + $this->redirectToRoute("home"); + } + + $this->dispatch(TheliaEvents::ADDRESS_DELETE, new AddressEvent($address)); + + $this->redirectToRoute("customer.account.view"); + } + protected function createAddressEvent($form) { return new AddressCreateOrUpdateEvent( diff --git a/core/lib/Thelia/Core/Event/TheliaEvents.php b/core/lib/Thelia/Core/Event/TheliaEvents.php index 97e140eb6..54f05c0c0 100755 --- a/core/lib/Thelia/Core/Event/TheliaEvents.php +++ b/core/lib/Thelia/Core/Event/TheliaEvents.php @@ -129,6 +129,11 @@ final class TheliaEvents */ const ADDRESS_UPDATE = "action.updateAddress"; + /** + * sent on address removal + */ + const ADDRESS_DELETE = "action.deleteAddress"; + const BEFORE_CREATEADDRESS = "action.before_createAddress"; const AFTER_CREATEADDRESS = "action.after_createAddress"; diff --git a/templates/default/account.html b/templates/default/account.html index f3815e5c0..94bd58501 100644 --- a/templates/default/account.html +++ b/templates/default/account.html @@ -78,8 +78,8 @@ {intl l="Add a new address"} - {loop type="address" name="customer.addresses"} - + {loop type="address" name="customer.addresses" customer="current"} + @@ -173,4 +173,37 @@ + + +{/block} + +{block name="after-javascript-include"} + + + {/block} \ No newline at end of file From ecc419fbdf53896c6ae8f40ce4710dbc0ac1ccaf Mon Sep 17 00:00:00 2001 From: Etienne Roudeix Date: Fri, 13 Sep 2013 13:59:16 +0200 Subject: [PATCH 42/45] tax engine retriever --- core/lib/Thelia/TaxEngine/Calculator.php | 75 ++++++++++++++++++- .../Thelia/TaxEngine/TaxType/BaseTaxType.php | 4 + .../TaxType/FeatureSlicePercentTaxType.php | 10 +++ .../TaxEngine/TaxType/FixAmountTaxType.php | 10 +++ .../TaxEngine/TaxType/PricePercentTaxType.php | 12 +++ .../Thelia/Tests/TaxEngine/CalculatorTest.php | 67 +++++++++++------ 6 files changed, 155 insertions(+), 23 deletions(-) diff --git a/core/lib/Thelia/TaxEngine/Calculator.php b/core/lib/Thelia/TaxEngine/Calculator.php index f8c527cd1..b5a2f995e 100755 --- a/core/lib/Thelia/TaxEngine/Calculator.php +++ b/core/lib/Thelia/TaxEngine/Calculator.php @@ -73,11 +73,16 @@ class Calculator return $this; } - public function getTaxAmount($untaxedPrice) + public function getTaxAmountFromUntaxedPrice($untaxedPrice) { return $this->getTaxedPrice($untaxedPrice) - $untaxedPrice; } + public function getTaxAmountFromTaxedPrice($taxedPrice) + { + return $taxedPrice - $this->getUntaxedPrice($taxedPrice); + } + public function getTaxedPrice($untaxedPrice) { if(null === $this->taxRulesCollection) { @@ -111,4 +116,72 @@ class Calculator return $taxedPrice; } + + public function getUntaxedPrice($taxedPrice) + { + if(null === $this->taxRulesCollection) { + throw new TaxEngineException('Tax rules collection is empty in Calculator::getTaxAmount', TaxEngineException::UNDEFINED_TAX_RULES_COLLECTION); + } + + if(false === filter_var($taxedPrice, FILTER_VALIDATE_FLOAT)) { + throw new TaxEngineException('BAD AMOUNT FORMAT', TaxEngineException::BAD_AMOUNT_FORMAT); + } + + $taxRule = $this->taxRulesCollection->getLast(); + + $untaxedPrice = $taxedPrice; + $currentPosition = (int)$taxRule->getTaxRuleCountryPosition(); + $currentFixTax = 0; + $currentTaxFactor = 0; + + do { + $position = (int)$taxRule->getTaxRuleCountryPosition(); + + $taxType = $taxRule->getTypeInstance(); + $taxType->loadRequirements( $taxRule->getRequirements() ); + + if($currentPosition !== $position) { + $untaxedPrice -= $currentFixTax; + $untaxedPrice = $untaxedPrice / (1+$currentTaxFactor); + $currentFixTax = 0; + $currentTaxFactor = 0; + $currentPosition = $position; + } + + $currentFixTax += $taxType->fixAmountRetriever(); + $currentTaxFactor += $taxType->pricePercentRetriever(); + + + } while($taxRule = $this->taxRulesCollection->getPrevious()); + + $untaxedPrice -= $currentFixTax; + $untaxedPrice = $untaxedPrice / (1+$currentTaxFactor); + + /*do { + + $taxType = $taxRule->getTypeInstance(); + $taxType->loadRequirements( $taxRule->getRequirements() ); + + $untaxedPrice -= $taxType->fixAmountRetriever(); + + } while($taxRule = $this->taxRulesCollection->getPrevious()); + + $taxRule = $this->taxRulesCollection->getLast(); + + $currentTaxFactor = 0; + do { + + $taxType = $taxRule->getTypeInstance(); + $taxType->loadRequirements( $taxRule->getRequirements() ); + + $currentTaxFactor += $taxType->pricePercentRetriever($untaxedPrice); + + $toto = true; + + } while($taxRule = $this->taxRulesCollection->getPrevious()); + + $untaxedPrice = $untaxedPrice / (1+$currentTaxFactor);*/ + + return $untaxedPrice; + } } diff --git a/core/lib/Thelia/TaxEngine/TaxType/BaseTaxType.php b/core/lib/Thelia/TaxEngine/TaxType/BaseTaxType.php index 7f487bf64..149e3f1df 100755 --- a/core/lib/Thelia/TaxEngine/TaxType/BaseTaxType.php +++ b/core/lib/Thelia/TaxEngine/TaxType/BaseTaxType.php @@ -36,6 +36,10 @@ abstract class BaseTaxType public abstract function calculate($untaxedPrice); + public abstract function pricePercentRetriever(); + + public abstract function fixAmountRetriever(); + public abstract function getRequirementsList(); public function loadRequirements($requirementsValues) diff --git a/core/lib/Thelia/TaxEngine/TaxType/FeatureSlicePercentTaxType.php b/core/lib/Thelia/TaxEngine/TaxType/FeatureSlicePercentTaxType.php index 4485f1e21..911439574 100755 --- a/core/lib/Thelia/TaxEngine/TaxType/FeatureSlicePercentTaxType.php +++ b/core/lib/Thelia/TaxEngine/TaxType/FeatureSlicePercentTaxType.php @@ -37,6 +37,16 @@ class featureSlicePercentTaxType extends BaseTaxType } + public function pricePercentRetriever() + { + + } + + public function fixAmountRetriever() + { + + } + public function getRequirementsList() { return array( diff --git a/core/lib/Thelia/TaxEngine/TaxType/FixAmountTaxType.php b/core/lib/Thelia/TaxEngine/TaxType/FixAmountTaxType.php index c533d0ec3..acd52bf8a 100755 --- a/core/lib/Thelia/TaxEngine/TaxType/FixAmountTaxType.php +++ b/core/lib/Thelia/TaxEngine/TaxType/FixAmountTaxType.php @@ -36,6 +36,16 @@ class FixAmountTaxType extends BaseTaxType return $this->getRequirement("amount"); } + public function pricePercentRetriever() + { + return 0; + } + + public function fixAmountRetriever() + { + return $this->getRequirement("amount"); + } + public function getRequirementsList() { return array( diff --git a/core/lib/Thelia/TaxEngine/TaxType/PricePercentTaxType.php b/core/lib/Thelia/TaxEngine/TaxType/PricePercentTaxType.php index 1d7152fcf..a8cd8c759 100755 --- a/core/lib/Thelia/TaxEngine/TaxType/PricePercentTaxType.php +++ b/core/lib/Thelia/TaxEngine/TaxType/PricePercentTaxType.php @@ -36,6 +36,16 @@ class PricePercentTaxType extends BaseTaxType return $untaxedPrice * $this->getRequirement("percent") * 0.01; } + public function pricePercentRetriever() + { + return ($this->getRequirement("percent") * 0.01); + } + + public function fixAmountRetriever() + { + return 0; + } + public function getRequirementsList() { return array( @@ -43,3 +53,5 @@ class PricePercentTaxType extends BaseTaxType ); } } + +//600 / (1 + 0,10 + 0,10) =/= 600 / (1 + 0,10 ) + 600 / (1 + 0,10 ) \ No newline at end of file diff --git a/core/lib/Thelia/Tests/TaxEngine/CalculatorTest.php b/core/lib/Thelia/Tests/TaxEngine/CalculatorTest.php index 165d5d517..e0443c5ba 100755 --- a/core/lib/Thelia/Tests/TaxEngine/CalculatorTest.php +++ b/core/lib/Thelia/Tests/TaxEngine/CalculatorTest.php @@ -112,17 +112,17 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase * @expectedException \Thelia\Exception\TaxEngineException * @expectedExceptionCode 503 */ - public function testGetTaxAmountBadTaxRulesCollection() + public function testGetTaxedPriceBadTaxRulesCollection() { $calculator = new Calculator(); - $calculator->getTaxAmount(500); + $calculator->getTaxedPrice(500); } /** * @expectedException \Thelia\Exception\TaxEngineException * @expectedExceptionCode 601 */ - public function testGetTaxAmountBadAmount() + public function testGetTaxedPriceBadAmount() { $taxRulesCollection = new ObjectCollection(); @@ -131,12 +131,11 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase $rewritingUrlQuery = $this->getProperty('taxRulesCollection'); $rewritingUrlQuery->setValue($calculator, $taxRulesCollection); - $calculator->getTaxAmount('foo'); + $calculator->getTaxedPrice('foo'); } - public function testGetTaxAmountAndGetTaxedPrice() + public function testGetTaxedPriceAndGetTaxAmountFromUntaxedPrice() { - /* consecutives taxes */ $taxRulesCollection = new ObjectCollection(); $taxRulesCollection->setModel('\Thelia\Model\Tax'); @@ -144,14 +143,24 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase $tax->setType('PricePercentTaxType') ->setRequirements(array('percent' => 10)) ->setVirtualColumn('taxRuleCountryPosition', 1); - $taxRulesCollection->append($tax); $tax = new Tax(); $tax->setType('PricePercentTaxType') ->setRequirements(array('percent' => 8)) + ->setVirtualColumn('taxRuleCountryPosition', 1); + $taxRulesCollection->append($tax); + + $tax = new Tax(); + $tax->setType('FixAmountTaxType') + ->setRequirements(array('amount' => 5)) ->setVirtualColumn('taxRuleCountryPosition', 2); + $taxRulesCollection->append($tax); + $tax = new Tax(); + $tax->setType('PricePercentTaxType') + ->setRequirements(array('percent' => 1)) + ->setVirtualColumn('taxRuleCountryPosition', 3); $taxRulesCollection->append($tax); $calculator = new Calculator(); @@ -159,19 +168,22 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase $rewritingUrlQuery = $this->getProperty('taxRulesCollection'); $rewritingUrlQuery->setValue($calculator, $taxRulesCollection); - $taxAmount = $calculator->getTaxAmount(500); + $taxAmount = $calculator->getTaxAmountFromUntaxedPrice(500); $taxedPrice = $calculator->getTaxedPrice(500); /* * expect : - * tax 1 = 500*0.10 = 50 // amout with tax 1 : 550 - * tax 2 = 550*0.08 = 44 // amout with tax 2 : 594 - * total tax amount = 94 + * tax 1 = 500*0.10 = 50 + 500*0.08 = 40 // amount with tax 1 : 590 + * tax 2 = 5 // amount with tax 2 : 595 + * tax 3 = 595 * 0.01 = 5.95 // amount with tax 3 : 600.95 + * total tax amount = 100.95 */ - $this->assertEquals(94, $taxAmount); - $this->assertEquals(594, $taxedPrice); + $this->assertEquals(100.95, $taxAmount); + $this->assertEquals(600.95, $taxedPrice); + } - /* same position taxes */ + public function testGetUntaxedPriceAndGetTaxAmountFromTaxedPrice() + { $taxRulesCollection = new ObjectCollection(); $taxRulesCollection->setModel('\Thelia\Model\Tax'); @@ -179,14 +191,24 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase $tax->setType('PricePercentTaxType') ->setRequirements(array('percent' => 10)) ->setVirtualColumn('taxRuleCountryPosition', 1); - $taxRulesCollection->append($tax); $tax = new Tax(); $tax->setType('PricePercentTaxType') ->setRequirements(array('percent' => 8)) ->setVirtualColumn('taxRuleCountryPosition', 1); + $taxRulesCollection->append($tax); + $tax = new Tax(); + $tax->setType('FixAmountTaxType') + ->setRequirements(array('amount' => 5)) + ->setVirtualColumn('taxRuleCountryPosition', 2); + $taxRulesCollection->append($tax); + + $tax = new Tax(); + $tax->setType('PricePercentTaxType') + ->setRequirements(array('percent' => 1)) + ->setVirtualColumn('taxRuleCountryPosition', 3); $taxRulesCollection->append($tax); $calculator = new Calculator(); @@ -194,16 +216,17 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase $rewritingUrlQuery = $this->getProperty('taxRulesCollection'); $rewritingUrlQuery->setValue($calculator, $taxRulesCollection); - $taxAmount = $calculator->getTaxAmount(500); - $taxedPrice = $calculator->getTaxedPrice(500); + $taxAmount = $calculator->getTaxAmountFromTaxedPrice(600.95); + $untaxedPrice = $calculator->getUntaxedPrice(600.95); /* * expect : - * tax 1 = 500*0.10 = 50 // amout with tax 1 : 550 - * tax 2 = 500*0.08 = 40 // amout with tax 2 : 590 - * total tax amount = 90 + * tax 3 = 600.95 - 600.95 / (1 + 0.01) = 5,95 // amount without tax 3 : 595 + * tax 2 = 5 // amount without tax 2 : 590 + * tax 1 = 590 - 590 / (1 + 0.08 + 0.10) = 90 // amount without tax 1 : 500 + * total tax amount = 100.95 */ - $this->assertEquals(90, $taxAmount); - $this->assertEquals(590, $taxedPrice); + $this->assertEquals(100.95, $taxAmount); + $this->assertEquals(500, $untaxedPrice); } } From 8b0c8bd760262c92120b8bc45cf79f7ad2cb6f9b Mon Sep 17 00:00:00 2001 From: mespeche Date: Fri, 13 Sep 2013 18:03:45 +0200 Subject: [PATCH 43/45] First version of installation wizard --- .../Config/Resources/routing/install.xml | 20 ++- .../Install/BaseInstallController.php | 2 +- .../Controller/Install/InstallController.php | 51 ++++++- core/lib/Thelia/Install/BaseInstall.php | 3 +- .../default/assets/less/thelia/thelia.less | 1 + .../default/assets/less/thelia/wizard.less | 129 ++++++++++++++++++ templates/install/index.html | 52 +++++-- templates/install/layout.html | 49 ------- templates/install/layout.tpl | 62 +++++++++ templates/install/step-2.html | 51 +++++++ templates/install/step-3.html | 56 ++++++++ templates/install/step-4.html | 77 +++++++++++ templates/install/step-5.html | 72 ++++++++++ templates/install/thanks.html | 42 ++++++ 14 files changed, 601 insertions(+), 66 deletions(-) create mode 100644 templates/admin/default/assets/less/thelia/wizard.less delete mode 100644 templates/install/layout.html create mode 100644 templates/install/layout.tpl create mode 100644 templates/install/step-2.html create mode 100644 templates/install/step-3.html create mode 100644 templates/install/step-4.html create mode 100644 templates/install/step-5.html create mode 100644 templates/install/thanks.html diff --git a/core/lib/Thelia/Config/Resources/routing/install.xml b/core/lib/Thelia/Config/Resources/routing/install.xml index d53763948..37ddde487 100644 --- a/core/lib/Thelia/Config/Resources/routing/install.xml +++ b/core/lib/Thelia/Config/Resources/routing/install.xml @@ -4,12 +4,28 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd"> - + Thelia\Controller\Install\InstallController::index - + Thelia\Controller\Install\InstallController::checkPermission + + Thelia\Controller\Install\InstallController::databaseConnection + + + + Thelia\Controller\Install\InstallController::databaseSelection + + + + Thelia\Controller\Install\InstallController::generalInformation + + + + Thelia\Controller\Install\InstallController::thanks + + diff --git a/core/lib/Thelia/Controller/Install/BaseInstallController.php b/core/lib/Thelia/Controller/Install/BaseInstallController.php index 35293904e..bac7a4f19 100644 --- a/core/lib/Thelia/Controller/Install/BaseInstallController.php +++ b/core/lib/Thelia/Controller/Install/BaseInstallController.php @@ -39,7 +39,7 @@ class BaseInstallController extends BaseController { $parser = $this->container->get("thelia.parser"); - // Define the template thant shoud be used + // Define the template that shoud be used $parser->setTemplate("install"); return $parser; diff --git a/core/lib/Thelia/Controller/Install/InstallController.php b/core/lib/Thelia/Controller/Install/InstallController.php index 0514ba0ff..40e6643db 100644 --- a/core/lib/Thelia/Controller/Install/InstallController.php +++ b/core/lib/Thelia/Controller/Install/InstallController.php @@ -33,18 +33,61 @@ class InstallController extends BaseInstallController { public function index() { - $this->verifyStep(1); + //$this->verifyStep(1); $this->getSession()->set("step", 1); - $this->render("index.html"); + return $this->render("index.html"); } public function checkPermission() { - $this->verifyStep(2); + //$this->verifyStep(2); - $permission = new CheckPermission(); + //$permission = new CheckPermission(); + + $this->getSession()->set("step", 2); + return $this->render("step-2.html"); + } + + public function databaseConnection() + { + //$this->verifyStep(2); + + //$permission = new CheckPermission(); + + $this->getSession()->set("step", 3); + return $this->render("step-3.html"); + } + + public function databaseSelection() + { + //$this->verifyStep(2); + + //$permission = new CheckPermission(); + + $this->getSession()->set("step", 4); + return $this->render("step-4.html"); + } + + public function generalInformation() + { + //$this->verifyStep(2); + + //$permission = new CheckPermission(); + + $this->getSession()->set("step", 5); + return $this->render("step-5.html"); + } + + public function thanks() + { + //$this->verifyStep(2); + + //$permission = new CheckPermission(); + + $this->getSession()->set("step", 6); + return $this->render("thanks.html"); } protected function verifyStep($step) diff --git a/core/lib/Thelia/Install/BaseInstall.php b/core/lib/Thelia/Install/BaseInstall.php index 58c510267..11b8d0999 100644 --- a/core/lib/Thelia/Install/BaseInstall.php +++ b/core/lib/Thelia/Install/BaseInstall.php @@ -34,9 +34,10 @@ abstract class BaseInstall */ public function __construct($verifyInstall = true) { + /* TODO : activate this part if (file_exists(THELIA_ROOT . '/local/config/database.yml') && $verifyInstall) { throw new AlreadyInstallException("Thelia is already installed"); - } + }*/ $this->exec(); diff --git a/templates/admin/default/assets/less/thelia/thelia.less b/templates/admin/default/assets/less/thelia/thelia.less index ac525566f..50cd9bde6 100644 --- a/templates/admin/default/assets/less/thelia/thelia.less +++ b/templates/admin/default/assets/less/thelia/thelia.less @@ -8,6 +8,7 @@ @import "modals.less"; @import "tables.less"; @import "tablesorter.less"; +@import "wizard.less"; @import "bootstrap-editable.less"; @import "bootstrap-switch.less"; diff --git a/templates/admin/default/assets/less/thelia/wizard.less b/templates/admin/default/assets/less/thelia/wizard.less new file mode 100644 index 000000000..0d130a2d5 --- /dev/null +++ b/templates/admin/default/assets/less/thelia/wizard.less @@ -0,0 +1,129 @@ +.wizard { + background-color: #fff; + border: 1px solid #d4d4d4; + border-radius: 4px; + .box-shadow(0 1px 4px rgba(0, 0, 0, 0.065)); + *zoom: 1; + margin-bottom: 20px; + + &:before, + &:after { + display: table; + line-height: 0; + content: ""; + clear: both; + } + + ul { + padding: 0; + margin: 0; + list-style: none outside none; + } + + li { + position: relative; + float: left; + height: 46px; + padding: 0 10px 0 30px; + margin: 0; + font-size: 15px; + line-height: 46px; + color: #999999; + cursor: default; + background: #ededed; + + &.complete { + color: #468847; + background: #f3f4f5; + + &:hover{ + background: #e8e8e8; + + .chevron:before { + border-left: 14px solid #e8e8e8; + } + } + + a{ + color: inherit; + text-decoration: none; + font-weight: normal; + } + + .chevron:before { + border-left: 14px solid #f3f4f5; + } + + } + + &.active { + color: @link-color; + background: #fff; + + .chevron:before { + border-left: 14px solid #fff; + } + } + + .chevron { + position: absolute; + top: 0; + right: -14px; + display: block; + border: 24px solid transparent; + border-right: 0; + border-left: 14px solid #d4d4d4; + + &:before { + position: absolute; + top: -24px; + right: 1px; + display: block; + border: 24px solid transparent; + border-right: 0; + border-left: 14px solid #ededed; + content: ""; + } + + } + + .badge { + margin-right: 8px; + } + + &:nth-child(1) { + z-index: 10; + padding-left: 20px; + border-radius: 4px 0 0 4px; + } + &:nth-child(2) { + z-index: 9; + } + &:nth-child(3) { + z-index: 8; + } + &:nth-child(4) { + z-index: 7; + } + &:nth-child(5) { + z-index: 6; + } + &:nth-child(6) { + z-index: 5; + } + &:nth-child(7) { + z-index: 4; + } + &:nth-child(8) { + z-index: 3; + } + &:nth-child(9) { + z-index: 2; + } + &:nth-child(10) { + z-index: 1; + } + + } + +} \ No newline at end of file diff --git a/templates/install/index.html b/templates/install/index.html index a996cc241..dd1d5f62b 100644 --- a/templates/install/index.html +++ b/templates/install/index.html @@ -1,12 +1,46 @@ -{extends file="layout.html"} -{block name="content"} -

    {intl l="Thelia installation wizard"}

    -
    +{extends file="layout.tpl"} - {intl l="Bienvenue au sein du programme d'installation de Thelia."}
    - {intl l="Nous allons vous guider tout au long de ce processus afin d'installer l'application sur votre système."}

    +{block name="page-title"}{intl l='Installation'}{/block} -
    - - +{block name="main-content"} +
    +
    + +
    +
    +
    + +

    {intl l="Thelia installation wizard"}

    + +
    +
      +
    • 1{intl l="Welcome"}
    • +
    • 2{intl l="Checking permissions"}
    • +
    • 3{intl l="Database connection"}
    • +
    • 4{intl l="Database selection"}
    • +
    • 5{intl l="General information"}
    • +
    • 6{intl l="Thanks"}
    • +
    +
    + +
    +

    + {intl l="Welcome in the Thelia installation wizard."} +

    +

    + {intl l="We will guide you throughout this process to install any application on your system."} +

    + +
    + + + +
    +
    +
    + +
    +
    {/block} \ No newline at end of file diff --git a/templates/install/layout.html b/templates/install/layout.html deleted file mode 100644 index 0a13586ad..000000000 --- a/templates/install/layout.html +++ /dev/null @@ -1,49 +0,0 @@ - - - - {block name="title"}Thelia Install{/block} - - {images file='../admin/default/assets/img/favicon.ico'}{/images} - - - - {stylesheets file='../admin/default/assets/bootstrap/css/bootstrap.css' filters='cssembed'} - - {/stylesheets} - - {stylesheets file='../admin/default/assets/bootstrap/css/bootstrap-responsive.css' filters='cssembed'} - - {/stylesheets} - - - {stylesheets file='../admin/default/assets/css/*' filters='less,cssembed'} - - {/stylesheets} - - - -
    -
    -
    {intl l='Version %ver' ver="{$THELIA_VERSION}"}
    -
    -
    -
    - {block name="content"}{/block} -
    - -
    - - - - \ No newline at end of file diff --git a/templates/install/layout.tpl b/templates/install/layout.tpl new file mode 100644 index 000000000..4539ce32f --- /dev/null +++ b/templates/install/layout.tpl @@ -0,0 +1,62 @@ + + + + {block name="page-title"}Thelia Install{/block} + + {images file='../admin/default/assets/img/favicon.ico'}{/images} + + + + {stylesheets file='../admin/default/assets/less/*' filters='less,cssembed'} + + {/stylesheets} + + + +
    +
    + +
    +
    +
    {intl l='Version %ver' ver="{$THELIA_VERSION}"}
    +
    +
    + +
    +
    + + {* -- Main page content section ----------------------------------------- *} + + {block name="main-content"}Put here the content of the template{/block} + + {* -- Footer section ---------------------------------------------------- *} + +
    + + + {* -- Javascript section ------------------------------------------------ *} + + + + {block name="after-javascript-include"}{/block} + + {javascripts file='../admin/default/assets/js/bootstrap/bootstrap.js'} + + {/javascripts} + + {block name="javascript-initialization"}{/block} + + + \ No newline at end of file diff --git a/templates/install/step-2.html b/templates/install/step-2.html new file mode 100644 index 000000000..fc24d25cb --- /dev/null +++ b/templates/install/step-2.html @@ -0,0 +1,51 @@ +{extends file="layout.tpl"} + +{block name="page-title"}{intl l='Installation step 2'}{/block} + +{block name="main-content"} +
    +
    + +
    +
    +
    + +

    {intl l="Thelia installation wizard"}

    + +
    +
      +
    • 1{intl l="Welcome"}
    • +
    • 2{intl l="Checking permissions"}
    • +
    • 3{intl l="Database connection"}
    • +
    • 4{intl l="Database selection"}
    • +
    • 5{intl l="General information"}
    • +
    • 6{intl l="Thanks"}
    • +
    +
    + +
    +

    We will check some rights to files and directories...

    +
      +
    • Duis mollis, est non commodo luctus, nisi erat porttitor ligula.
    • +
    • Duis mollis, est non commodo luctus, nisi erat porttitor ligula.
    • +
    • Duis mollis, est non commodo luctus, nisi erat porttitor ligula.
    • +
    • Duis mollis, est non commodo luctus, nisi erat porttitor ligula.
    • +
    • Duis mollis, est non commodo luctus, nisi erat porttitor ligula.
    • +
    • Duis mollis, est non commodo luctus, nisi erat porttitor ligula.
    • +
    • Duis mollis, est non commodo luctus, nisi erat porttitor ligula.
    • +
    + +
    + + + +
    +
    +
    + +
    +
    +{/block} \ No newline at end of file diff --git a/templates/install/step-3.html b/templates/install/step-3.html new file mode 100644 index 000000000..cb4157dd7 --- /dev/null +++ b/templates/install/step-3.html @@ -0,0 +1,56 @@ +{extends file="layout.tpl"} + +{block name="page-title"}{intl l='Installation step 3'}{/block} + +{block name="main-content"} +
    +
    + +
    +
    +
    + +

    {intl l="Thelia installation wizard"}

    + +
    + +
    + +
    + +
    +
    + + +
    +
    + + +
    +
    + + +
    + + +
    + + + +
    +
    +
    + +
    +
    +{/block} \ No newline at end of file diff --git a/templates/install/step-4.html b/templates/install/step-4.html new file mode 100644 index 000000000..981be34bb --- /dev/null +++ b/templates/install/step-4.html @@ -0,0 +1,77 @@ +{extends file="layout.tpl"} + +{block name="page-title"}{intl l='Installation step 4'}{/block} + +{block name="main-content"} +
    +
    + +
    +
    +
    + +

    {intl l="Thelia installation wizard"}

    + +
    + +
    + +
    +
    +
    + {intl l="Choose your database"} +

    + The SQL server contains multiple databases.
    + Select below the one you want to use. +

    + +
    + +
    +
    + +
    + +

    + {intl l="or"} +

    + +
    + +
    + +
    + +
    +
    + +
    + + + +
    +
    +
    + +
    +
    +{/block} \ No newline at end of file diff --git a/templates/install/step-5.html b/templates/install/step-5.html new file mode 100644 index 000000000..611a86a20 --- /dev/null +++ b/templates/install/step-5.html @@ -0,0 +1,72 @@ +{extends file="layout.tpl"} + +{block name="page-title"}{intl l='Installation step 4'}{/block} + +{block name="main-content"} +
    +
    + +
    +
    +
    + +

    {intl l="Thelia installation wizard"}

    + + + +
    +
    + +

    + The system will now you create a custom site access. +

    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + + +
    + + + +
    +
    +
    + +
    +
    +{/block} \ No newline at end of file diff --git a/templates/install/thanks.html b/templates/install/thanks.html new file mode 100644 index 000000000..b6ed27065 --- /dev/null +++ b/templates/install/thanks.html @@ -0,0 +1,42 @@ +{extends file="layout.tpl"} + +{block name="page-title"}{intl l='Thanks'}{/block} + +{block name="main-content"} +
    +
    + +
    +
    +
    + +

    {intl l="Thelia installation wizard"}

    + + + +
    +

    + {intl l="Thank you have installed Thelia"}. +

    +

    + {intl l="You will be redirected to your personal space in order to manage your store now."} +

    + +
    + +
    +
    +
    + +
    +
    +{/block} \ No newline at end of file From a0f09057c490933d41366021c7d0b83c269fa765 Mon Sep 17 00:00:00 2001 From: franck Date: Fri, 13 Sep 2013 20:21:47 +0200 Subject: [PATCH 44/45] Added Templates events --- core/lib/Thelia/Core/Event/TheliaEvents.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/core/lib/Thelia/Core/Event/TheliaEvents.php b/core/lib/Thelia/Core/Event/TheliaEvents.php index 97e140eb6..ac0064c41 100755 --- a/core/lib/Thelia/Core/Event/TheliaEvents.php +++ b/core/lib/Thelia/Core/Event/TheliaEvents.php @@ -362,6 +362,21 @@ final class TheliaEvents const BEFORE_DELETECURRENCY = "action.before_deleteCurrency"; const AFTER_DELETECURRENCY = "action.after_deleteCurrency"; + // -- Product templates management ----------------------------------------- + + const TEMPLATE_CREATE = "action.createTemplate"; + const TEMPLATE_UPDATE = "action.updateTemplate"; + const TEMPLATE_DELETE = "action.deleteTemplate"; + + const BEFORE_CREATETEMPLATE = "action.before_createTemplate"; + const AFTER_CREATETEMPLATE = "action.after_createTemplate"; + + const BEFORE_UPDATETEMPLATE = "action.before_updateTemplate"; + const AFTER_UPDATETEMPLATE = "action.after_updateTemplate"; + + const BEFORE_DELETETEMPLATE = "action.before_deleteTemplate"; + const AFTER_DELETETEMPLATE = "action.after_deleteTemplate"; + // -- Attributes management --------------------------------------------- const ATTRIBUTE_CREATE = "action.createAttribute"; From 71c1cee66d8f2e515e82478f792879fa63843644 Mon Sep 17 00:00:00 2001 From: franck Date: Mon, 16 Sep 2013 09:23:44 +0200 Subject: [PATCH 45/45] Implemented "Remember Me" feature on admin. Started template management --- core/lib/Thelia/Action/Attribute.php | 8 +- core/lib/Thelia/Action/Template.php | 127 + core/lib/Thelia/Config/Resources/action.xml | 5 + core/lib/Thelia/Config/Resources/config.xml | 5 + .../Thelia/Config/Resources/routing/admin.xml | 23 + .../Admin/AbstractCrudController.php | 33 +- .../Controller/Admin/AdminController.php | 4 + .../Controller/Admin/AttributeController.php | 4 +- .../Controller/Admin/BaseAdminController.php | 42 + .../Controller/Admin/SessionController.php | 49 +- .../Controller/Admin/TemplateController.php | 196 ++ core/lib/Thelia/Controller/BaseController.php | 4 +- .../Thelia/Core/Event/TemplateCreateEvent.php | 54 + .../Thelia/Core/Event/TemplateDeleteEvent.php | 59 + core/lib/Thelia/Core/Event/TemplateEvent.php | 52 + .../Thelia/Core/Event/TemplateUpdateEvent.php | 71 + .../AdminTokenAuthenticator.php | 37 + .../CustomerTokenAuthenticator.php | 37 + .../Authentication/TokenAuthenticator.php | 57 + .../TokenAuthenticationException.php | 28 + .../Security/Token/CookieTokenProvider.php | 55 + .../Core/Security/Token/TokenProvider.php | 27 + .../Core/Security/User/UserInterface.php | 22 +- .../UserProvider/AdminTokenUserProvider.php | 39 + .../UserProvider/AdminUserProvider.php | 22 + .../CustomerTokenUserProvider.php | 39 + .../UserProvider/CustomerUserProvider.php | 24 +- .../UserProvider/TokenUserProvider.php | 32 + .../UserProvider/UserProviderInterface.php | 21 + .../Thelia/Core/Template/Loop/Attribute.php | 33 +- .../Thelia/Core/Template/Loop/Template.php | 114 + .../Core/Template/Smarty/Plugins/Form.php | 30 +- core/lib/Thelia/Core/TheliaHttpKernel.php | 2 +- core/lib/Thelia/Form/TemplateCreationForm.php | 57 + .../Thelia/Form/TemplateModificationForm.php | 67 + core/lib/Thelia/Model/Admin.php | 39 + core/lib/Thelia/Model/AttributeTemplate.php | 10 + .../Thelia/Model/AttributeTemplateQuery.php | 21 + core/lib/Thelia/Model/Base/Admin.php | 134 +- core/lib/Thelia/Model/Base/AdminQuery.php | 68 +- core/lib/Thelia/Model/Base/Attribute.php | 398 +-- core/lib/Thelia/Model/Base/AttributeQuery.php | 54 +- .../Thelia/Model/Base/AttributeTemplate.php | 1495 ++++++++ .../Model/Base/AttributeTemplateQuery.php | 759 +++++ core/lib/Thelia/Model/Base/Category.php | 1060 ------ core/lib/Thelia/Model/Base/CategoryQuery.php | 188 - core/lib/Thelia/Model/Base/Customer.php | 134 +- core/lib/Thelia/Model/Base/CustomerQuery.php | 68 +- core/lib/Thelia/Model/Base/Feature.php | 398 +-- core/lib/Thelia/Model/Base/FeatureQuery.php | 54 +- .../lib/Thelia/Model/Base/FeatureTemplate.php | 1495 ++++++++ .../Model/Base/FeatureTemplateQuery.php | 759 +++++ core/lib/Thelia/Model/Base/Product.php | 185 +- core/lib/Thelia/Model/Base/ProductQuery.php | 128 +- core/lib/Thelia/Model/Base/ProductVersion.php | 106 +- .../Thelia/Model/Base/ProductVersionQuery.php | 47 +- core/lib/Thelia/Model/Base/TaxRule.php | 25 + core/lib/Thelia/Model/Base/Template.php | 3019 +++++++++++++++++ core/lib/Thelia/Model/Base/TemplateI18n.php | 1265 +++++++ .../Thelia/Model/Base/TemplateI18nQuery.php | 508 +++ core/lib/Thelia/Model/Base/TemplateQuery.php | 907 +++++ core/lib/Thelia/Model/Customer.php | 31 + core/lib/Thelia/Model/FeatureTemplate.php | 10 + .../lib/Thelia/Model/FeatureTemplateQuery.php | 21 + core/lib/Thelia/Model/Map/AdminTableMap.php | 44 +- .../Thelia/Model/Map/AttributeTableMap.php | 6 +- .../Model/Map/AttributeTemplateTableMap.php | 449 +++ .../lib/Thelia/Model/Map/CategoryTableMap.php | 6 - .../lib/Thelia/Model/Map/CustomerTableMap.php | 44 +- core/lib/Thelia/Model/Map/FeatureTableMap.php | 6 +- .../Model/Map/FeatureTemplateTableMap.php | 449 +++ core/lib/Thelia/Model/Map/ProductTableMap.php | 37 +- .../Model/Map/ProductVersionTableMap.php | 40 +- .../Thelia/Model/Map/TemplateI18nTableMap.php | 473 +++ .../lib/Thelia/Model/Map/TemplateTableMap.php | 455 +++ core/lib/Thelia/Model/Template.php | 68 + core/lib/Thelia/Model/TemplateI18n.php | 10 + core/lib/Thelia/Model/TemplateI18nQuery.php | 21 + core/lib/Thelia/Model/TemplateQuery.php | 21 + core/lib/Thelia/Tools/Redirect.php | 2 +- install/faker.php | 44 +- ...er_100categories_1000products_4locales.php | 14 +- install/insert.sql | 10 +- install/thelia.sql | 92 +- local/config/schema.xml | 2305 ++++++------- .../default/ajax/template-attribute-list.html | 15 + .../{includes => ajax}/thelia_news_feed.html | 0 templates/admin/default/attributes.html | 2 +- templates/admin/default/login.html | 2 +- templates/admin/default/template-edit.html | 115 + templates/admin/default/templates.html | 215 ++ 91 files changed, 16722 insertions(+), 3088 deletions(-) create mode 100644 core/lib/Thelia/Action/Template.php create mode 100644 core/lib/Thelia/Controller/Admin/TemplateController.php create mode 100644 core/lib/Thelia/Core/Event/TemplateCreateEvent.php create mode 100644 core/lib/Thelia/Core/Event/TemplateDeleteEvent.php create mode 100644 core/lib/Thelia/Core/Event/TemplateEvent.php create mode 100644 core/lib/Thelia/Core/Event/TemplateUpdateEvent.php create mode 100644 core/lib/Thelia/Core/Security/Authentication/AdminTokenAuthenticator.php create mode 100644 core/lib/Thelia/Core/Security/Authentication/CustomerTokenAuthenticator.php create mode 100644 core/lib/Thelia/Core/Security/Authentication/TokenAuthenticator.php create mode 100644 core/lib/Thelia/Core/Security/Exception/TokenAuthenticationException.php create mode 100644 core/lib/Thelia/Core/Security/Token/CookieTokenProvider.php create mode 100644 core/lib/Thelia/Core/Security/Token/TokenProvider.php create mode 100644 core/lib/Thelia/Core/Security/UserProvider/AdminTokenUserProvider.php create mode 100644 core/lib/Thelia/Core/Security/UserProvider/CustomerTokenUserProvider.php create mode 100644 core/lib/Thelia/Core/Security/UserProvider/TokenUserProvider.php create mode 100644 core/lib/Thelia/Core/Template/Loop/Template.php create mode 100644 core/lib/Thelia/Form/TemplateCreationForm.php create mode 100644 core/lib/Thelia/Form/TemplateModificationForm.php create mode 100644 core/lib/Thelia/Model/AttributeTemplate.php create mode 100644 core/lib/Thelia/Model/AttributeTemplateQuery.php create mode 100644 core/lib/Thelia/Model/Base/AttributeTemplate.php create mode 100644 core/lib/Thelia/Model/Base/AttributeTemplateQuery.php create mode 100644 core/lib/Thelia/Model/Base/FeatureTemplate.php create mode 100644 core/lib/Thelia/Model/Base/FeatureTemplateQuery.php create mode 100644 core/lib/Thelia/Model/Base/Template.php create mode 100644 core/lib/Thelia/Model/Base/TemplateI18n.php create mode 100644 core/lib/Thelia/Model/Base/TemplateI18nQuery.php create mode 100644 core/lib/Thelia/Model/Base/TemplateQuery.php create mode 100644 core/lib/Thelia/Model/FeatureTemplate.php create mode 100644 core/lib/Thelia/Model/FeatureTemplateQuery.php create mode 100644 core/lib/Thelia/Model/Map/AttributeTemplateTableMap.php create mode 100644 core/lib/Thelia/Model/Map/FeatureTemplateTableMap.php create mode 100644 core/lib/Thelia/Model/Map/TemplateI18nTableMap.php create mode 100644 core/lib/Thelia/Model/Map/TemplateTableMap.php create mode 100644 core/lib/Thelia/Model/Template.php create mode 100644 core/lib/Thelia/Model/TemplateI18n.php create mode 100644 core/lib/Thelia/Model/TemplateI18nQuery.php create mode 100644 core/lib/Thelia/Model/TemplateQuery.php create mode 100644 templates/admin/default/ajax/template-attribute-list.html rename templates/admin/default/{includes => ajax}/thelia_news_feed.html (100%) create mode 100644 templates/admin/default/template-edit.html create mode 100644 templates/admin/default/templates.html diff --git a/core/lib/Thelia/Action/Attribute.php b/core/lib/Thelia/Action/Attribute.php index 2877ca388..a2e956d8e 100644 --- a/core/lib/Thelia/Action/Attribute.php +++ b/core/lib/Thelia/Action/Attribute.php @@ -39,6 +39,8 @@ use Thelia\Model\AttributeAvQuery; use Thelia\Core\Event\UpdatePositionEvent; use Thelia\Core\Event\CategoryEvent; use Thelia\Core\Event\AttributeEvent; +use Thelia\Model\AttributeTemplate; +use Thelia\Model\AttributeTemplateQuery; class Attribute extends BaseAction implements EventSubscriberInterface { @@ -137,10 +139,10 @@ class Attribute extends BaseAction implements EventSubscriberInterface public function addToAllTemplates(AttributeEvent $event) { - $templates = ProductTemplateAttributeQuery::create()->find(); + $templates = AttributeTemplateQuery::create()->find(); foreach($templates as $template) { - $pat = new ProductTemplateAttribute(); + $pat = new AttributeTemplate(); $pat->setTemplate($template->getId()) ->setAttributeId($event->getAttribute()->getId()) @@ -151,7 +153,7 @@ class Attribute extends BaseAction implements EventSubscriberInterface public function removeFromAllTemplates(AttributeEvent $event) { // Delete this attribute from all product templates - ProductTemplateAttributeQuery::create()->filterByAttributeId($event->getAttribute()->getId())->delete(); + AttributeTemplateQuery::create()->filterByAttributeId($event->getAttribute()->getId())->delete(); } /** diff --git a/core/lib/Thelia/Action/Template.php b/core/lib/Thelia/Action/Template.php new file mode 100644 index 000000000..a06e10430 --- /dev/null +++ b/core/lib/Thelia/Action/Template.php @@ -0,0 +1,127 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Action; + +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +use Thelia\Model\TemplateQuery; +use Thelia\Model\Template as TemplateModel; + +use Thelia\Core\Event\TheliaEvents; + +use Thelia\Core\Event\TemplateUpdateEvent; +use Thelia\Core\Event\TemplateCreateEvent; +use Thelia\Core\Event\TemplateDeleteEvent; +use Thelia\Model\ConfigQuery; +use Thelia\Model\TemplateAv; +use Thelia\Model\TemplateAvQuery; +use Thelia\Core\Event\UpdatePositionEvent; +use Thelia\Core\Event\CategoryEvent; +use Thelia\Core\Event\TemplateEvent; +use Thelia\Model\TemplateTemplate; +use Thelia\Model\TemplateTemplateQuery; +use Thelia\Model\ProductQuery; + +class Template extends BaseAction implements EventSubscriberInterface +{ + /** + * Create a new template entry + * + * @param TemplateCreateEvent $event + */ + public function create(TemplateCreateEvent $event) + { + $template = new TemplateModel(); + + $template + ->setDispatcher($this->getDispatcher()) + + ->setLocale($event->getLocale()) + ->setName($event->getTemplateName()) + + ->save() + ; + + $event->setTemplate($template); + } + + /** + * Change a product template + * + * @param TemplateUpdateEvent $event + */ + public function update(TemplateUpdateEvent $event) + { + $search = TemplateQuery::create(); + + if (null !== $template = TemplateQuery::create()->findPk($event->getTemplateId())) { + + $template + ->setDispatcher($this->getDispatcher()) + + ->setLocale($event->getLocale()) + ->setName($event->getTemplateName()) + ->save(); + + $event->setTemplate($template); + } + } + + /** + * Delete a product template entry + * + * @param TemplateDeleteEvent $event + */ + public function delete(TemplateDeleteEvent $event) + { + if (null !== ($template = TemplateQuery::create()->findPk($event->getTemplateId()))) { + + // Check if template is used by a product + $product_count = ProductQuery::create()->findByTemplateId($template->getId())->count(); + + if ($product_count <= 0) { + $template + ->setDispatcher($this->getDispatcher()) + ->delete() + ; + } + + $event->setTemplate($template); + + $event->setProductCount($product_count); + } + } + + /** + * {@inheritDoc} + */ + public static function getSubscribedEvents() + { + return array( + TheliaEvents::TEMPLATE_CREATE => array("create", 128), + TheliaEvents::TEMPLATE_UPDATE => array("update", 128), + TheliaEvents::TEMPLATE_DELETE => array("delete", 128), + ); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Config/Resources/action.xml b/core/lib/Thelia/Config/Resources/action.xml index 2b86ed33e..f2fa776c3 100755 --- a/core/lib/Thelia/Config/Resources/action.xml +++ b/core/lib/Thelia/Config/Resources/action.xml @@ -57,6 +57,11 @@ + + + + + diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index ddb32cf65..8098eb9d4 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -36,6 +36,7 @@ + @@ -72,6 +73,10 @@
    + + + +
    diff --git a/core/lib/Thelia/Config/Resources/routing/admin.xml b/core/lib/Thelia/Config/Resources/routing/admin.xml index c16ee05bd..5c9399e27 100755 --- a/core/lib/Thelia/Config/Resources/routing/admin.xml +++ b/core/lib/Thelia/Config/Resources/routing/admin.xml @@ -210,6 +210,29 @@
    + + + + Thelia\Controller\Admin\TemplateController::defaultAction + + + + Thelia\Controller\Admin\TemplateController::createAction + + + + Thelia\Controller\Admin\TemplateController::updateAction + + + + Thelia\Controller\Admin\TemplateController::processUpdateAction + + + + Thelia\Controller\Admin\TemplateController::deleteAction + + + diff --git a/core/lib/Thelia/Controller/Admin/AbstractCrudController.php b/core/lib/Thelia/Controller/Admin/AbstractCrudController.php index 31f9ba72a..fad774023 100644 --- a/core/lib/Thelia/Controller/Admin/AbstractCrudController.php +++ b/core/lib/Thelia/Controller/Admin/AbstractCrudController.php @@ -210,31 +210,34 @@ abstract class AbstractCrudController extends BaseAdminController /** * Put in this method post object creation processing if required. * - * @param unknown $createdObject the created object + * @param unknown $createEvent the create event + * @return Response a response, or null to continue normal processing */ - protected function performAdditionalCreateAction($createdObject) + protected function performAdditionalCreateAction($createEvent) { - // Nothing to do + return null; } /** * Put in this method post object update processing if required. * - * @param unknown $updatedObject the updated object + * @param unknown $updateEvent the update event + * @return Response a response, or null to continue normal processing */ - protected function performAdditionalUpdateAction($updatedObject) + protected function performAdditionalUpdateAction($updateeEvent) { - // Nothing to do + return null; } /** * Put in this method post object delete processing if required. * - * @param unknown $deletedObject the deleted object + * @param unknown $deleteEvent the delete event + * @return Response a response, or null to continue normal processing */ - protected function performAdditionalDeleteAction($deletedObject) + protected function performAdditionalDeleteAction($deleteEvent) { - // Nothing to do + return null; } /** @@ -306,7 +309,7 @@ abstract class AbstractCrudController extends BaseAdminController $this->adminLogAppend(sprintf("%s %s (ID %s) created", ucfirst($this->objectName), $this->getObjectLabel($createdObject), $this->getObjectId($createdObject))); } - $this->performAdditionalCreateAction($createdObject); + $this->performAdditionalCreateAction($createEvent); // Substitute _ID_ in the URL with the ID of the created object $successUrl = str_replace('_ID_', $this->getObjectId($createdObject), $creationForm->getSuccessUrl()); @@ -393,7 +396,7 @@ abstract class AbstractCrudController extends BaseAdminController $this->adminLogAppend(sprintf("%s %s (ID %s) modified", ucfirst($this->objectName), $this->getObjectLabel($changedObject), $this->getObjectId($changedObject))); } - $this->performAdditionalUpdateAction($changedObject); + $this->performAdditionalUpdateAction($changeEvent); // If we have to stay on the same page, do not redirect to the succesUrl, // just redirect to the edit page again. @@ -494,8 +497,12 @@ abstract class AbstractCrudController extends BaseAdminController $this->adminLogAppend( sprintf("%s %s (ID %s) deleted", ucfirst($this->objectName), $this->getObjectLabel($deletedObject), $this->getObjectId($deletedObject))); } - $this->performAdditionalDeleteAction($deletedObject); - $this->redirectToListTemplate(); + $response = $this->performAdditionalDeleteAction($deleteEvent); + + if ($response == null) + $this->redirectToListTemplate(); + else + return $response; } } diff --git a/core/lib/Thelia/Controller/Admin/AdminController.php b/core/lib/Thelia/Controller/Admin/AdminController.php index fdb6b13ac..2c252258d 100755 --- a/core/lib/Thelia/Controller/Admin/AdminController.php +++ b/core/lib/Thelia/Controller/Admin/AdminController.php @@ -23,6 +23,10 @@ namespace Thelia\Controller\Admin; +use Thelia\Core\Security\Authentication\AdminTokenAuthenticator; +use Thelia\Model\ConfigQuery; +use Thelia\Core\Security\Exception\TokenAuthenticationException; + class AdminController extends BaseAdminController { public function indexAction() diff --git a/core/lib/Thelia/Controller/Admin/AttributeController.php b/core/lib/Thelia/Controller/Admin/AttributeController.php index 0ae181900..247b89632 100644 --- a/core/lib/Thelia/Controller/Admin/AttributeController.php +++ b/core/lib/Thelia/Controller/Admin/AttributeController.php @@ -107,7 +107,7 @@ class AttributeController extends AbstractCrudController * * @see \Thelia\Controller\Admin\AbstractCrudController::performAdditionalUpdateAction() */ - protected function performAdditionalUpdateAction($updatedObject) + protected function performAdditionalUpdateAction($updateEvent) { $attr_values = $this->getRequest()->get('attribute_values', null); @@ -123,6 +123,8 @@ class AttributeController extends AbstractCrudController $this->dispatch(TheliaEvents::ATTRIBUTE_AV_UPDATE, $event); } } + + return null; } protected function createUpdatePositionEvent($positionChangeMode, $positionValue) diff --git a/core/lib/Thelia/Controller/Admin/BaseAdminController.php b/core/lib/Thelia/Controller/Admin/BaseAdminController.php index 6471dda81..1e0f65055 100755 --- a/core/lib/Thelia/Controller/Admin/BaseAdminController.php +++ b/core/lib/Thelia/Controller/Admin/BaseAdminController.php @@ -40,6 +40,8 @@ use Thelia\Form\BaseForm; use Thelia\Form\Exception\FormValidationException; use Thelia\Log\Tlog; use Symfony\Component\Routing\Router; +use Thelia\Model\Admin; +use Thelia\Core\Security\Token\CookieTokenProvider; class BaseAdminController extends BaseController { @@ -302,6 +304,46 @@ class BaseAdminController extends BaseController return $order; } + /** + * Create the remember me cookie for the given user. + */ + protected function createAdminRememberMeCookie(Admin $user) + { + $ctp = new CookieTokenProvider(); + + $cookieName = ConfigQuery::read('admin_remember_me_cookie_name', 'armcn'); + $cookieExpiration = ConfigQuery::read('admin_remember_me_cookie_expiration', 2592000 /* 1 month */); + + $ctp->createCookie($user, $cookieName, $cookieExpiration); + } + + /** + * Get the rememberme key from the cookie. + * + * @return string hte key found, or null if no key was found. + */ + protected function getRememberMeKeyFromCookie() + { + // Check if we can authenticate the user with a cookie-based token + $cookieName = ConfigQuery::read('admin_remember_me_cookie_name', 'armcn'); + + $ctp = new CookieTokenProvider(); + + return $ctp->getKeyFromCookie($this->getRequest(), $cookieName); + } + + /** Clear the remember me cookie. + * + */ + protected function clearRememberMeCookie() { + + $ctp = new CookieTokenProvider(); + + $cookieName = ConfigQuery::read('admin_remember_me_cookie_name', 'armcn'); + + $ctp->clearCookie($cookieName); + } + /** * Render the given template, and returns the result as an Http Response. * diff --git a/core/lib/Thelia/Controller/Admin/SessionController.php b/core/lib/Thelia/Controller/Admin/SessionController.php index 81f366ddf..120a28b26 100755 --- a/core/lib/Thelia/Controller/Admin/SessionController.php +++ b/core/lib/Thelia/Controller/Admin/SessionController.php @@ -30,11 +30,44 @@ use Thelia\Core\Security\Exception\AuthenticationException; use Thelia\Tools\URL; use Thelia\Tools\Redirect; use Thelia\Core\Event\TheliaEvents; +use Thelia\Core\Security\Authentication\AdminTokenAuthenticator; +use Thelia\Core\Security\UserProvider\TokenProvider; +use Symfony\Component\HttpFoundation\Cookie; +use Thelia\Core\Security\UserProvider\CookieTokenProvider; +use Thelia\Core\Security\Exception\TokenAuthenticationException; class SessionController extends BaseAdminController { public function showLoginAction() { + // Check if we can authenticate the user with a cookie-based token + if (null !== $key = $this->getRememberMeKeyFromCookie()) { + + // Create the authenticator + $authenticator = new AdminTokenAuthenticator($key); + + try { + // If have found a user, store it in the security context + $user = $authenticator->getAuthentifiedUser(); + + $this->getSecurityContext()->setAdminUser($user); + + $this->adminLogAppend("Successful token authentication"); + + // Update the cookie + $cookie = $this->createAdminRememberMeCookie($user); + + // Render the home page + return $this->render("home"); + } + catch (TokenAuthenticationException $ex) { + $this->adminLogAppend("Token based authentication failed."); + + // Clear the cookie + $this->clearRememberMeCookie(); + } + } + return $this->render("login"); } @@ -44,6 +77,9 @@ class SessionController extends BaseAdminController $this->getSecurityContext()->clearAdminUser(); + // Clear the remember me cookie, if any + $this->clearRememberMeCookie(); + // Go back to login page. $this->redirectToRoute('admin.login'); } @@ -68,10 +104,19 @@ class SessionController extends BaseAdminController // Log authentication success AdminLog::append("Authentication successful", $request, $user); + /** + * FIXME: we have tou find a way to send cookie + */ + if (intval($adminLoginForm->getForm()->get('remember_me')->getData()) > 0) { + // If a remember me field if present and set in the form, create + // the cookie thant store "remember me" information + $this->createAdminRememberMeCookie($user); + } + $this->dispatch(TheliaEvents::ADMIN_LOGIN); - // Redirect to the success URL - return Redirect::exec($adminLoginForm->getSuccessUrl()); + // Redirect to the success URL, passing the cookie if one exists. + $this->redirect($adminLoginForm->getSuccessUrl()); } catch (FormValidationException $ex) { diff --git a/core/lib/Thelia/Controller/Admin/TemplateController.php b/core/lib/Thelia/Controller/Admin/TemplateController.php new file mode 100644 index 000000000..aafc56e4b --- /dev/null +++ b/core/lib/Thelia/Controller/Admin/TemplateController.php @@ -0,0 +1,196 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Controller\Admin; + +use Thelia\Core\Event\TemplateDeleteEvent; +use Thelia\Core\Event\TheliaEvents; +use Thelia\Core\Event\TemplateUpdateEvent; +use Thelia\Core\Event\TemplateCreateEvent; +use Thelia\Model\TemplateQuery; +use Thelia\Form\TemplateModificationForm; +use Thelia\Form\TemplateCreationForm; +use Thelia\Core\Event\UpdatePositionEvent; +use Thelia\Model\TemplateAv; +use Thelia\Model\TemplateAvQuery; +use Thelia\Core\Event\TemplateAvUpdateEvent; +use Thelia\Core\Event\TemplateEvent; + +/** + * Manages templates sent by mail + * + * @author Franck Allimant + */ +class TemplateController extends AbstractCrudController +{ + public function __construct() + { + parent::__construct( + 'template', + null, + null, + + 'admin.configuration.templates.view', + 'admin.configuration.templates.create', + 'admin.configuration.templates.update', + 'admin.configuration.templates.delete', + + TheliaEvents::TEMPLATE_CREATE, + TheliaEvents::TEMPLATE_UPDATE, + TheliaEvents::TEMPLATE_DELETE, + null, // No visibility toggle + null // No position update + ); + } + + protected function getCreationForm() + { + return new TemplateCreationForm($this->getRequest()); + } + + protected function getUpdateForm() + { + return new TemplateModificationForm($this->getRequest()); + } + + protected function getCreationEvent($formData) + { + $createEvent = new TemplateCreateEvent(); + + $createEvent + ->setTemplateName($formData['name']) + ->setLocale($formData["locale"]) + ; + + return $createEvent; + } + + protected function getUpdateEvent($formData) + { + $changeEvent = new TemplateUpdateEvent($formData['id']); + + // Create and dispatch the change event + $changeEvent + ->setLocale($formData["locale"]) + ->setTemplateName($formData['name']) + ; + + // Add feature and attributes list + + return $changeEvent; + } + + protected function getDeleteEvent() + { + return new TemplateDeleteEvent($this->getRequest()->get('template_id')); + } + + protected function eventContainsObject($event) + { + return $event->hasTemplate(); + } + + protected function hydrateObjectForm($object) + { + + $data = array( + 'id' => $object->getId(), + 'locale' => $object->getLocale(), + 'name' => $object->getName() + ); + + // Setup the object form + return new TemplateModificationForm($this->getRequest(), "form", $data); + } + + protected function getObjectFromEvent($event) + { + return $event->hasTemplate() ? $event->getTemplate() : null; + } + + protected function getExistingObject() + { + return TemplateQuery::create() + ->joinWithI18n($this->getCurrentEditionLocale()) + ->findOneById($this->getRequest()->get('template_id')); + } + + protected function getObjectLabel($object) + { + return $object->getName(); + } + + protected function getObjectId($object) + { + return $object->getId(); + } + + protected function renderListTemplate($currentOrder) + { + return $this->render('templates', array('order' => $currentOrder)); + } + + protected function renderEditionTemplate() + { + return $this->render( + 'template-edit', + array( + 'template_id' => $this->getRequest()->get('template_id'), + ) + ); + } + + protected function redirectToEditionTemplate() + { + $this->redirectToRoute( + "admin.configuration.templates.update", + array( + 'template_id' => $this->getRequest()->get('template_id'), + ) + ); + } + + protected function redirectToListTemplate() + { + $this->redirectToRoute('admin.configuration.templates.default'); + } + + // Process delete failure, which may occurs if template is in use. + protected function performAdditionalDeleteAction($deleteEvent) + { + if ($deleteEvent->getProductCount() > 0) { + + $this->getParserContext()->setGeneralError( + $this->getTranslator()->trans( + "This template is in use in some of your products, and cannot be deleted. Delete it from all your products and try again." + ) + ); + + return $this->renderList(); + } + + // Normal delete processing + return null; + } + +} \ No newline at end of file diff --git a/core/lib/Thelia/Controller/BaseController.php b/core/lib/Thelia/Controller/BaseController.php index 56118635b..bd1e68422 100755 --- a/core/lib/Thelia/Controller/BaseController.php +++ b/core/lib/Thelia/Controller/BaseController.php @@ -198,9 +198,9 @@ class BaseController extends ContainerAware * * @param string $url */ - public function redirect($url, $status = 302) + public function redirect($url, $status = 302, $cookies = array()) { - Redirect::exec($url, $status); + Redirect::exec($url, $status, $cookies); } /** diff --git a/core/lib/Thelia/Core/Event/TemplateCreateEvent.php b/core/lib/Thelia/Core/Event/TemplateCreateEvent.php new file mode 100644 index 000000000..b966ce09b --- /dev/null +++ b/core/lib/Thelia/Core/Event/TemplateCreateEvent.php @@ -0,0 +1,54 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; + +class TemplateCreateEvent extends TemplateEvent +{ + protected $template_name; + protected $locale; + + public function getLocale() + { + return $this->locale; + } + + public function setLocale($locale) + { + $this->locale = $locale; + + return $this; + } + + public function getTemplateName() + { + return $this->template_name; + } + + public function setTemplateName($template_name) + { + $this->template_name = $template_name; + + return $this; + } +} diff --git a/core/lib/Thelia/Core/Event/TemplateDeleteEvent.php b/core/lib/Thelia/Core/Event/TemplateDeleteEvent.php new file mode 100644 index 000000000..de504cc98 --- /dev/null +++ b/core/lib/Thelia/Core/Event/TemplateDeleteEvent.php @@ -0,0 +1,59 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; + +class TemplateDeleteEvent extends TemplateEvent +{ + protected $template_id; + protected $product_count; + + public function __construct($template_id) + { + $this->setTemplateId($template_id); + } + + public function getTemplateId() + { + return $this->template_id; + } + + public function setTemplateId($template_id) + { + $this->template_id = $template_id; + + return $this; + } + + public function getProductCount() + { + return $this->product_count; + } + + public function setProductCount($product_count) + { + $this->product_count = $product_count; + + return $this; + } +} diff --git a/core/lib/Thelia/Core/Event/TemplateEvent.php b/core/lib/Thelia/Core/Event/TemplateEvent.php new file mode 100644 index 000000000..96945189e --- /dev/null +++ b/core/lib/Thelia/Core/Event/TemplateEvent.php @@ -0,0 +1,52 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; +use Thelia\Model\Template; + +class TemplateEvent extends ActionEvent +{ + protected $template = null; + + public function __construct(Template $template = null) + { + $this->template = $template; + } + + public function hasTemplate() + { + return ! is_null($this->template); + } + + public function getTemplate() + { + return $this->template; + } + + public function setTemplate($template) + { + $this->template = $template; + + return $this; + } +} diff --git a/core/lib/Thelia/Core/Event/TemplateUpdateEvent.php b/core/lib/Thelia/Core/Event/TemplateUpdateEvent.php new file mode 100644 index 000000000..bae8ec7da --- /dev/null +++ b/core/lib/Thelia/Core/Event/TemplateUpdateEvent.php @@ -0,0 +1,71 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; + +class TemplateUpdateEvent extends TemplateCreateEvent +{ + protected $template_id; + + protected $feature_list; + protected $attribute_list; + + public function __construct($template_id) + { + $this->setTemplateId($template_id); + } + + public function getTemplateId() + { + return $this->template_id; + } + + public function setTemplateId($template_id) + { + $this->template_id = $template_id; + + return $this; + } + + public function getFeatureList() + { + return $this->feature_list; + } + + public function setFeatureList($feature_list) + { + $this->feature_list = $feature_list; + return $this; + } + + public function getAttributeList() + { + return $this->attribute_list; + } + + public function setAttributeList($attribute_list) + { + $this->attribute_list = $attribute_list; + return $this; + } +} diff --git a/core/lib/Thelia/Core/Security/Authentication/AdminTokenAuthenticator.php b/core/lib/Thelia/Core/Security/Authentication/AdminTokenAuthenticator.php new file mode 100644 index 000000000..4c6dcec5c --- /dev/null +++ b/core/lib/Thelia/Core/Security/Authentication/AdminTokenAuthenticator.php @@ -0,0 +1,37 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Security\Authentication; + +use Thelia\Core\Security\UserProvider\AdminTokenUserProvider; + +class AdminTokenAuthenticator extends TokenAuthenticator +{ + public function __construct($key) + { + parent::__construct( + $key, + new AdminTokenUserProvider() + ); + } +} diff --git a/core/lib/Thelia/Core/Security/Authentication/CustomerTokenAuthenticator.php b/core/lib/Thelia/Core/Security/Authentication/CustomerTokenAuthenticator.php new file mode 100644 index 000000000..d06400875 --- /dev/null +++ b/core/lib/Thelia/Core/Security/Authentication/CustomerTokenAuthenticator.php @@ -0,0 +1,37 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Security\Authentication; + +use Thelia\Core\Security\UserProvider\CustomerTokenUserProvider; + +class CustomerTokenAuthenticator extends TokenAuthenticator +{ + public function __construct($key) + { + parent::__construct( + $key, + new CustomerTokenUserProvider() + ); + } +} diff --git a/core/lib/Thelia/Core/Security/Authentication/TokenAuthenticator.php b/core/lib/Thelia/Core/Security/Authentication/TokenAuthenticator.php new file mode 100644 index 000000000..1c8c11c73 --- /dev/null +++ b/core/lib/Thelia/Core/Security/Authentication/TokenAuthenticator.php @@ -0,0 +1,57 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Security\Authentication; + +use Thelia\Core\Security\Authentication\AuthenticatorInterface; +use Thelia\Core\Security\UserProvider\UserProviderInterface; +use Thelia\Core\Security\UserProvider\TokenUserProvider; +use Thelia\Core\Security\Exception\TokenAuthenticationException; + +class TokenAuthenticator implements AuthenticatorInterface +{ + protected $key; + + protected $userProvider; + + public function __construct($key, TokenUserProvider $userProvider) + { + $this->key = $key; + + $this->userProvider = $userProvider; + } + + /** + * @see \Thelia\Core\Security\Authentication\AuthenticatorInterface::getAuthentifiedUser() + */ + public function getAuthentifiedUser() + { + $keyData = $this->userProvider->decodeKey($this->key); + + $user = $this->userProvider->getUser($keyData); + + if ($user === null) throw new TokenAuthenticationException("No user matches the provided token"); + + return $user; + } +} diff --git a/core/lib/Thelia/Core/Security/Exception/TokenAuthenticationException.php b/core/lib/Thelia/Core/Security/Exception/TokenAuthenticationException.php new file mode 100644 index 000000000..6af57162d --- /dev/null +++ b/core/lib/Thelia/Core/Security/Exception/TokenAuthenticationException.php @@ -0,0 +1,28 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Security\Exception; + +class TokenAuthenticationException extends \Exception +{ +} diff --git a/core/lib/Thelia/Core/Security/Token/CookieTokenProvider.php b/core/lib/Thelia/Core/Security/Token/CookieTokenProvider.php new file mode 100644 index 000000000..ee2d9291a --- /dev/null +++ b/core/lib/Thelia/Core/Security/Token/CookieTokenProvider.php @@ -0,0 +1,55 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Security\Token; + +use Thelia\Core\HttpFoundation\Request; +use Thelia\Core\Security\User\UserInterface; + +class CookieTokenProvider +{ + public function getKeyFromCookie(Request $request, $cookieName) + { + if ($request->cookies->has($cookieName)) { + + // Create the authenticator + return $request->cookies->get($cookieName); + } + + return null; + } + + public function createCookie(UserInterface $user, $cookieName, $cookieExpires) + { + $tokenProvider = new TokenProvider(); + + $key = $tokenProvider->encodeKey($user); + + setcookie($cookieName, $key, time() + $cookieExpires, '/'); + } + + public function clearCookie($cookieName) + { + setcookie($cookieName, '', time() - 3600, '/'); + } +} diff --git a/core/lib/Thelia/Core/Security/Token/TokenProvider.php b/core/lib/Thelia/Core/Security/Token/TokenProvider.php new file mode 100644 index 000000000..e50b60602 --- /dev/null +++ b/core/lib/Thelia/Core/Security/Token/TokenProvider.php @@ -0,0 +1,27 @@ +setToken(uniqid()); + + return base64_encode(serialize( + array($user->getUsername(), $user->getToken(), $user->getSerial()))); + } + + public function decodeKey($key) { + $data = unserialize(base64_decode($key)); + + return array( + 'username' => $data[0], + 'token' => $data[1], + 'serial' => $data[2] + ); + } +} diff --git a/core/lib/Thelia/Core/Security/User/UserInterface.php b/core/lib/Thelia/Core/Security/User/UserInterface.php index 12e07f431..cdff4d44e 100755 --- a/core/lib/Thelia/Core/Security/User/UserInterface.php +++ b/core/lib/Thelia/Core/Security/User/UserInterface.php @@ -48,4 +48,24 @@ interface UserInterface * @return void */ public function eraseCredentials(); -} + + /** + * return the user token (used by remember me authnetication system) + */ + public function getToken(); + + /** + * Set a token in the user data (used by remember me authnetication system) + */ + public function setToken($token); + + /** + * return the user serial (used by remember me authnetication system) + */ + public function getSerial(); + + /** + * Set a serial number int the user data (used by remember me authnetication system) + */ + public function setSerial($serial); +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Security/UserProvider/AdminTokenUserProvider.php b/core/lib/Thelia/Core/Security/UserProvider/AdminTokenUserProvider.php new file mode 100644 index 000000000..4567176e5 --- /dev/null +++ b/core/lib/Thelia/Core/Security/UserProvider/AdminTokenUserProvider.php @@ -0,0 +1,39 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Security\UserProvider; + +use Thelia\Model\Admin; +use Thelia\Model\AdminQuery; + +class AdminTokenUserProvider extends TokenUserProvider +{ + public function getUser($dataArray) { + + return AdminQuery::create() + ->filterByLogin($dataArray['username']) + ->filterByRememberMeSerial($dataArray['serial']) + ->filterByRememberMeToken($dataArray['token']) + ->findOne(); + } +} diff --git a/core/lib/Thelia/Core/Security/UserProvider/AdminUserProvider.php b/core/lib/Thelia/Core/Security/UserProvider/AdminUserProvider.php index a889053c4..a6147fca4 100755 --- a/core/lib/Thelia/Core/Security/UserProvider/AdminUserProvider.php +++ b/core/lib/Thelia/Core/Security/UserProvider/AdminUserProvider.php @@ -1,4 +1,26 @@ . */ +/* */ +/*************************************************************************************/ + namespace Thelia\Core\Security\UserProvider; use Thelia\Model\Admin; diff --git a/core/lib/Thelia/Core/Security/UserProvider/CustomerTokenUserProvider.php b/core/lib/Thelia/Core/Security/UserProvider/CustomerTokenUserProvider.php new file mode 100644 index 000000000..421d48dd4 --- /dev/null +++ b/core/lib/Thelia/Core/Security/UserProvider/CustomerTokenUserProvider.php @@ -0,0 +1,39 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Security\UserProvider; + +use Thelia\Action\Customer; +use Thelia\Model\CustomerQuery; + +class CustomerTokenUserProvider extends TokenUserProvider +{ + public function getUser($dataArray) { + + return CustomerQuery::create() + ->filterByEmail($dataArray['username']) + ->filterByRememberMeSerial($dataArray['serial']) + ->filterByRememberMeToken($dataArray['token']) + ->findOne(); + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Security/UserProvider/CustomerUserProvider.php b/core/lib/Thelia/Core/Security/UserProvider/CustomerUserProvider.php index 371af73fc..21db28cab 100755 --- a/core/lib/Thelia/Core/Security/UserProvider/CustomerUserProvider.php +++ b/core/lib/Thelia/Core/Security/UserProvider/CustomerUserProvider.php @@ -1,4 +1,26 @@ . */ +/* */ +/*************************************************************************************/ + namespace Thelia\Core\Security\UserProvider; use Thelia\Action\Customer; @@ -13,4 +35,4 @@ class CustomerUserProvider implements UserProviderInterface return $customer; } -} +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Security/UserProvider/TokenUserProvider.php b/core/lib/Thelia/Core/Security/UserProvider/TokenUserProvider.php new file mode 100644 index 000000000..6c46bcbbb --- /dev/null +++ b/core/lib/Thelia/Core/Security/UserProvider/TokenUserProvider.php @@ -0,0 +1,32 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Security\UserProvider; + +use Thelia\Core\Security\User\UserInterface; +use Thelia\Core\Security\Token\TokenProvider; + +abstract class TokenUserProvider extends TokenProvider implements UserProviderInterface +{ + public abstract function getUser($key); +} diff --git a/core/lib/Thelia/Core/Security/UserProvider/UserProviderInterface.php b/core/lib/Thelia/Core/Security/UserProvider/UserProviderInterface.php index dd4232ade..6fe5e5197 100755 --- a/core/lib/Thelia/Core/Security/UserProvider/UserProviderInterface.php +++ b/core/lib/Thelia/Core/Security/UserProvider/UserProviderInterface.php @@ -1,4 +1,25 @@ . */ +/* */ +/*************************************************************************************/ namespace Thelia\Core\Security\UserProvider; diff --git a/core/lib/Thelia/Core/Template/Loop/Attribute.php b/core/lib/Thelia/Core/Template/Loop/Attribute.php index cb3a25e17..db9eb9b8f 100755 --- a/core/lib/Thelia/Core/Template/Loop/Attribute.php +++ b/core/lib/Thelia/Core/Template/Loop/Attribute.php @@ -38,6 +38,9 @@ use Thelia\Model\Map\ProductCategoryTableMap; use Thelia\Type\TypeCollection; use Thelia\Type; use Thelia\Type\BooleanOrBothType; +use Thelia\Model\ProductQuery; +use Thelia\Model\TemplateQuery; +use Thelia\Model\AttributeTemplateQuery; /** * @@ -60,8 +63,7 @@ class Attribute extends BaseI18nLoop return new ArgumentCollection( Argument::createIntListTypeArgument('id'), Argument::createIntListTypeArgument('product'), - Argument::createIntListTypeArgument('category'), - Argument::createBooleanOrBothTypeArgument('visible', 1), + Argument::createIntListTypeArgument('template'), Argument::createIntListTypeArgument('exclude'), new Argument( 'order', @@ -101,26 +103,23 @@ class Attribute extends BaseI18nLoop $search->filterById($exclude, Criteria::NOT_IN); } - $visible = $this->getVisible(); - - if ($visible != BooleanOrBothType::ANY) $search->filterByVisible($visible); - $product = $this->getProduct(); - $category = $this->getCategory(); + $template = $this->getTemplate(); if (null !== $product) { - $productCategories = ProductCategoryQuery::create()->select(array(ProductCategoryTableMap::CATEGORY_ID))->filterByProductId($product, Criteria::IN)->find()->getData(); + // Find the template assigned to the product. + $productObj = ProductQuery::create()->findPk($product); - if (null === $category) { - $category = $productCategories; - } else { - $category = array_merge($category, $productCategories); - } - } + // Ignore if the product cannot be found. + if ($productObj !== null) + $template = $productObj->getTemplate(); + } - if (null !== $category) { - $search->filterByCategory( - CategoryQuery::create()->filterById($category)->find(), + + // If we have to filter by template, find all attributes assigned to this template, and filter by found IDs + if (null !== $template) { + $search->filterById( + AttributeTemplateQuery::create()->filterByTemplateId($template)->select('id')->find(), Criteria::IN ); } diff --git a/core/lib/Thelia/Core/Template/Loop/Template.php b/core/lib/Thelia/Core/Template/Loop/Template.php new file mode 100644 index 000000000..db8bca7ee --- /dev/null +++ b/core/lib/Thelia/Core/Template/Loop/Template.php @@ -0,0 +1,114 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Template\Loop; + +use Propel\Runtime\ActiveQuery\Criteria; +use Thelia\Core\Template\Element\BaseI18nLoop; +use Thelia\Core\Template\Element\LoopResult; +use Thelia\Core\Template\Element\LoopResultRow; + +use Thelia\Core\Template\Loop\Argument\ArgumentCollection; +use Thelia\Core\Template\Loop\Argument\Argument; + +use Thelia\Model\Base\CategoryQuery; +use Thelia\Model\Base\ProductCategoryQuery; +use Thelia\Model\Base\TemplateQuery; +use Thelia\Model\Map\ProductCategoryTableMap; +use Thelia\Type\TypeCollection; +use Thelia\Type; +use Thelia\Type\BooleanOrBothType; + +/** + * + * Template loop + * + * + * Class Template + * @package Thelia\Core\Template\Loop + * @author Etienne Roudeix + */ +class Template extends BaseI18nLoop +{ + public $timestampable = true; + + /** + * @return ArgumentCollection + */ + protected function getArgDefinitions() + { + return new ArgumentCollection( + Argument::createIntListTypeArgument('id'), + Argument::createIntListTypeArgument('exclude') + ); + } + + /** + * @param $pagination + * + * @return \Thelia\Core\Template\Element\LoopResult + */ + public function exec(&$pagination) + { + $search = TemplateQuery::create(); + + $backendContext = $this->getBackend_context(); + + $lang = $this->getLang(); + + /* manage translations */ + $locale = $this->configureI18nProcessing($search, $columns = array('NAME')); + + $id = $this->getId(); + + if (null !== $id) { + $search->filterById($id, Criteria::IN); + } + + $exclude = $this->getExclude(); + + if (null !== $exclude) { + $search->filterById($exclude, Criteria::NOT_IN); + } + + /* perform search */ + $templates = $this->search($search, $pagination); + + $loopResult = new LoopResult($templates); + + foreach ($templates as $template) { + $loopResultRow = new LoopResultRow($loopResult, $template, $this->versionable, $this->timestampable, $this->countable); + + $loopResultRow + ->set("ID", $template->getId()) + ->set("IS_TRANSLATED" , $template->getVirtualColumn('IS_TRANSLATED')) + ->set("LOCALE" , $locale) + ->set("NAME" , $template->getVirtualColumn('i18n_NAME')) + ; + + $loopResult->addRow($loopResultRow); + } + + return $loopResult; + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php index 2d5324644..4c953be3c 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php @@ -145,7 +145,7 @@ class Form extends AbstractSmartyPlugin public function renderFormField($params, $content, \Smarty_Internal_Template $template, &$repeat) { - if ($repeat) { + if ($repeat) { $formFieldView = $this->getFormFieldView($params); @@ -153,25 +153,25 @@ class Form extends AbstractSmartyPlugin $value = $formFieldView->vars["value"]; /* FIXME: doesnt work. We got "This form should not contain extra fields." error. - // We have a collection - if (is_array($value)) { +// We have a collection +if (is_array($value)) { - $key = $this->getParam($params, 'value_key'); +$key = $this->getParam($params, 'value_key'); - if ($key != null) { +if ($key != null) { - if (isset($value[$key])) { +if (isset($value[$key])) { - $name = sprintf("%s[%s]", $formFieldView->vars["full_name"], $key); - $val = $value[$key]; +$name = sprintf("%s[%s]", $formFieldView->vars["full_name"], $key); +$val = $value[$key]; - $this->assignFieldValues($template, $name, $val, $formFieldView->vars); - } - } - } - else { - $this->assignFieldValues($template, $formFieldView->vars["full_name"], $fieldVars["value"], $formFieldView->vars); - } +$this->assignFieldValues($template, $name, $val, $formFieldView->vars); +} +} +} +else { +$this->assignFieldValues($template, $formFieldView->vars["full_name"], $fieldVars["value"], $formFieldView->vars); +} */ $this->assignFieldValues($template, $formFieldView->vars["full_name"], $formFieldView->vars["value"], $formFieldView->vars); diff --git a/core/lib/Thelia/Core/TheliaHttpKernel.php b/core/lib/Thelia/Core/TheliaHttpKernel.php index cf1d35195..446983363 100755 --- a/core/lib/Thelia/Core/TheliaHttpKernel.php +++ b/core/lib/Thelia/Core/TheliaHttpKernel.php @@ -212,7 +212,7 @@ class TheliaHttpKernel extends HttpKernel if (Model\ConfigQuery::read("session_config.default")) { $storage->setSaveHandler(new Session\Storage\Handler\NativeFileSessionHandler(Model\ConfigQuery::read("session_config.save_path", THELIA_ROOT . '/local/session/'))); } else { - $handlerString = Model\ConfigQuery::read("session_config.handlers"); + $handlerString = Model\ConfigQuery::read("session_config.handlers", 'Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeFileSessionHandler'); $handler = new $handlerString; diff --git a/core/lib/Thelia/Form/TemplateCreationForm.php b/core/lib/Thelia/Form/TemplateCreationForm.php new file mode 100644 index 000000000..42e6db5a4 --- /dev/null +++ b/core/lib/Thelia/Form/TemplateCreationForm.php @@ -0,0 +1,57 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form; + +use Symfony\Component\Validator\Constraints; +use Thelia\Model\CurrencyQuery; +use Symfony\Component\Validator\ExecutionContextInterface; +use Symfony\Component\Validator\Constraints\NotBlank; +use Thelia\Core\Translation\Translator; + +class TemplateCreationForm extends BaseForm +{ + protected function buildForm() + { + $this->formBuilder + ->add("name" , "text" , array( + "constraints" => array( + new NotBlank() + ), + "label" => Translator::getInstance()->trans("Template Name *"), + "label_attr" => array( + "for" => "name" + )) + ) + ->add("locale" , "text" , array( + "constraints" => array( + new NotBlank() + )) + ) + ; + } + + public function getName() + { + return "thelia_template_creation"; + } +} diff --git a/core/lib/Thelia/Form/TemplateModificationForm.php b/core/lib/Thelia/Form/TemplateModificationForm.php new file mode 100644 index 000000000..b2b50a3ca --- /dev/null +++ b/core/lib/Thelia/Form/TemplateModificationForm.php @@ -0,0 +1,67 @@ +. */ +/* */ +/*************************************************************************************/ +namespace Thelia\Form; + +use Symfony\Component\Validator\Constraints; +use Thelia\Model\CurrencyQuery; +use Symfony\Component\Validator\ExecutionContextInterface; +use Symfony\Component\Validator\Constraints\NotBlank; +use Thelia\Core\Translation\Translator; +use Symfony\Component\Validator\Constraints\GreaterThan; + +class TemplateModificationForm extends TemplateCreationForm +{ + use StandardDescriptionFieldsTrait; + + protected function buildForm() + { + parent::buildForm(); + + $this->formBuilder + ->add("id", "hidden", array( + "constraints" => array( + new GreaterThan( + array('value' => 0) + ) + ) + )) +/* + ->add('attributes', 'collection', array( + 'type' => 'text', + 'options' => array('required' => false) + )) +*/ +/* FIXME: doesn't work + ->add('features', 'collection', array( + 'type' => 'text', + 'options' => array('required' => false) + )) +*/ + ; + } + + public function getName() + { + return "thelia_template_modification"; + } +} diff --git a/core/lib/Thelia/Model/Admin.php b/core/lib/Thelia/Model/Admin.php index a6deb7e60..67f6a5928 100755 --- a/core/lib/Thelia/Model/Admin.php +++ b/core/lib/Thelia/Model/Admin.php @@ -6,6 +6,7 @@ use Thelia\Core\Security\User\UserInterface; use Thelia\Core\Security\Role\Role; use Thelia\Model\Base\Admin as BaseAdmin; +use Propel\Runtime\Connection\ConnectionInterface; /** * Skeleton subclass for representing a row from the 'admin' table. @@ -20,6 +21,16 @@ use Thelia\Model\Base\Admin as BaseAdmin; */ class Admin extends BaseAdmin implements UserInterface { + /** + * {@inheritDoc} + */ + public function preInsert(ConnectionInterface $con = null) + { + // Set the serial number (for auto-login) + $this->setRememberMeSerial(uniqid()); + + return true; + } public function setPassword($password) { @@ -65,4 +76,32 @@ class Admin extends BaseAdmin implements UserInterface public function getRoles() { return array(new Role('ADMIN')); } + + /** + * {@inheritDoc} + */ + public function getToken() { + return $this->getRememberMeToken(); + } + + /** + * {@inheritDoc} + */ + public function setToken($token) { + $this->setRememberMeToken($token)->save(); + } + + /** + * {@inheritDoc} + */ + public function getSerial() { + return $this->getRememberMeSerial(); + } + + /** + * {@inheritDoc} + */ + public function setSerial($serial) { + $this->setRememberMeSerial($serial)->save(); + } } diff --git a/core/lib/Thelia/Model/AttributeTemplate.php b/core/lib/Thelia/Model/AttributeTemplate.php new file mode 100644 index 000000000..57b4c3745 --- /dev/null +++ b/core/lib/Thelia/Model/AttributeTemplate.php @@ -0,0 +1,10 @@ +salt; } + /** + * Get the [remember_me_token] column value. + * + * @return string + */ + public function getRememberMeToken() + { + + return $this->remember_me_token; + } + + /** + * Get the [remember_me_serial] column value. + * + * @return string + */ + public function getRememberMeSerial() + { + + return $this->remember_me_serial; + } + /** * Get the [optionally formatted] temporal [created_at] column value. * @@ -662,6 +696,48 @@ abstract class Admin implements ActiveRecordInterface return $this; } // setSalt() + /** + * Set the value of [remember_me_token] column. + * + * @param string $v new value + * @return \Thelia\Model\Admin The current object (for fluent API support) + */ + public function setRememberMeToken($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->remember_me_token !== $v) { + $this->remember_me_token = $v; + $this->modifiedColumns[] = AdminTableMap::REMEMBER_ME_TOKEN; + } + + + return $this; + } // setRememberMeToken() + + /** + * Set the value of [remember_me_serial] column. + * + * @param string $v new value + * @return \Thelia\Model\Admin The current object (for fluent API support) + */ + public function setRememberMeSerial($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->remember_me_serial !== $v) { + $this->remember_me_serial = $v; + $this->modifiedColumns[] = AdminTableMap::REMEMBER_ME_SERIAL; + } + + + return $this; + } // setRememberMeSerial() + /** * Sets the value of [created_at] column to a normalized version of the date/time value specified. * @@ -762,13 +838,19 @@ abstract class Admin implements ActiveRecordInterface $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : AdminTableMap::translateFieldName('Salt', TableMap::TYPE_PHPNAME, $indexType)]; $this->salt = (null !== $col) ? (string) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : AdminTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : AdminTableMap::translateFieldName('RememberMeToken', TableMap::TYPE_PHPNAME, $indexType)]; + $this->remember_me_token = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 8 + $startcol : AdminTableMap::translateFieldName('RememberMeSerial', TableMap::TYPE_PHPNAME, $indexType)]; + $this->remember_me_serial = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 9 + $startcol : AdminTableMap::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 ? 8 + $startcol : AdminTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 10 + $startcol : AdminTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } @@ -781,7 +863,7 @@ abstract class Admin implements ActiveRecordInterface $this->ensureConsistency(); } - return $startcol + 9; // 9 = AdminTableMap::NUM_HYDRATE_COLUMNS. + return $startcol + 11; // 11 = AdminTableMap::NUM_HYDRATE_COLUMNS. } catch (Exception $e) { throw new PropelException("Error populating \Thelia\Model\Admin object", 0, $e); @@ -1069,6 +1151,12 @@ abstract class Admin implements ActiveRecordInterface if ($this->isColumnModified(AdminTableMap::SALT)) { $modifiedColumns[':p' . $index++] = 'SALT'; } + if ($this->isColumnModified(AdminTableMap::REMEMBER_ME_TOKEN)) { + $modifiedColumns[':p' . $index++] = 'REMEMBER_ME_TOKEN'; + } + if ($this->isColumnModified(AdminTableMap::REMEMBER_ME_SERIAL)) { + $modifiedColumns[':p' . $index++] = 'REMEMBER_ME_SERIAL'; + } if ($this->isColumnModified(AdminTableMap::CREATED_AT)) { $modifiedColumns[':p' . $index++] = 'CREATED_AT'; } @@ -1107,6 +1195,12 @@ abstract class Admin implements ActiveRecordInterface case 'SALT': $stmt->bindValue($identifier, $this->salt, PDO::PARAM_STR); break; + case 'REMEMBER_ME_TOKEN': + $stmt->bindValue($identifier, $this->remember_me_token, PDO::PARAM_STR); + break; + case 'REMEMBER_ME_SERIAL': + $stmt->bindValue($identifier, $this->remember_me_serial, 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; @@ -1197,9 +1291,15 @@ abstract class Admin implements ActiveRecordInterface return $this->getSalt(); break; case 7: - return $this->getCreatedAt(); + return $this->getRememberMeToken(); break; case 8: + return $this->getRememberMeSerial(); + break; + case 9: + return $this->getCreatedAt(); + break; + case 10: return $this->getUpdatedAt(); break; default: @@ -1238,8 +1338,10 @@ abstract class Admin implements ActiveRecordInterface $keys[4] => $this->getPassword(), $keys[5] => $this->getAlgo(), $keys[6] => $this->getSalt(), - $keys[7] => $this->getCreatedAt(), - $keys[8] => $this->getUpdatedAt(), + $keys[7] => $this->getRememberMeToken(), + $keys[8] => $this->getRememberMeSerial(), + $keys[9] => $this->getCreatedAt(), + $keys[10] => $this->getUpdatedAt(), ); $virtualColumns = $this->virtualColumns; foreach($virtualColumns as $key => $virtualColumn) @@ -1307,9 +1409,15 @@ abstract class Admin implements ActiveRecordInterface $this->setSalt($value); break; case 7: - $this->setCreatedAt($value); + $this->setRememberMeToken($value); break; case 8: + $this->setRememberMeSerial($value); + break; + case 9: + $this->setCreatedAt($value); + break; + case 10: $this->setUpdatedAt($value); break; } // switch() @@ -1343,8 +1451,10 @@ abstract class Admin implements ActiveRecordInterface if (array_key_exists($keys[4], $arr)) $this->setPassword($arr[$keys[4]]); if (array_key_exists($keys[5], $arr)) $this->setAlgo($arr[$keys[5]]); if (array_key_exists($keys[6], $arr)) $this->setSalt($arr[$keys[6]]); - if (array_key_exists($keys[7], $arr)) $this->setCreatedAt($arr[$keys[7]]); - if (array_key_exists($keys[8], $arr)) $this->setUpdatedAt($arr[$keys[8]]); + if (array_key_exists($keys[7], $arr)) $this->setRememberMeToken($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setRememberMeSerial($arr[$keys[8]]); + if (array_key_exists($keys[9], $arr)) $this->setCreatedAt($arr[$keys[9]]); + if (array_key_exists($keys[10], $arr)) $this->setUpdatedAt($arr[$keys[10]]); } /** @@ -1363,6 +1473,8 @@ abstract class Admin implements ActiveRecordInterface if ($this->isColumnModified(AdminTableMap::PASSWORD)) $criteria->add(AdminTableMap::PASSWORD, $this->password); if ($this->isColumnModified(AdminTableMap::ALGO)) $criteria->add(AdminTableMap::ALGO, $this->algo); if ($this->isColumnModified(AdminTableMap::SALT)) $criteria->add(AdminTableMap::SALT, $this->salt); + if ($this->isColumnModified(AdminTableMap::REMEMBER_ME_TOKEN)) $criteria->add(AdminTableMap::REMEMBER_ME_TOKEN, $this->remember_me_token); + if ($this->isColumnModified(AdminTableMap::REMEMBER_ME_SERIAL)) $criteria->add(AdminTableMap::REMEMBER_ME_SERIAL, $this->remember_me_serial); if ($this->isColumnModified(AdminTableMap::CREATED_AT)) $criteria->add(AdminTableMap::CREATED_AT, $this->created_at); if ($this->isColumnModified(AdminTableMap::UPDATED_AT)) $criteria->add(AdminTableMap::UPDATED_AT, $this->updated_at); @@ -1434,6 +1546,8 @@ abstract class Admin implements ActiveRecordInterface $copyObj->setPassword($this->getPassword()); $copyObj->setAlgo($this->getAlgo()); $copyObj->setSalt($this->getSalt()); + $copyObj->setRememberMeToken($this->getRememberMeToken()); + $copyObj->setRememberMeSerial($this->getRememberMeSerial()); $copyObj->setCreatedAt($this->getCreatedAt()); $copyObj->setUpdatedAt($this->getUpdatedAt()); @@ -1935,6 +2049,8 @@ abstract class Admin implements ActiveRecordInterface $this->password = null; $this->algo = null; $this->salt = null; + $this->remember_me_token = null; + $this->remember_me_serial = null; $this->created_at = null; $this->updated_at = null; $this->alreadyInSave = false; diff --git a/core/lib/Thelia/Model/Base/AdminQuery.php b/core/lib/Thelia/Model/Base/AdminQuery.php index 1ac79b4fe..071832d9b 100644 --- a/core/lib/Thelia/Model/Base/AdminQuery.php +++ b/core/lib/Thelia/Model/Base/AdminQuery.php @@ -28,6 +28,8 @@ use Thelia\Model\Map\AdminTableMap; * @method ChildAdminQuery orderByPassword($order = Criteria::ASC) Order by the password column * @method ChildAdminQuery orderByAlgo($order = Criteria::ASC) Order by the algo column * @method ChildAdminQuery orderBySalt($order = Criteria::ASC) Order by the salt column + * @method ChildAdminQuery orderByRememberMeToken($order = Criteria::ASC) Order by the remember_me_token column + * @method ChildAdminQuery orderByRememberMeSerial($order = Criteria::ASC) Order by the remember_me_serial column * @method ChildAdminQuery orderByCreatedAt($order = Criteria::ASC) Order by the created_at column * @method ChildAdminQuery orderByUpdatedAt($order = Criteria::ASC) Order by the updated_at column * @@ -38,6 +40,8 @@ use Thelia\Model\Map\AdminTableMap; * @method ChildAdminQuery groupByPassword() Group by the password column * @method ChildAdminQuery groupByAlgo() Group by the algo column * @method ChildAdminQuery groupBySalt() Group by the salt column + * @method ChildAdminQuery groupByRememberMeToken() Group by the remember_me_token column + * @method ChildAdminQuery groupByRememberMeSerial() Group by the remember_me_serial column * @method ChildAdminQuery groupByCreatedAt() Group by the created_at column * @method ChildAdminQuery groupByUpdatedAt() Group by the updated_at column * @@ -59,6 +63,8 @@ use Thelia\Model\Map\AdminTableMap; * @method ChildAdmin findOneByPassword(string $password) Return the first ChildAdmin filtered by the password column * @method ChildAdmin findOneByAlgo(string $algo) Return the first ChildAdmin filtered by the algo column * @method ChildAdmin findOneBySalt(string $salt) Return the first ChildAdmin filtered by the salt column + * @method ChildAdmin findOneByRememberMeToken(string $remember_me_token) Return the first ChildAdmin filtered by the remember_me_token column + * @method ChildAdmin findOneByRememberMeSerial(string $remember_me_serial) Return the first ChildAdmin filtered by the remember_me_serial column * @method ChildAdmin findOneByCreatedAt(string $created_at) Return the first ChildAdmin filtered by the created_at column * @method ChildAdmin findOneByUpdatedAt(string $updated_at) Return the first ChildAdmin filtered by the updated_at column * @@ -69,6 +75,8 @@ use Thelia\Model\Map\AdminTableMap; * @method array findByPassword(string $password) Return ChildAdmin objects filtered by the password column * @method array findByAlgo(string $algo) Return ChildAdmin objects filtered by the algo column * @method array findBySalt(string $salt) Return ChildAdmin objects filtered by the salt column + * @method array findByRememberMeToken(string $remember_me_token) Return ChildAdmin objects filtered by the remember_me_token column + * @method array findByRememberMeSerial(string $remember_me_serial) Return ChildAdmin objects filtered by the remember_me_serial column * @method array findByCreatedAt(string $created_at) Return ChildAdmin objects filtered by the created_at column * @method array findByUpdatedAt(string $updated_at) Return ChildAdmin objects filtered by the updated_at column * @@ -159,7 +167,7 @@ abstract class AdminQuery extends ModelCriteria */ protected function findPkSimple($key, $con) { - $sql = 'SELECT ID, FIRSTNAME, LASTNAME, LOGIN, PASSWORD, ALGO, SALT, CREATED_AT, UPDATED_AT FROM admin WHERE ID = :p0'; + $sql = 'SELECT ID, FIRSTNAME, LASTNAME, LOGIN, PASSWORD, ALGO, SALT, REMEMBER_ME_TOKEN, REMEMBER_ME_SERIAL, CREATED_AT, UPDATED_AT FROM admin WHERE ID = :p0'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key, PDO::PARAM_INT); @@ -463,6 +471,64 @@ abstract class AdminQuery extends ModelCriteria return $this->addUsingAlias(AdminTableMap::SALT, $salt, $comparison); } + /** + * Filter the query on the remember_me_token column + * + * Example usage: + * + * $query->filterByRememberMeToken('fooValue'); // WHERE remember_me_token = 'fooValue' + * $query->filterByRememberMeToken('%fooValue%'); // WHERE remember_me_token LIKE '%fooValue%' + * + * + * @param string $rememberMeToken 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 ChildAdminQuery The current query, for fluid interface + */ + public function filterByRememberMeToken($rememberMeToken = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($rememberMeToken)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $rememberMeToken)) { + $rememberMeToken = str_replace('*', '%', $rememberMeToken); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(AdminTableMap::REMEMBER_ME_TOKEN, $rememberMeToken, $comparison); + } + + /** + * Filter the query on the remember_me_serial column + * + * Example usage: + * + * $query->filterByRememberMeSerial('fooValue'); // WHERE remember_me_serial = 'fooValue' + * $query->filterByRememberMeSerial('%fooValue%'); // WHERE remember_me_serial LIKE '%fooValue%' + * + * + * @param string $rememberMeSerial 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 ChildAdminQuery The current query, for fluid interface + */ + public function filterByRememberMeSerial($rememberMeSerial = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($rememberMeSerial)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $rememberMeSerial)) { + $rememberMeSerial = str_replace('*', '%', $rememberMeSerial); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(AdminTableMap::REMEMBER_ME_SERIAL, $rememberMeSerial, $comparison); + } + /** * Filter the query on the created_at column * diff --git a/core/lib/Thelia/Model/Base/Attribute.php b/core/lib/Thelia/Model/Base/Attribute.php index 3c754c3b5..64e765fdd 100644 --- a/core/lib/Thelia/Model/Base/Attribute.php +++ b/core/lib/Thelia/Model/Base/Attribute.php @@ -20,15 +20,15 @@ use Propel\Runtime\Util\PropelDateTime; use Thelia\Model\Attribute as ChildAttribute; use Thelia\Model\AttributeAv as ChildAttributeAv; use Thelia\Model\AttributeAvQuery as ChildAttributeAvQuery; -use Thelia\Model\AttributeCategory as ChildAttributeCategory; -use Thelia\Model\AttributeCategoryQuery as ChildAttributeCategoryQuery; use Thelia\Model\AttributeCombination as ChildAttributeCombination; use Thelia\Model\AttributeCombinationQuery as ChildAttributeCombinationQuery; use Thelia\Model\AttributeI18n as ChildAttributeI18n; use Thelia\Model\AttributeI18nQuery as ChildAttributeI18nQuery; use Thelia\Model\AttributeQuery as ChildAttributeQuery; -use Thelia\Model\Category as ChildCategory; -use Thelia\Model\CategoryQuery as ChildCategoryQuery; +use Thelia\Model\AttributeTemplate as ChildAttributeTemplate; +use Thelia\Model\AttributeTemplateQuery as ChildAttributeTemplateQuery; +use Thelia\Model\Template as ChildTemplate; +use Thelia\Model\TemplateQuery as ChildTemplateQuery; use Thelia\Model\Map\AttributeTableMap; abstract class Attribute implements ActiveRecordInterface @@ -102,10 +102,10 @@ abstract class Attribute implements ActiveRecordInterface protected $collAttributeCombinationsPartial; /** - * @var ObjectCollection|ChildAttributeCategory[] Collection to store aggregation of ChildAttributeCategory objects. + * @var ObjectCollection|ChildAttributeTemplate[] Collection to store aggregation of ChildAttributeTemplate objects. */ - protected $collAttributeCategories; - protected $collAttributeCategoriesPartial; + protected $collAttributeTemplates; + protected $collAttributeTemplatesPartial; /** * @var ObjectCollection|ChildAttributeI18n[] Collection to store aggregation of ChildAttributeI18n objects. @@ -114,9 +114,9 @@ abstract class Attribute implements ActiveRecordInterface protected $collAttributeI18nsPartial; /** - * @var ChildCategory[] Collection to store aggregation of ChildCategory objects. + * @var ChildTemplate[] Collection to store aggregation of ChildTemplate objects. */ - protected $collCategories; + protected $collTemplates; /** * Flag to prevent endless save loop, if this object is referenced @@ -144,7 +144,7 @@ abstract class Attribute implements ActiveRecordInterface * An array of objects scheduled for deletion. * @var ObjectCollection */ - protected $categoriesScheduledForDeletion = null; + protected $templatesScheduledForDeletion = null; /** * An array of objects scheduled for deletion. @@ -162,7 +162,7 @@ abstract class Attribute implements ActiveRecordInterface * An array of objects scheduled for deletion. * @var ObjectCollection */ - protected $attributeCategoriesScheduledForDeletion = null; + protected $attributeTemplatesScheduledForDeletion = null; /** * An array of objects scheduled for deletion. @@ -697,11 +697,11 @@ abstract class Attribute implements ActiveRecordInterface $this->collAttributeCombinations = null; - $this->collAttributeCategories = null; + $this->collAttributeTemplates = null; $this->collAttributeI18ns = null; - $this->collCategories = null; + $this->collTemplates = null; } // if (deep) } @@ -835,29 +835,29 @@ abstract class Attribute implements ActiveRecordInterface $this->resetModified(); } - if ($this->categoriesScheduledForDeletion !== null) { - if (!$this->categoriesScheduledForDeletion->isEmpty()) { + if ($this->templatesScheduledForDeletion !== null) { + if (!$this->templatesScheduledForDeletion->isEmpty()) { $pks = array(); $pk = $this->getPrimaryKey(); - foreach ($this->categoriesScheduledForDeletion->getPrimaryKeys(false) as $remotePk) { - $pks[] = array($remotePk, $pk); + foreach ($this->templatesScheduledForDeletion->getPrimaryKeys(false) as $remotePk) { + $pks[] = array($pk, $remotePk); } - AttributeCategoryQuery::create() + AttributeTemplateQuery::create() ->filterByPrimaryKeys($pks) ->delete($con); - $this->categoriesScheduledForDeletion = null; + $this->templatesScheduledForDeletion = null; } - foreach ($this->getCategories() as $category) { - if ($category->isModified()) { - $category->save($con); + foreach ($this->getTemplates() as $template) { + if ($template->isModified()) { + $template->save($con); } } - } elseif ($this->collCategories) { - foreach ($this->collCategories as $category) { - if ($category->isModified()) { - $category->save($con); + } elseif ($this->collTemplates) { + foreach ($this->collTemplates as $template) { + if ($template->isModified()) { + $template->save($con); } } } @@ -896,17 +896,17 @@ abstract class Attribute implements ActiveRecordInterface } } - if ($this->attributeCategoriesScheduledForDeletion !== null) { - if (!$this->attributeCategoriesScheduledForDeletion->isEmpty()) { - \Thelia\Model\AttributeCategoryQuery::create() - ->filterByPrimaryKeys($this->attributeCategoriesScheduledForDeletion->getPrimaryKeys(false)) + if ($this->attributeTemplatesScheduledForDeletion !== null) { + if (!$this->attributeTemplatesScheduledForDeletion->isEmpty()) { + \Thelia\Model\AttributeTemplateQuery::create() + ->filterByPrimaryKeys($this->attributeTemplatesScheduledForDeletion->getPrimaryKeys(false)) ->delete($con); - $this->attributeCategoriesScheduledForDeletion = null; + $this->attributeTemplatesScheduledForDeletion = null; } } - if ($this->collAttributeCategories !== null) { - foreach ($this->collAttributeCategories as $referrerFK) { + if ($this->collAttributeTemplates !== null) { + foreach ($this->collAttributeTemplates as $referrerFK) { if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) { $affectedRows += $referrerFK->save($con); } @@ -1112,8 +1112,8 @@ abstract class Attribute implements ActiveRecordInterface if (null !== $this->collAttributeCombinations) { $result['AttributeCombinations'] = $this->collAttributeCombinations->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); } - if (null !== $this->collAttributeCategories) { - $result['AttributeCategories'] = $this->collAttributeCategories->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); + if (null !== $this->collAttributeTemplates) { + $result['AttributeTemplates'] = $this->collAttributeTemplates->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); } if (null !== $this->collAttributeI18ns) { $result['AttributeI18ns'] = $this->collAttributeI18ns->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); @@ -1291,9 +1291,9 @@ abstract class Attribute implements ActiveRecordInterface } } - foreach ($this->getAttributeCategories() as $relObj) { + foreach ($this->getAttributeTemplates() as $relObj) { if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves - $copyObj->addAttributeCategory($relObj->copy($deepCopy)); + $copyObj->addAttributeTemplate($relObj->copy($deepCopy)); } } @@ -1350,8 +1350,8 @@ abstract class Attribute implements ActiveRecordInterface if ('AttributeCombination' == $relationName) { return $this->initAttributeCombinations(); } - if ('AttributeCategory' == $relationName) { - return $this->initAttributeCategories(); + if ('AttributeTemplate' == $relationName) { + return $this->initAttributeTemplates(); } if ('AttributeI18n' == $relationName) { return $this->initAttributeI18ns(); @@ -1848,31 +1848,31 @@ abstract class Attribute implements ActiveRecordInterface } /** - * Clears out the collAttributeCategories collection + * Clears out the collAttributeTemplates collection * * This does not modify the database; however, it will remove any associated objects, causing * them to be refetched by subsequent calls to accessor method. * * @return void - * @see addAttributeCategories() + * @see addAttributeTemplates() */ - public function clearAttributeCategories() + public function clearAttributeTemplates() { - $this->collAttributeCategories = null; // important to set this to NULL since that means it is uninitialized + $this->collAttributeTemplates = null; // important to set this to NULL since that means it is uninitialized } /** - * Reset is the collAttributeCategories collection loaded partially. + * Reset is the collAttributeTemplates collection loaded partially. */ - public function resetPartialAttributeCategories($v = true) + public function resetPartialAttributeTemplates($v = true) { - $this->collAttributeCategoriesPartial = $v; + $this->collAttributeTemplatesPartial = $v; } /** - * Initializes the collAttributeCategories collection. + * Initializes the collAttributeTemplates collection. * - * By default this just sets the collAttributeCategories collection to an empty array (like clearcollAttributeCategories()); + * By default this just sets the collAttributeTemplates collection to an empty array (like clearcollAttributeTemplates()); * however, you may wish to override this method in your stub class to provide setting appropriate * to your application -- for example, setting the initial array to the values stored in database. * @@ -1881,17 +1881,17 @@ abstract class Attribute implements ActiveRecordInterface * * @return void */ - public function initAttributeCategories($overrideExisting = true) + public function initAttributeTemplates($overrideExisting = true) { - if (null !== $this->collAttributeCategories && !$overrideExisting) { + if (null !== $this->collAttributeTemplates && !$overrideExisting) { return; } - $this->collAttributeCategories = new ObjectCollection(); - $this->collAttributeCategories->setModel('\Thelia\Model\AttributeCategory'); + $this->collAttributeTemplates = new ObjectCollection(); + $this->collAttributeTemplates->setModel('\Thelia\Model\AttributeTemplate'); } /** - * Gets an array of ChildAttributeCategory objects which contain a foreign key that references this object. + * Gets an array of ChildAttributeTemplate objects which contain a foreign key that references this object. * * If the $criteria is not null, it is used to always fetch the results from the database. * Otherwise the results are fetched from the database the first time, then cached. @@ -1901,109 +1901,109 @@ abstract class Attribute implements ActiveRecordInterface * * @param Criteria $criteria optional Criteria object to narrow the query * @param ConnectionInterface $con optional connection object - * @return Collection|ChildAttributeCategory[] List of ChildAttributeCategory objects + * @return Collection|ChildAttributeTemplate[] List of ChildAttributeTemplate objects * @throws PropelException */ - public function getAttributeCategories($criteria = null, ConnectionInterface $con = null) + public function getAttributeTemplates($criteria = null, ConnectionInterface $con = null) { - $partial = $this->collAttributeCategoriesPartial && !$this->isNew(); - if (null === $this->collAttributeCategories || null !== $criteria || $partial) { - if ($this->isNew() && null === $this->collAttributeCategories) { + $partial = $this->collAttributeTemplatesPartial && !$this->isNew(); + if (null === $this->collAttributeTemplates || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collAttributeTemplates) { // return empty collection - $this->initAttributeCategories(); + $this->initAttributeTemplates(); } else { - $collAttributeCategories = ChildAttributeCategoryQuery::create(null, $criteria) + $collAttributeTemplates = ChildAttributeTemplateQuery::create(null, $criteria) ->filterByAttribute($this) ->find($con); if (null !== $criteria) { - if (false !== $this->collAttributeCategoriesPartial && count($collAttributeCategories)) { - $this->initAttributeCategories(false); + if (false !== $this->collAttributeTemplatesPartial && count($collAttributeTemplates)) { + $this->initAttributeTemplates(false); - foreach ($collAttributeCategories as $obj) { - if (false == $this->collAttributeCategories->contains($obj)) { - $this->collAttributeCategories->append($obj); + foreach ($collAttributeTemplates as $obj) { + if (false == $this->collAttributeTemplates->contains($obj)) { + $this->collAttributeTemplates->append($obj); } } - $this->collAttributeCategoriesPartial = true; + $this->collAttributeTemplatesPartial = true; } - $collAttributeCategories->getInternalIterator()->rewind(); + $collAttributeTemplates->getInternalIterator()->rewind(); - return $collAttributeCategories; + return $collAttributeTemplates; } - if ($partial && $this->collAttributeCategories) { - foreach ($this->collAttributeCategories as $obj) { + if ($partial && $this->collAttributeTemplates) { + foreach ($this->collAttributeTemplates as $obj) { if ($obj->isNew()) { - $collAttributeCategories[] = $obj; + $collAttributeTemplates[] = $obj; } } } - $this->collAttributeCategories = $collAttributeCategories; - $this->collAttributeCategoriesPartial = false; + $this->collAttributeTemplates = $collAttributeTemplates; + $this->collAttributeTemplatesPartial = false; } } - return $this->collAttributeCategories; + return $this->collAttributeTemplates; } /** - * Sets a collection of AttributeCategory objects related by a one-to-many relationship + * Sets a collection of AttributeTemplate objects related by a one-to-many relationship * to the current object. * It will also schedule objects for deletion based on a diff between old objects (aka persisted) * and new objects from the given Propel collection. * - * @param Collection $attributeCategories A Propel collection. + * @param Collection $attributeTemplates A Propel collection. * @param ConnectionInterface $con Optional connection object * @return ChildAttribute The current object (for fluent API support) */ - public function setAttributeCategories(Collection $attributeCategories, ConnectionInterface $con = null) + public function setAttributeTemplates(Collection $attributeTemplates, ConnectionInterface $con = null) { - $attributeCategoriesToDelete = $this->getAttributeCategories(new Criteria(), $con)->diff($attributeCategories); + $attributeTemplatesToDelete = $this->getAttributeTemplates(new Criteria(), $con)->diff($attributeTemplates); - $this->attributeCategoriesScheduledForDeletion = $attributeCategoriesToDelete; + $this->attributeTemplatesScheduledForDeletion = $attributeTemplatesToDelete; - foreach ($attributeCategoriesToDelete as $attributeCategoryRemoved) { - $attributeCategoryRemoved->setAttribute(null); + foreach ($attributeTemplatesToDelete as $attributeTemplateRemoved) { + $attributeTemplateRemoved->setAttribute(null); } - $this->collAttributeCategories = null; - foreach ($attributeCategories as $attributeCategory) { - $this->addAttributeCategory($attributeCategory); + $this->collAttributeTemplates = null; + foreach ($attributeTemplates as $attributeTemplate) { + $this->addAttributeTemplate($attributeTemplate); } - $this->collAttributeCategories = $attributeCategories; - $this->collAttributeCategoriesPartial = false; + $this->collAttributeTemplates = $attributeTemplates; + $this->collAttributeTemplatesPartial = false; return $this; } /** - * Returns the number of related AttributeCategory objects. + * Returns the number of related AttributeTemplate objects. * * @param Criteria $criteria * @param boolean $distinct * @param ConnectionInterface $con - * @return int Count of related AttributeCategory objects. + * @return int Count of related AttributeTemplate objects. * @throws PropelException */ - public function countAttributeCategories(Criteria $criteria = null, $distinct = false, ConnectionInterface $con = null) + public function countAttributeTemplates(Criteria $criteria = null, $distinct = false, ConnectionInterface $con = null) { - $partial = $this->collAttributeCategoriesPartial && !$this->isNew(); - if (null === $this->collAttributeCategories || null !== $criteria || $partial) { - if ($this->isNew() && null === $this->collAttributeCategories) { + $partial = $this->collAttributeTemplatesPartial && !$this->isNew(); + if (null === $this->collAttributeTemplates || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collAttributeTemplates) { return 0; } if ($partial && !$criteria) { - return count($this->getAttributeCategories()); + return count($this->getAttributeTemplates()); } - $query = ChildAttributeCategoryQuery::create(null, $criteria); + $query = ChildAttributeTemplateQuery::create(null, $criteria); if ($distinct) { $query->distinct(); } @@ -2013,53 +2013,53 @@ abstract class Attribute implements ActiveRecordInterface ->count($con); } - return count($this->collAttributeCategories); + return count($this->collAttributeTemplates); } /** - * Method called to associate a ChildAttributeCategory object to this object - * through the ChildAttributeCategory foreign key attribute. + * Method called to associate a ChildAttributeTemplate object to this object + * through the ChildAttributeTemplate foreign key attribute. * - * @param ChildAttributeCategory $l ChildAttributeCategory + * @param ChildAttributeTemplate $l ChildAttributeTemplate * @return \Thelia\Model\Attribute The current object (for fluent API support) */ - public function addAttributeCategory(ChildAttributeCategory $l) + public function addAttributeTemplate(ChildAttributeTemplate $l) { - if ($this->collAttributeCategories === null) { - $this->initAttributeCategories(); - $this->collAttributeCategoriesPartial = true; + if ($this->collAttributeTemplates === null) { + $this->initAttributeTemplates(); + $this->collAttributeTemplatesPartial = true; } - if (!in_array($l, $this->collAttributeCategories->getArrayCopy(), true)) { // only add it if the **same** object is not already associated - $this->doAddAttributeCategory($l); + if (!in_array($l, $this->collAttributeTemplates->getArrayCopy(), true)) { // only add it if the **same** object is not already associated + $this->doAddAttributeTemplate($l); } return $this; } /** - * @param AttributeCategory $attributeCategory The attributeCategory object to add. + * @param AttributeTemplate $attributeTemplate The attributeTemplate object to add. */ - protected function doAddAttributeCategory($attributeCategory) + protected function doAddAttributeTemplate($attributeTemplate) { - $this->collAttributeCategories[]= $attributeCategory; - $attributeCategory->setAttribute($this); + $this->collAttributeTemplates[]= $attributeTemplate; + $attributeTemplate->setAttribute($this); } /** - * @param AttributeCategory $attributeCategory The attributeCategory object to remove. + * @param AttributeTemplate $attributeTemplate The attributeTemplate object to remove. * @return ChildAttribute The current object (for fluent API support) */ - public function removeAttributeCategory($attributeCategory) + public function removeAttributeTemplate($attributeTemplate) { - if ($this->getAttributeCategories()->contains($attributeCategory)) { - $this->collAttributeCategories->remove($this->collAttributeCategories->search($attributeCategory)); - if (null === $this->attributeCategoriesScheduledForDeletion) { - $this->attributeCategoriesScheduledForDeletion = clone $this->collAttributeCategories; - $this->attributeCategoriesScheduledForDeletion->clear(); + if ($this->getAttributeTemplates()->contains($attributeTemplate)) { + $this->collAttributeTemplates->remove($this->collAttributeTemplates->search($attributeTemplate)); + if (null === $this->attributeTemplatesScheduledForDeletion) { + $this->attributeTemplatesScheduledForDeletion = clone $this->collAttributeTemplates; + $this->attributeTemplatesScheduledForDeletion->clear(); } - $this->attributeCategoriesScheduledForDeletion[]= clone $attributeCategory; - $attributeCategory->setAttribute(null); + $this->attributeTemplatesScheduledForDeletion[]= clone $attributeTemplate; + $attributeTemplate->setAttribute(null); } return $this; @@ -2071,7 +2071,7 @@ abstract class Attribute implements ActiveRecordInterface * an identical criteria, it returns the collection. * Otherwise if this Attribute is new, it will return * an empty collection; or if this Attribute has previously - * been saved, it will retrieve related AttributeCategories from storage. + * been saved, it will retrieve related AttributeTemplates from storage. * * This method is protected by default in order to keep the public * api reasonable. You can provide public methods for those you @@ -2080,14 +2080,14 @@ abstract class Attribute implements ActiveRecordInterface * @param Criteria $criteria optional Criteria object to narrow the query * @param ConnectionInterface $con optional connection object * @param string $joinBehavior optional join type to use (defaults to Criteria::LEFT_JOIN) - * @return Collection|ChildAttributeCategory[] List of ChildAttributeCategory objects + * @return Collection|ChildAttributeTemplate[] List of ChildAttributeTemplate objects */ - public function getAttributeCategoriesJoinCategory($criteria = null, $con = null, $joinBehavior = Criteria::LEFT_JOIN) + public function getAttributeTemplatesJoinTemplate($criteria = null, $con = null, $joinBehavior = Criteria::LEFT_JOIN) { - $query = ChildAttributeCategoryQuery::create(null, $criteria); - $query->joinWith('Category', $joinBehavior); + $query = ChildAttributeTemplateQuery::create(null, $criteria); + $query->joinWith('Template', $joinBehavior); - return $this->getAttributeCategories($query, $con); + return $this->getAttributeTemplates($query, $con); } /** @@ -2316,38 +2316,38 @@ abstract class Attribute implements ActiveRecordInterface } /** - * Clears out the collCategories collection + * Clears out the collTemplates collection * * This does not modify the database; however, it will remove any associated objects, causing * them to be refetched by subsequent calls to accessor method. * * @return void - * @see addCategories() + * @see addTemplates() */ - public function clearCategories() + public function clearTemplates() { - $this->collCategories = null; // important to set this to NULL since that means it is uninitialized - $this->collCategoriesPartial = null; + $this->collTemplates = null; // important to set this to NULL since that means it is uninitialized + $this->collTemplatesPartial = null; } /** - * Initializes the collCategories collection. + * Initializes the collTemplates collection. * - * By default this just sets the collCategories collection to an empty collection (like clearCategories()); + * By default this just sets the collTemplates collection to an empty collection (like clearTemplates()); * however, you may wish to override this method in your stub class to provide setting appropriate * to your application -- for example, setting the initial array to the values stored in database. * * @return void */ - public function initCategories() + public function initTemplates() { - $this->collCategories = new ObjectCollection(); - $this->collCategories->setModel('\Thelia\Model\Category'); + $this->collTemplates = new ObjectCollection(); + $this->collTemplates->setModel('\Thelia\Model\Template'); } /** - * Gets a collection of ChildCategory objects related by a many-to-many relationship - * to the current object by way of the attribute_category cross-reference table. + * Gets a collection of ChildTemplate objects related by a many-to-many relationship + * to the current object by way of the attribute_template cross-reference table. * * If the $criteria is not null, it is used to always fetch the results from the database. * Otherwise the results are fetched from the database the first time, then cached. @@ -2358,73 +2358,73 @@ abstract class Attribute implements ActiveRecordInterface * @param Criteria $criteria Optional query object to filter the query * @param ConnectionInterface $con Optional connection object * - * @return ObjectCollection|ChildCategory[] List of ChildCategory objects + * @return ObjectCollection|ChildTemplate[] List of ChildTemplate objects */ - public function getCategories($criteria = null, ConnectionInterface $con = null) + public function getTemplates($criteria = null, ConnectionInterface $con = null) { - if (null === $this->collCategories || null !== $criteria) { - if ($this->isNew() && null === $this->collCategories) { + if (null === $this->collTemplates || null !== $criteria) { + if ($this->isNew() && null === $this->collTemplates) { // return empty collection - $this->initCategories(); + $this->initTemplates(); } else { - $collCategories = ChildCategoryQuery::create(null, $criteria) + $collTemplates = ChildTemplateQuery::create(null, $criteria) ->filterByAttribute($this) ->find($con); if (null !== $criteria) { - return $collCategories; + return $collTemplates; } - $this->collCategories = $collCategories; + $this->collTemplates = $collTemplates; } } - return $this->collCategories; + return $this->collTemplates; } /** - * Sets a collection of Category objects related by a many-to-many relationship - * to the current object by way of the attribute_category cross-reference table. + * Sets a collection of Template objects related by a many-to-many relationship + * to the current object by way of the attribute_template cross-reference table. * It will also schedule objects for deletion based on a diff between old objects (aka persisted) * and new objects from the given Propel collection. * - * @param Collection $categories A Propel collection. + * @param Collection $templates A Propel collection. * @param ConnectionInterface $con Optional connection object * @return ChildAttribute The current object (for fluent API support) */ - public function setCategories(Collection $categories, ConnectionInterface $con = null) + public function setTemplates(Collection $templates, ConnectionInterface $con = null) { - $this->clearCategories(); - $currentCategories = $this->getCategories(); + $this->clearTemplates(); + $currentTemplates = $this->getTemplates(); - $this->categoriesScheduledForDeletion = $currentCategories->diff($categories); + $this->templatesScheduledForDeletion = $currentTemplates->diff($templates); - foreach ($categories as $category) { - if (!$currentCategories->contains($category)) { - $this->doAddCategory($category); + foreach ($templates as $template) { + if (!$currentTemplates->contains($template)) { + $this->doAddTemplate($template); } } - $this->collCategories = $categories; + $this->collTemplates = $templates; return $this; } /** - * Gets the number of ChildCategory objects related by a many-to-many relationship - * to the current object by way of the attribute_category cross-reference table. + * Gets the number of ChildTemplate objects related by a many-to-many relationship + * to the current object by way of the attribute_template cross-reference table. * * @param Criteria $criteria Optional query object to filter the query * @param boolean $distinct Set to true to force count distinct * @param ConnectionInterface $con Optional connection object * - * @return int the number of related ChildCategory objects + * @return int the number of related ChildTemplate objects */ - public function countCategories($criteria = null, $distinct = false, ConnectionInterface $con = null) + public function countTemplates($criteria = null, $distinct = false, ConnectionInterface $con = null) { - if (null === $this->collCategories || null !== $criteria) { - if ($this->isNew() && null === $this->collCategories) { + if (null === $this->collTemplates || null !== $criteria) { + if ($this->isNew() && null === $this->collTemplates) { return 0; } else { - $query = ChildCategoryQuery::create(null, $criteria); + $query = ChildTemplateQuery::create(null, $criteria); if ($distinct) { $query->distinct(); } @@ -2434,65 +2434,65 @@ abstract class Attribute implements ActiveRecordInterface ->count($con); } } else { - return count($this->collCategories); + return count($this->collTemplates); } } /** - * Associate a ChildCategory object to this object - * through the attribute_category cross reference table. + * Associate a ChildTemplate object to this object + * through the attribute_template cross reference table. * - * @param ChildCategory $category The ChildAttributeCategory object to relate + * @param ChildTemplate $template The ChildAttributeTemplate object to relate * @return ChildAttribute The current object (for fluent API support) */ - public function addCategory(ChildCategory $category) + public function addTemplate(ChildTemplate $template) { - if ($this->collCategories === null) { - $this->initCategories(); + if ($this->collTemplates === null) { + $this->initTemplates(); } - if (!$this->collCategories->contains($category)) { // only add it if the **same** object is not already associated - $this->doAddCategory($category); - $this->collCategories[] = $category; + if (!$this->collTemplates->contains($template)) { // only add it if the **same** object is not already associated + $this->doAddTemplate($template); + $this->collTemplates[] = $template; } return $this; } /** - * @param Category $category The category object to add. + * @param Template $template The template object to add. */ - protected function doAddCategory($category) + protected function doAddTemplate($template) { - $attributeCategory = new ChildAttributeCategory(); - $attributeCategory->setCategory($category); - $this->addAttributeCategory($attributeCategory); + $attributeTemplate = new ChildAttributeTemplate(); + $attributeTemplate->setTemplate($template); + $this->addAttributeTemplate($attributeTemplate); // set the back reference to this object directly as using provided method either results // in endless loop or in multiple relations - if (!$category->getAttributes()->contains($this)) { - $foreignCollection = $category->getAttributes(); + if (!$template->getAttributes()->contains($this)) { + $foreignCollection = $template->getAttributes(); $foreignCollection[] = $this; } } /** - * Remove a ChildCategory object to this object - * through the attribute_category cross reference table. + * Remove a ChildTemplate object to this object + * through the attribute_template cross reference table. * - * @param ChildCategory $category The ChildAttributeCategory object to relate + * @param ChildTemplate $template The ChildAttributeTemplate object to relate * @return ChildAttribute The current object (for fluent API support) */ - public function removeCategory(ChildCategory $category) + public function removeTemplate(ChildTemplate $template) { - if ($this->getCategories()->contains($category)) { - $this->collCategories->remove($this->collCategories->search($category)); + if ($this->getTemplates()->contains($template)) { + $this->collTemplates->remove($this->collTemplates->search($template)); - if (null === $this->categoriesScheduledForDeletion) { - $this->categoriesScheduledForDeletion = clone $this->collCategories; - $this->categoriesScheduledForDeletion->clear(); + if (null === $this->templatesScheduledForDeletion) { + $this->templatesScheduledForDeletion = clone $this->collTemplates; + $this->templatesScheduledForDeletion->clear(); } - $this->categoriesScheduledForDeletion[] = $category; + $this->templatesScheduledForDeletion[] = $template; } return $this; @@ -2536,8 +2536,8 @@ abstract class Attribute implements ActiveRecordInterface $o->clearAllReferences($deep); } } - if ($this->collAttributeCategories) { - foreach ($this->collAttributeCategories as $o) { + if ($this->collAttributeTemplates) { + foreach ($this->collAttributeTemplates as $o) { $o->clearAllReferences($deep); } } @@ -2546,8 +2546,8 @@ abstract class Attribute implements ActiveRecordInterface $o->clearAllReferences($deep); } } - if ($this->collCategories) { - foreach ($this->collCategories as $o) { + if ($this->collTemplates) { + foreach ($this->collTemplates as $o) { $o->clearAllReferences($deep); } } @@ -2565,18 +2565,18 @@ abstract class Attribute implements ActiveRecordInterface $this->collAttributeCombinations->clearIterator(); } $this->collAttributeCombinations = null; - if ($this->collAttributeCategories instanceof Collection) { - $this->collAttributeCategories->clearIterator(); + if ($this->collAttributeTemplates instanceof Collection) { + $this->collAttributeTemplates->clearIterator(); } - $this->collAttributeCategories = null; + $this->collAttributeTemplates = null; if ($this->collAttributeI18ns instanceof Collection) { $this->collAttributeI18ns->clearIterator(); } $this->collAttributeI18ns = null; - if ($this->collCategories instanceof Collection) { - $this->collCategories->clearIterator(); + if ($this->collTemplates instanceof Collection) { + $this->collTemplates->clearIterator(); } - $this->collCategories = null; + $this->collTemplates = null; } /** diff --git a/core/lib/Thelia/Model/Base/AttributeQuery.php b/core/lib/Thelia/Model/Base/AttributeQuery.php index cabbaf7ac..b496289f8 100644 --- a/core/lib/Thelia/Model/Base/AttributeQuery.php +++ b/core/lib/Thelia/Model/Base/AttributeQuery.php @@ -44,9 +44,9 @@ use Thelia\Model\Map\AttributeTableMap; * @method ChildAttributeQuery rightJoinAttributeCombination($relationAlias = null) Adds a RIGHT JOIN clause to the query using the AttributeCombination relation * @method ChildAttributeQuery innerJoinAttributeCombination($relationAlias = null) Adds a INNER JOIN clause to the query using the AttributeCombination relation * - * @method ChildAttributeQuery leftJoinAttributeCategory($relationAlias = null) Adds a LEFT JOIN clause to the query using the AttributeCategory relation - * @method ChildAttributeQuery rightJoinAttributeCategory($relationAlias = null) Adds a RIGHT JOIN clause to the query using the AttributeCategory relation - * @method ChildAttributeQuery innerJoinAttributeCategory($relationAlias = null) Adds a INNER JOIN clause to the query using the AttributeCategory relation + * @method ChildAttributeQuery leftJoinAttributeTemplate($relationAlias = null) Adds a LEFT JOIN clause to the query using the AttributeTemplate relation + * @method ChildAttributeQuery rightJoinAttributeTemplate($relationAlias = null) Adds a RIGHT JOIN clause to the query using the AttributeTemplate relation + * @method ChildAttributeQuery innerJoinAttributeTemplate($relationAlias = null) Adds a INNER JOIN clause to the query using the AttributeTemplate relation * * @method ChildAttributeQuery leftJoinAttributeI18n($relationAlias = null) Adds a LEFT JOIN clause to the query using the AttributeI18n relation * @method ChildAttributeQuery rightJoinAttributeI18n($relationAlias = null) Adds a RIGHT JOIN clause to the query using the AttributeI18n relation @@ -556,40 +556,40 @@ abstract class AttributeQuery extends ModelCriteria } /** - * Filter the query by a related \Thelia\Model\AttributeCategory object + * Filter the query by a related \Thelia\Model\AttributeTemplate object * - * @param \Thelia\Model\AttributeCategory|ObjectCollection $attributeCategory the related object to use as filter + * @param \Thelia\Model\AttributeTemplate|ObjectCollection $attributeTemplate the related object to use as filter * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL * * @return ChildAttributeQuery The current query, for fluid interface */ - public function filterByAttributeCategory($attributeCategory, $comparison = null) + public function filterByAttributeTemplate($attributeTemplate, $comparison = null) { - if ($attributeCategory instanceof \Thelia\Model\AttributeCategory) { + if ($attributeTemplate instanceof \Thelia\Model\AttributeTemplate) { return $this - ->addUsingAlias(AttributeTableMap::ID, $attributeCategory->getAttributeId(), $comparison); - } elseif ($attributeCategory instanceof ObjectCollection) { + ->addUsingAlias(AttributeTableMap::ID, $attributeTemplate->getAttributeId(), $comparison); + } elseif ($attributeTemplate instanceof ObjectCollection) { return $this - ->useAttributeCategoryQuery() - ->filterByPrimaryKeys($attributeCategory->getPrimaryKeys()) + ->useAttributeTemplateQuery() + ->filterByPrimaryKeys($attributeTemplate->getPrimaryKeys()) ->endUse(); } else { - throw new PropelException('filterByAttributeCategory() only accepts arguments of type \Thelia\Model\AttributeCategory or Collection'); + throw new PropelException('filterByAttributeTemplate() only accepts arguments of type \Thelia\Model\AttributeTemplate or Collection'); } } /** - * Adds a JOIN clause to the query using the AttributeCategory relation + * Adds a JOIN clause to the query using the AttributeTemplate relation * * @param string $relationAlias optional alias for the relation * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' * * @return ChildAttributeQuery The current query, for fluid interface */ - public function joinAttributeCategory($relationAlias = null, $joinType = Criteria::INNER_JOIN) + public function joinAttributeTemplate($relationAlias = null, $joinType = Criteria::INNER_JOIN) { $tableMap = $this->getTableMap(); - $relationMap = $tableMap->getRelation('AttributeCategory'); + $relationMap = $tableMap->getRelation('AttributeTemplate'); // create a ModelJoin object for this join $join = new ModelJoin(); @@ -604,14 +604,14 @@ abstract class AttributeQuery extends ModelCriteria $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); $this->addJoinObject($join, $relationAlias); } else { - $this->addJoinObject($join, 'AttributeCategory'); + $this->addJoinObject($join, 'AttributeTemplate'); } return $this; } /** - * Use the AttributeCategory relation AttributeCategory object + * Use the AttributeTemplate relation AttributeTemplate object * * @see useQuery() * @@ -619,13 +619,13 @@ abstract class AttributeQuery extends ModelCriteria * to be used as main alias in the secondary query * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' * - * @return \Thelia\Model\AttributeCategoryQuery A secondary query class using the current class as primary query + * @return \Thelia\Model\AttributeTemplateQuery A secondary query class using the current class as primary query */ - public function useAttributeCategoryQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) + public function useAttributeTemplateQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) { return $this - ->joinAttributeCategory($relationAlias, $joinType) - ->useQuery($relationAlias ? $relationAlias : 'AttributeCategory', '\Thelia\Model\AttributeCategoryQuery'); + ->joinAttributeTemplate($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'AttributeTemplate', '\Thelia\Model\AttributeTemplateQuery'); } /** @@ -702,19 +702,19 @@ abstract class AttributeQuery extends ModelCriteria } /** - * Filter the query by a related Category object - * using the attribute_category table as cross reference + * Filter the query by a related Template object + * using the attribute_template table as cross reference * - * @param Category $category the related object to use as filter + * @param Template $template the related object to use as filter * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL * * @return ChildAttributeQuery The current query, for fluid interface */ - public function filterByCategory($category, $comparison = Criteria::EQUAL) + public function filterByTemplate($template, $comparison = Criteria::EQUAL) { return $this - ->useAttributeCategoryQuery() - ->filterByCategory($category, $comparison) + ->useAttributeTemplateQuery() + ->filterByTemplate($template, $comparison) ->endUse(); } diff --git a/core/lib/Thelia/Model/Base/AttributeTemplate.php b/core/lib/Thelia/Model/Base/AttributeTemplate.php new file mode 100644 index 000000000..cedc85431 --- /dev/null +++ b/core/lib/Thelia/Model/Base/AttributeTemplate.php @@ -0,0 +1,1495 @@ +modifiedColumns); + } + + /** + * Has specified column been modified? + * + * @param string $col column fully qualified name (TableMap::TYPE_COLNAME), e.g. Book::AUTHOR_ID + * @return boolean True if $col has been modified. + */ + public function isColumnModified($col) + { + return in_array($col, $this->modifiedColumns); + } + + /** + * Get the columns that have been modified in this object. + * @return array A unique list of the modified column names for this object. + */ + public function getModifiedColumns() + { + return array_unique($this->modifiedColumns); + } + + /** + * Returns whether the object has ever been saved. This will + * be false, if the object was retrieved from storage or was created + * and then saved. + * + * @return true, if the object has never been persisted. + */ + public function isNew() + { + return $this->new; + } + + /** + * Setter for the isNew attribute. This method will be called + * by Propel-generated children and objects. + * + * @param boolean $b the state of the object. + */ + public function setNew($b) + { + $this->new = (Boolean) $b; + } + + /** + * Whether this object has been deleted. + * @return boolean The deleted state of this object. + */ + public function isDeleted() + { + return $this->deleted; + } + + /** + * Specify whether this object has been deleted. + * @param boolean $b The deleted state of this object. + * @return void + */ + public function setDeleted($b) + { + $this->deleted = (Boolean) $b; + } + + /** + * Sets the modified state for the object to be false. + * @param string $col If supplied, only the specified column is reset. + * @return void + */ + public function resetModified($col = null) + { + if (null !== $col) { + while (false !== ($offset = array_search($col, $this->modifiedColumns))) { + array_splice($this->modifiedColumns, $offset, 1); + } + } else { + $this->modifiedColumns = array(); + } + } + + /** + * Compares this with another AttributeTemplate instance. If + * obj is an instance of AttributeTemplate, delegates to + * equals(AttributeTemplate). Otherwise, returns false. + * + * @param obj The object to compare to. + * @return Whether equal to the object specified. + */ + public function equals($obj) + { + $thisclazz = get_class($this); + if (!is_object($obj) || !($obj instanceof $thisclazz)) { + return false; + } + + if ($this === $obj) { + return true; + } + + if (null === $this->getPrimaryKey() + || null === $obj->getPrimaryKey()) { + return false; + } + + return $this->getPrimaryKey() === $obj->getPrimaryKey(); + } + + /** + * If the primary key is not null, return the hashcode of the + * primary key. Otherwise, return the hash code of the object. + * + * @return int Hashcode + */ + public function hashCode() + { + if (null !== $this->getPrimaryKey()) { + return crc32(serialize($this->getPrimaryKey())); + } + + return crc32(serialize(clone $this)); + } + + /** + * Get the associative array of the virtual columns in this object + * + * @param string $name The virtual column name + * + * @return array + */ + public function getVirtualColumns() + { + return $this->virtualColumns; + } + + /** + * Checks the existence of a virtual column in this object + * + * @return boolean + */ + public function hasVirtualColumn($name) + { + return array_key_exists($name, $this->virtualColumns); + } + + /** + * Get the value of a virtual column in this object + * + * @return mixed + */ + public function getVirtualColumn($name) + { + if (!$this->hasVirtualColumn($name)) { + throw new PropelException(sprintf('Cannot get value of inexistent virtual column %s.', $name)); + } + + return $this->virtualColumns[$name]; + } + + /** + * Set the value of a virtual column in this object + * + * @param string $name The virtual column name + * @param mixed $value The value to give to the virtual column + * + * @return AttributeTemplate The current object, for fluid interface + */ + public function setVirtualColumn($name, $value) + { + $this->virtualColumns[$name] = $value; + + return $this; + } + + /** + * Logs a message using Propel::log(). + * + * @param string $msg + * @param int $priority One of the Propel::LOG_* logging levels + * @return boolean + */ + protected function log($msg, $priority = Propel::LOG_INFO) + { + return Propel::log(get_class($this) . ': ' . $msg, $priority); + } + + /** + * Populate the current object from a string, using a given parser format + * + * $book = new Book(); + * $book->importFrom('JSON', '{"Id":9012,"Title":"Don Juan","ISBN":"0140422161","Price":12.99,"PublisherId":1234,"AuthorId":5678}'); + * + * + * @param mixed $parser A AbstractParser instance, + * or a format name ('XML', 'YAML', 'JSON', 'CSV') + * @param string $data The source data to import from + * + * @return AttributeTemplate The current object, for fluid interface + */ + public function importFrom($parser, $data) + { + if (!$parser instanceof AbstractParser) { + $parser = AbstractParser::getParser($parser); + } + + return $this->fromArray($parser->toArray($data), TableMap::TYPE_PHPNAME); + } + + /** + * Export the current object properties to a string, using a given parser format + * + * $book = BookQuery::create()->findPk(9012); + * echo $book->exportTo('JSON'); + * => {"Id":9012,"Title":"Don Juan","ISBN":"0140422161","Price":12.99,"PublisherId":1234,"AuthorId":5678}'); + * + * + * @param mixed $parser A AbstractParser instance, or a format name ('XML', 'YAML', 'JSON', 'CSV') + * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy load(ed) columns. Defaults to TRUE. + * @return string The exported data + */ + public function exportTo($parser, $includeLazyLoadColumns = true) + { + if (!$parser instanceof AbstractParser) { + $parser = AbstractParser::getParser($parser); + } + + return $parser->fromArray($this->toArray(TableMap::TYPE_PHPNAME, $includeLazyLoadColumns, array(), true)); + } + + /** + * Clean up internal collections prior to serializing + * Avoids recursive loops that turn into segmentation faults when serializing + */ + public function __sleep() + { + $this->clearAllReferences(); + + return array_keys(get_object_vars($this)); + } + + /** + * Get the [id] column value. + * + * @return int + */ + public function getId() + { + + return $this->id; + } + + /** + * Get the [attribute_id] column value. + * + * @return int + */ + public function getAttributeId() + { + + return $this->attribute_id; + } + + /** + * Get the [template_id] column value. + * + * @return int + */ + public function getTemplateId() + { + + return $this->template_id; + } + + /** + * 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 !== null ? $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 !== null ? $this->updated_at->format($format) : null; + } + } + + /** + * Set the value of [id] column. + * + * @param int $v new value + * @return \Thelia\Model\AttributeTemplate The current object (for fluent API support) + */ + public function setId($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->id !== $v) { + $this->id = $v; + $this->modifiedColumns[] = AttributeTemplateTableMap::ID; + } + + + return $this; + } // setId() + + /** + * Set the value of [attribute_id] column. + * + * @param int $v new value + * @return \Thelia\Model\AttributeTemplate The current object (for fluent API support) + */ + public function setAttributeId($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->attribute_id !== $v) { + $this->attribute_id = $v; + $this->modifiedColumns[] = AttributeTemplateTableMap::ATTRIBUTE_ID; + } + + if ($this->aAttribute !== null && $this->aAttribute->getId() !== $v) { + $this->aAttribute = null; + } + + + return $this; + } // setAttributeId() + + /** + * Set the value of [template_id] column. + * + * @param int $v new value + * @return \Thelia\Model\AttributeTemplate The current object (for fluent API support) + */ + public function setTemplateId($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->template_id !== $v) { + $this->template_id = $v; + $this->modifiedColumns[] = AttributeTemplateTableMap::TEMPLATE_ID; + } + + if ($this->aTemplate !== null && $this->aTemplate->getId() !== $v) { + $this->aTemplate = null; + } + + + return $this; + } // setTemplateId() + + /** + * 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\AttributeTemplate 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[] = AttributeTemplateTableMap::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\AttributeTemplate 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[] = AttributeTemplateTableMap::UPDATED_AT; + } + } // if either are not null + + + return $this; + } // setUpdatedAt() + + /** + * Indicates whether the columns in this object are only set to default values. + * + * This method can be used in conjunction with isModified() to indicate whether an object is both + * modified _and_ has some values set which are non-default. + * + * @return boolean Whether the columns in this object are only been set with default values. + */ + public function hasOnlyDefaultValues() + { + // otherwise, everything was equal, so return TRUE + return true; + } // hasOnlyDefaultValues() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (0-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param array $row The row returned by DataFetcher->fetch(). + * @param int $startcol 0-based offset column which indicates which restultset column to start with. + * @param boolean $rehydrate Whether this object is being re-hydrated from the database. + * @param string $indexType The index type of $row. Mostly DataFetcher->getIndexType(). + One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate($row, $startcol = 0, $rehydrate = false, $indexType = TableMap::TYPE_NUM) + { + try { + + + $col = $row[TableMap::TYPE_NUM == $indexType ? 0 + $startcol : AttributeTemplateTableMap::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)]; + $this->id = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 1 + $startcol : AttributeTemplateTableMap::translateFieldName('AttributeId', TableMap::TYPE_PHPNAME, $indexType)]; + $this->attribute_id = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : AttributeTemplateTableMap::translateFieldName('TemplateId', TableMap::TYPE_PHPNAME, $indexType)]; + $this->template_id = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : AttributeTemplateTableMap::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 ? 4 + $startcol : AttributeTemplateTableMap::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); + + if ($rehydrate) { + $this->ensureConsistency(); + } + + return $startcol + 5; // 5 = AttributeTemplateTableMap::NUM_HYDRATE_COLUMNS. + + } catch (Exception $e) { + throw new PropelException("Error populating \Thelia\Model\AttributeTemplate object", 0, $e); + } + } + + /** + * Checks and repairs the internal consistency of the object. + * + * This method is executed after an already-instantiated object is re-hydrated + * from the database. It exists to check any foreign keys to make sure that + * the objects related to the current object are correct based on foreign key. + * + * You can override this method in the stub class, but you should always invoke + * the base method from the overridden method (i.e. parent::ensureConsistency()), + * in case your model changes. + * + * @throws PropelException + */ + public function ensureConsistency() + { + if ($this->aAttribute !== null && $this->attribute_id !== $this->aAttribute->getId()) { + $this->aAttribute = null; + } + if ($this->aTemplate !== null && $this->template_id !== $this->aTemplate->getId()) { + $this->aTemplate = null; + } + } // ensureConsistency + + /** + * Reloads this object from datastore based on primary key and (optionally) resets all associated objects. + * + * This will only work if the object has been saved and has a valid primary key set. + * + * @param boolean $deep (optional) Whether to also de-associated any related objects. + * @param ConnectionInterface $con (optional) The ConnectionInterface connection to use. + * @return void + * @throws PropelException - if this object is deleted, unsaved or doesn't have pk match in db + */ + public function reload($deep = false, ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("Cannot reload a deleted object."); + } + + if ($this->isNew()) { + throw new PropelException("Cannot reload an unsaved object."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getReadConnection(AttributeTemplateTableMap::DATABASE_NAME); + } + + // We don't need to alter the object instance pool; we're just modifying this instance + // already in the pool. + + $dataFetcher = ChildAttributeTemplateQuery::create(null, $this->buildPkeyCriteria())->setFormatter(ModelCriteria::FORMAT_STATEMENT)->find($con); + $row = $dataFetcher->fetch(); + $dataFetcher->close(); + if (!$row) { + throw new PropelException('Cannot find matching row in the database to reload object values.'); + } + $this->hydrate($row, 0, true, $dataFetcher->getIndexType()); // rehydrate + + if ($deep) { // also de-associate any related objects? + + $this->aAttribute = null; + $this->aTemplate = null; + } // if (deep) + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param ConnectionInterface $con + * @return void + * @throws PropelException + * @see AttributeTemplate::setDeleted() + * @see AttributeTemplate::isDeleted() + */ + public function delete(ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getWriteConnection(AttributeTemplateTableMap::DATABASE_NAME); + } + + $con->beginTransaction(); + try { + $deleteQuery = ChildAttributeTemplateQuery::create() + ->filterByPrimaryKey($this->getPrimaryKey()); + $ret = $this->preDelete($con); + if ($ret) { + $deleteQuery->delete($con); + $this->postDelete($con); + $con->commit(); + $this->setDeleted(true); + } else { + $con->commit(); + } + } catch (Exception $e) { + $con->rollBack(); + throw $e; + } + } + + /** + * Persists this object to the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All modified related objects will also be persisted in the doSave() + * method. This method wraps all precipitate database operations in a + * single transaction. + * + * @param ConnectionInterface $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save(ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getWriteConnection(AttributeTemplateTableMap::DATABASE_NAME); + } + + $con->beginTransaction(); + $isInsert = $this->isNew(); + try { + $ret = $this->preSave($con); + if ($isInsert) { + $ret = $ret && $this->preInsert($con); + // timestampable behavior + if (!$this->isColumnModified(AttributeTemplateTableMap::CREATED_AT)) { + $this->setCreatedAt(time()); + } + if (!$this->isColumnModified(AttributeTemplateTableMap::UPDATED_AT)) { + $this->setUpdatedAt(time()); + } + } else { + $ret = $ret && $this->preUpdate($con); + // timestampable behavior + if ($this->isModified() && !$this->isColumnModified(AttributeTemplateTableMap::UPDATED_AT)) { + $this->setUpdatedAt(time()); + } + } + if ($ret) { + $affectedRows = $this->doSave($con); + if ($isInsert) { + $this->postInsert($con); + } else { + $this->postUpdate($con); + } + $this->postSave($con); + AttributeTemplateTableMap::addInstanceToPool($this); + } else { + $affectedRows = 0; + } + $con->commit(); + + return $affectedRows; + } catch (Exception $e) { + $con->rollBack(); + throw $e; + } + } + + /** + * Performs the work of inserting or updating the row in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param ConnectionInterface $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave(ConnectionInterface $con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + // We call the save method on the following object(s) if they + // were passed to this object by their corresponding set + // method. This object relates to these object(s) by a + // foreign key reference. + + if ($this->aAttribute !== null) { + if ($this->aAttribute->isModified() || $this->aAttribute->isNew()) { + $affectedRows += $this->aAttribute->save($con); + } + $this->setAttribute($this->aAttribute); + } + + if ($this->aTemplate !== null) { + if ($this->aTemplate->isModified() || $this->aTemplate->isNew()) { + $affectedRows += $this->aTemplate->save($con); + } + $this->setTemplate($this->aTemplate); + } + + if ($this->isNew() || $this->isModified()) { + // persist changes + if ($this->isNew()) { + $this->doInsert($con); + } else { + $this->doUpdate($con); + } + $affectedRows += 1; + $this->resetModified(); + } + + $this->alreadyInSave = false; + + } + + return $affectedRows; + } // doSave() + + /** + * Insert the row in the database. + * + * @param ConnectionInterface $con + * + * @throws PropelException + * @see doSave() + */ + protected function doInsert(ConnectionInterface $con) + { + $modifiedColumns = array(); + $index = 0; + + $this->modifiedColumns[] = AttributeTemplateTableMap::ID; + if (null !== $this->id) { + throw new PropelException('Cannot insert a value for auto-increment primary key (' . AttributeTemplateTableMap::ID . ')'); + } + + // check the columns in natural order for more readable SQL queries + if ($this->isColumnModified(AttributeTemplateTableMap::ID)) { + $modifiedColumns[':p' . $index++] = 'ID'; + } + if ($this->isColumnModified(AttributeTemplateTableMap::ATTRIBUTE_ID)) { + $modifiedColumns[':p' . $index++] = 'ATTRIBUTE_ID'; + } + if ($this->isColumnModified(AttributeTemplateTableMap::TEMPLATE_ID)) { + $modifiedColumns[':p' . $index++] = 'TEMPLATE_ID'; + } + if ($this->isColumnModified(AttributeTemplateTableMap::CREATED_AT)) { + $modifiedColumns[':p' . $index++] = 'CREATED_AT'; + } + if ($this->isColumnModified(AttributeTemplateTableMap::UPDATED_AT)) { + $modifiedColumns[':p' . $index++] = 'UPDATED_AT'; + } + + $sql = sprintf( + 'INSERT INTO attribute_template (%s) VALUES (%s)', + implode(', ', $modifiedColumns), + implode(', ', array_keys($modifiedColumns)) + ); + + try { + $stmt = $con->prepare($sql); + foreach ($modifiedColumns as $identifier => $columnName) { + switch ($columnName) { + case 'ID': + $stmt->bindValue($identifier, $this->id, PDO::PARAM_INT); + break; + case 'ATTRIBUTE_ID': + $stmt->bindValue($identifier, $this->attribute_id, PDO::PARAM_INT); + break; + case 'TEMPLATE_ID': + $stmt->bindValue($identifier, $this->template_id, PDO::PARAM_INT); + 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(); + } catch (Exception $e) { + Propel::log($e->getMessage(), Propel::LOG_ERR); + throw new PropelException(sprintf('Unable to execute INSERT statement [%s]', $sql), 0, $e); + } + + try { + $pk = $con->lastInsertId(); + } catch (Exception $e) { + throw new PropelException('Unable to get autoincrement id.', 0, $e); + } + $this->setId($pk); + + $this->setNew(false); + } + + /** + * Update the row in the database. + * + * @param ConnectionInterface $con + * + * @return Integer Number of updated rows + * @see doSave() + */ + protected function doUpdate(ConnectionInterface $con) + { + $selectCriteria = $this->buildPkeyCriteria(); + $valuesCriteria = $this->buildCriteria(); + + return $selectCriteria->doUpdate($valuesCriteria, $con); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @return mixed Value of field. + */ + public function getByName($name, $type = TableMap::TYPE_PHPNAME) + { + $pos = AttributeTemplateTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); + $field = $this->getByPosition($pos); + + return $field; + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch ($pos) { + case 0: + return $this->getId(); + break; + case 1: + return $this->getAttributeId(); + break; + case 2: + return $this->getTemplateId(); + break; + case 3: + return $this->getCreatedAt(); + break; + case 4: + return $this->getUpdatedAt(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType (optional) One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME, + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to TRUE. + * @param array $alreadyDumpedObjects List of objects to skip to avoid recursion + * @param boolean $includeForeignObjects (optional) Whether to include hydrated related objects. Default to FALSE. + * + * @return array an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = TableMap::TYPE_PHPNAME, $includeLazyLoadColumns = true, $alreadyDumpedObjects = array(), $includeForeignObjects = false) + { + if (isset($alreadyDumpedObjects['AttributeTemplate'][$this->getPrimaryKey()])) { + return '*RECURSION*'; + } + $alreadyDumpedObjects['AttributeTemplate'][$this->getPrimaryKey()] = true; + $keys = AttributeTemplateTableMap::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getId(), + $keys[1] => $this->getAttributeId(), + $keys[2] => $this->getTemplateId(), + $keys[3] => $this->getCreatedAt(), + $keys[4] => $this->getUpdatedAt(), + ); + $virtualColumns = $this->virtualColumns; + foreach($virtualColumns as $key => $virtualColumn) + { + $result[$key] = $virtualColumn; + } + + if ($includeForeignObjects) { + if (null !== $this->aAttribute) { + $result['Attribute'] = $this->aAttribute->toArray($keyType, $includeLazyLoadColumns, $alreadyDumpedObjects, true); + } + if (null !== $this->aTemplate) { + $result['Template'] = $this->aTemplate->toArray($keyType, $includeLazyLoadColumns, $alreadyDumpedObjects, true); + } + } + + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @return void + */ + public function setByName($name, $value, $type = TableMap::TYPE_PHPNAME) + { + $pos = AttributeTemplateTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); + + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch ($pos) { + case 0: + $this->setId($value); + break; + case 1: + $this->setAttributeId($value); + break; + case 2: + $this->setTemplateId($value); + break; + case 3: + $this->setCreatedAt($value); + break; + case 4: + $this->setUpdatedAt($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME, + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * The default key type is the column's TableMap::TYPE_PHPNAME. + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = TableMap::TYPE_PHPNAME) + { + $keys = AttributeTemplateTableMap::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setAttributeId($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setTemplateId($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setCreatedAt($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setUpdatedAt($arr[$keys[4]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(AttributeTemplateTableMap::DATABASE_NAME); + + if ($this->isColumnModified(AttributeTemplateTableMap::ID)) $criteria->add(AttributeTemplateTableMap::ID, $this->id); + if ($this->isColumnModified(AttributeTemplateTableMap::ATTRIBUTE_ID)) $criteria->add(AttributeTemplateTableMap::ATTRIBUTE_ID, $this->attribute_id); + if ($this->isColumnModified(AttributeTemplateTableMap::TEMPLATE_ID)) $criteria->add(AttributeTemplateTableMap::TEMPLATE_ID, $this->template_id); + if ($this->isColumnModified(AttributeTemplateTableMap::CREATED_AT)) $criteria->add(AttributeTemplateTableMap::CREATED_AT, $this->created_at); + if ($this->isColumnModified(AttributeTemplateTableMap::UPDATED_AT)) $criteria->add(AttributeTemplateTableMap::UPDATED_AT, $this->updated_at); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(AttributeTemplateTableMap::DATABASE_NAME); + $criteria->add(AttributeTemplateTableMap::ID, $this->id); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return int + */ + public function getPrimaryKey() + { + return $this->getId(); + } + + /** + * Generic method to set the primary key (id column). + * + * @param int $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setId($key); + } + + /** + * Returns true if the primary key for this object is null. + * @return boolean + */ + public function isPrimaryKeyNull() + { + + return null === $this->getId(); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of \Thelia\Model\AttributeTemplate (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @param boolean $makeNew Whether to reset autoincrement PKs and make the object new. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false, $makeNew = true) + { + $copyObj->setAttributeId($this->getAttributeId()); + $copyObj->setTemplateId($this->getTemplateId()); + $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 + } + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return \Thelia\Model\AttributeTemplate Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + + return $copyObj; + } + + /** + * Declares an association between this object and a ChildAttribute object. + * + * @param ChildAttribute $v + * @return \Thelia\Model\AttributeTemplate The current object (for fluent API support) + * @throws PropelException + */ + public function setAttribute(ChildAttribute $v = null) + { + if ($v === null) { + $this->setAttributeId(NULL); + } else { + $this->setAttributeId($v->getId()); + } + + $this->aAttribute = $v; + + // Add binding for other direction of this n:n relationship. + // If this object has already been added to the ChildAttribute object, it will not be re-added. + if ($v !== null) { + $v->addAttributeTemplate($this); + } + + + return $this; + } + + + /** + * Get the associated ChildAttribute object + * + * @param ConnectionInterface $con Optional Connection object. + * @return ChildAttribute The associated ChildAttribute object. + * @throws PropelException + */ + public function getAttribute(ConnectionInterface $con = null) + { + if ($this->aAttribute === null && ($this->attribute_id !== null)) { + $this->aAttribute = ChildAttributeQuery::create()->findPk($this->attribute_id, $con); + /* The following can be used additionally to + guarantee the related object contains a reference + to this object. This level of coupling may, however, be + undesirable since it could result in an only partially populated collection + in the referenced object. + $this->aAttribute->addAttributeTemplates($this); + */ + } + + return $this->aAttribute; + } + + /** + * Declares an association between this object and a ChildTemplate object. + * + * @param ChildTemplate $v + * @return \Thelia\Model\AttributeTemplate The current object (for fluent API support) + * @throws PropelException + */ + public function setTemplate(ChildTemplate $v = null) + { + if ($v === null) { + $this->setTemplateId(NULL); + } else { + $this->setTemplateId($v->getId()); + } + + $this->aTemplate = $v; + + // Add binding for other direction of this n:n relationship. + // If this object has already been added to the ChildTemplate object, it will not be re-added. + if ($v !== null) { + $v->addAttributeTemplate($this); + } + + + return $this; + } + + + /** + * Get the associated ChildTemplate object + * + * @param ConnectionInterface $con Optional Connection object. + * @return ChildTemplate The associated ChildTemplate object. + * @throws PropelException + */ + public function getTemplate(ConnectionInterface $con = null) + { + if ($this->aTemplate === null && ($this->template_id !== null)) { + $this->aTemplate = ChildTemplateQuery::create()->findPk($this->template_id, $con); + /* The following can be used additionally to + guarantee the related object contains a reference + to this object. This level of coupling may, however, be + undesirable since it could result in an only partially populated collection + in the referenced object. + $this->aTemplate->addAttributeTemplates($this); + */ + } + + return $this->aTemplate; + } + + /** + * Clears the current object and sets all attributes to their default values + */ + public function clear() + { + $this->id = null; + $this->attribute_id = null; + $this->template_id = null; + $this->created_at = null; + $this->updated_at = null; + $this->alreadyInSave = false; + $this->clearAllReferences(); + $this->resetModified(); + $this->setNew(true); + $this->setDeleted(false); + } + + /** + * Resets all references to other model objects or collections of model objects. + * + * This method is a user-space workaround for PHP's inability to garbage collect + * objects with circular references (even in PHP 5.3). This is currently necessary + * when using Propel in certain daemon or large-volume/high-memory operations. + * + * @param boolean $deep Whether to also clear the references on all referrer objects. + */ + public function clearAllReferences($deep = false) + { + if ($deep) { + } // if ($deep) + + $this->aAttribute = null; + $this->aTemplate = null; + } + + /** + * Return the string representation of this object + * + * @return string + */ + public function __toString() + { + return (string) $this->exportTo(AttributeTemplateTableMap::DEFAULT_STRING_FORMAT); + } + + // timestampable behavior + + /** + * Mark the current object so that the update date doesn't get updated during next save + * + * @return ChildAttributeTemplate The current object (for fluent API support) + */ + public function keepUpdateDateUnchanged() + { + $this->modifiedColumns[] = AttributeTemplateTableMap::UPDATED_AT; + + return $this; + } + + /** + * Code to be run before persisting the object + * @param ConnectionInterface $con + * @return boolean + */ + public function preSave(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after persisting the object + * @param ConnectionInterface $con + */ + public function postSave(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before inserting to database + * @param ConnectionInterface $con + * @return boolean + */ + public function preInsert(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after inserting to database + * @param ConnectionInterface $con + */ + public function postInsert(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before updating the object in database + * @param ConnectionInterface $con + * @return boolean + */ + public function preUpdate(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after updating the object in database + * @param ConnectionInterface $con + */ + public function postUpdate(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before deleting the object in database + * @param ConnectionInterface $con + * @return boolean + */ + public function preDelete(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after deleting the object in database + * @param ConnectionInterface $con + */ + public function postDelete(ConnectionInterface $con = null) + { + + } + + + /** + * Derived method to catches calls to undefined methods. + * + * Provides magic import/export method support (fromXML()/toXML(), fromYAML()/toYAML(), etc.). + * Allows to define default __call() behavior if you overwrite __call() + * + * @param string $name + * @param mixed $params + * + * @return array|string + */ + public function __call($name, $params) + { + if (0 === strpos($name, 'get')) { + $virtualColumn = substr($name, 3); + if ($this->hasVirtualColumn($virtualColumn)) { + return $this->getVirtualColumn($virtualColumn); + } + + $virtualColumn = lcfirst($virtualColumn); + if ($this->hasVirtualColumn($virtualColumn)) { + return $this->getVirtualColumn($virtualColumn); + } + } + + if (0 === strpos($name, 'from')) { + $format = substr($name, 4); + + return $this->importFrom($format, reset($params)); + } + + if (0 === strpos($name, 'to')) { + $format = substr($name, 2); + $includeLazyLoadColumns = isset($params[0]) ? $params[0] : true; + + return $this->exportTo($format, $includeLazyLoadColumns); + } + + throw new BadMethodCallException(sprintf('Call to undefined method: %s.', $name)); + } + +} diff --git a/core/lib/Thelia/Model/Base/AttributeTemplateQuery.php b/core/lib/Thelia/Model/Base/AttributeTemplateQuery.php new file mode 100644 index 000000000..bd895360b --- /dev/null +++ b/core/lib/Thelia/Model/Base/AttributeTemplateQuery.php @@ -0,0 +1,759 @@ +setModelAlias($modelAlias); + } + if ($criteria instanceof Criteria) { + $query->mergeWith($criteria); + } + + return $query; + } + + /** + * Find object by primary key. + * Propel uses the instance pool to skip the database if the object exists. + * Go fast if the query is untouched. + * + * + * $obj = $c->findPk(12, $con); + * + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con an optional connection object + * + * @return ChildAttributeTemplate|array|mixed the result, formatted by the current formatter + */ + public function findPk($key, $con = null) + { + if ($key === null) { + return null; + } + if ((null !== ($obj = AttributeTemplateTableMap::getInstanceFromPool((string) $key))) && !$this->formatter) { + // the object is already in the instance pool + return $obj; + } + if ($con === null) { + $con = Propel::getServiceContainer()->getReadConnection(AttributeTemplateTableMap::DATABASE_NAME); + } + $this->basePreSelect($con); + if ($this->formatter || $this->modelAlias || $this->with || $this->select + || $this->selectColumns || $this->asColumns || $this->selectModifiers + || $this->map || $this->having || $this->joins) { + return $this->findPkComplex($key, $con); + } else { + return $this->findPkSimple($key, $con); + } + } + + /** + * Find object by primary key using raw SQL to go fast. + * Bypass doSelect() and the object formatter by using generated code. + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con A connection object + * + * @return ChildAttributeTemplate A model object, or null if the key is not found + */ + protected function findPkSimple($key, $con) + { + $sql = 'SELECT ID, ATTRIBUTE_ID, TEMPLATE_ID, CREATED_AT, UPDATED_AT FROM attribute_template WHERE ID = :p0'; + try { + $stmt = $con->prepare($sql); + $stmt->bindValue(':p0', $key, PDO::PARAM_INT); + $stmt->execute(); + } catch (Exception $e) { + Propel::log($e->getMessage(), Propel::LOG_ERR); + throw new PropelException(sprintf('Unable to execute SELECT statement [%s]', $sql), 0, $e); + } + $obj = null; + if ($row = $stmt->fetch(\PDO::FETCH_NUM)) { + $obj = new ChildAttributeTemplate(); + $obj->hydrate($row); + AttributeTemplateTableMap::addInstanceToPool($obj, (string) $key); + } + $stmt->closeCursor(); + + return $obj; + } + + /** + * Find object by primary key. + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con A connection object + * + * @return ChildAttributeTemplate|array|mixed the result, formatted by the current formatter + */ + protected function findPkComplex($key, $con) + { + // As the query uses a PK condition, no limit(1) is necessary. + $criteria = $this->isKeepQuery() ? clone $this : $this; + $dataFetcher = $criteria + ->filterByPrimaryKey($key) + ->doSelect($con); + + return $criteria->getFormatter()->init($criteria)->formatOne($dataFetcher); + } + + /** + * Find objects by primary key + * + * $objs = $c->findPks(array(12, 56, 832), $con); + * + * @param array $keys Primary keys to use for the query + * @param ConnectionInterface $con an optional connection object + * + * @return ObjectCollection|array|mixed the list of results, formatted by the current formatter + */ + public function findPks($keys, $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getReadConnection($this->getDbName()); + } + $this->basePreSelect($con); + $criteria = $this->isKeepQuery() ? clone $this : $this; + $dataFetcher = $criteria + ->filterByPrimaryKeys($keys) + ->doSelect($con); + + return $criteria->getFormatter()->init($criteria)->format($dataFetcher); + } + + /** + * Filter the query by primary key + * + * @param mixed $key Primary key to use for the query + * + * @return ChildAttributeTemplateQuery The current query, for fluid interface + */ + public function filterByPrimaryKey($key) + { + + return $this->addUsingAlias(AttributeTemplateTableMap::ID, $key, Criteria::EQUAL); + } + + /** + * Filter the query by a list of primary keys + * + * @param array $keys The list of primary key to use for the query + * + * @return ChildAttributeTemplateQuery The current query, for fluid interface + */ + public function filterByPrimaryKeys($keys) + { + + return $this->addUsingAlias(AttributeTemplateTableMap::ID, $keys, Criteria::IN); + } + + /** + * Filter the query on the id column + * + * Example usage: + * + * $query->filterById(1234); // WHERE id = 1234 + * $query->filterById(array(12, 34)); // WHERE id IN (12, 34) + * $query->filterById(array('min' => 12)); // WHERE id > 12 + * + * + * @param mixed $id The value to use as filter. + * 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 ChildAttributeTemplateQuery The current query, for fluid interface + */ + public function filterById($id = null, $comparison = null) + { + if (is_array($id)) { + $useMinMax = false; + if (isset($id['min'])) { + $this->addUsingAlias(AttributeTemplateTableMap::ID, $id['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($id['max'])) { + $this->addUsingAlias(AttributeTemplateTableMap::ID, $id['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(AttributeTemplateTableMap::ID, $id, $comparison); + } + + /** + * Filter the query on the attribute_id column + * + * Example usage: + * + * $query->filterByAttributeId(1234); // WHERE attribute_id = 1234 + * $query->filterByAttributeId(array(12, 34)); // WHERE attribute_id IN (12, 34) + * $query->filterByAttributeId(array('min' => 12)); // WHERE attribute_id > 12 + * + * + * @see filterByAttribute() + * + * @param mixed $attributeId The value to use as filter. + * 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 ChildAttributeTemplateQuery The current query, for fluid interface + */ + public function filterByAttributeId($attributeId = null, $comparison = null) + { + if (is_array($attributeId)) { + $useMinMax = false; + if (isset($attributeId['min'])) { + $this->addUsingAlias(AttributeTemplateTableMap::ATTRIBUTE_ID, $attributeId['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($attributeId['max'])) { + $this->addUsingAlias(AttributeTemplateTableMap::ATTRIBUTE_ID, $attributeId['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(AttributeTemplateTableMap::ATTRIBUTE_ID, $attributeId, $comparison); + } + + /** + * Filter the query on the template_id column + * + * Example usage: + * + * $query->filterByTemplateId(1234); // WHERE template_id = 1234 + * $query->filterByTemplateId(array(12, 34)); // WHERE template_id IN (12, 34) + * $query->filterByTemplateId(array('min' => 12)); // WHERE template_id > 12 + * + * + * @see filterByTemplate() + * + * @param mixed $templateId The value to use as filter. + * 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 ChildAttributeTemplateQuery The current query, for fluid interface + */ + public function filterByTemplateId($templateId = null, $comparison = null) + { + if (is_array($templateId)) { + $useMinMax = false; + if (isset($templateId['min'])) { + $this->addUsingAlias(AttributeTemplateTableMap::TEMPLATE_ID, $templateId['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($templateId['max'])) { + $this->addUsingAlias(AttributeTemplateTableMap::TEMPLATE_ID, $templateId['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(AttributeTemplateTableMap::TEMPLATE_ID, $templateId, $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 ChildAttributeTemplateQuery 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(AttributeTemplateTableMap::CREATED_AT, $createdAt['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($createdAt['max'])) { + $this->addUsingAlias(AttributeTemplateTableMap::CREATED_AT, $createdAt['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(AttributeTemplateTableMap::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 ChildAttributeTemplateQuery 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(AttributeTemplateTableMap::UPDATED_AT, $updatedAt['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($updatedAt['max'])) { + $this->addUsingAlias(AttributeTemplateTableMap::UPDATED_AT, $updatedAt['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(AttributeTemplateTableMap::UPDATED_AT, $updatedAt, $comparison); + } + + /** + * Filter the query by a related \Thelia\Model\Attribute object + * + * @param \Thelia\Model\Attribute|ObjectCollection $attribute The related object(s) to use as filter + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildAttributeTemplateQuery The current query, for fluid interface + */ + public function filterByAttribute($attribute, $comparison = null) + { + if ($attribute instanceof \Thelia\Model\Attribute) { + return $this + ->addUsingAlias(AttributeTemplateTableMap::ATTRIBUTE_ID, $attribute->getId(), $comparison); + } elseif ($attribute instanceof ObjectCollection) { + if (null === $comparison) { + $comparison = Criteria::IN; + } + + return $this + ->addUsingAlias(AttributeTemplateTableMap::ATTRIBUTE_ID, $attribute->toKeyValue('PrimaryKey', 'Id'), $comparison); + } else { + throw new PropelException('filterByAttribute() only accepts arguments of type \Thelia\Model\Attribute or Collection'); + } + } + + /** + * Adds a JOIN clause to the query using the Attribute relation + * + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return ChildAttributeTemplateQuery The current query, for fluid interface + */ + public function joinAttribute($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + $tableMap = $this->getTableMap(); + $relationMap = $tableMap->getRelation('Attribute'); + + // create a ModelJoin object for this join + $join = new ModelJoin(); + $join->setJoinType($joinType); + $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); + if ($previousJoin = $this->getPreviousJoin()) { + $join->setPreviousJoin($previousJoin); + } + + // add the ModelJoin to the current object + if ($relationAlias) { + $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); + $this->addJoinObject($join, $relationAlias); + } else { + $this->addJoinObject($join, 'Attribute'); + } + + return $this; + } + + /** + * Use the Attribute relation Attribute object + * + * @see useQuery() + * + * @param string $relationAlias optional alias for the relation, + * to be used as main alias in the secondary query + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return \Thelia\Model\AttributeQuery A secondary query class using the current class as primary query + */ + public function useAttributeQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + return $this + ->joinAttribute($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'Attribute', '\Thelia\Model\AttributeQuery'); + } + + /** + * Filter the query by a related \Thelia\Model\Template object + * + * @param \Thelia\Model\Template|ObjectCollection $template The related object(s) to use as filter + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildAttributeTemplateQuery The current query, for fluid interface + */ + public function filterByTemplate($template, $comparison = null) + { + if ($template instanceof \Thelia\Model\Template) { + return $this + ->addUsingAlias(AttributeTemplateTableMap::TEMPLATE_ID, $template->getId(), $comparison); + } elseif ($template instanceof ObjectCollection) { + if (null === $comparison) { + $comparison = Criteria::IN; + } + + return $this + ->addUsingAlias(AttributeTemplateTableMap::TEMPLATE_ID, $template->toKeyValue('PrimaryKey', 'Id'), $comparison); + } else { + throw new PropelException('filterByTemplate() only accepts arguments of type \Thelia\Model\Template or Collection'); + } + } + + /** + * Adds a JOIN clause to the query using the Template relation + * + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return ChildAttributeTemplateQuery The current query, for fluid interface + */ + public function joinTemplate($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + $tableMap = $this->getTableMap(); + $relationMap = $tableMap->getRelation('Template'); + + // create a ModelJoin object for this join + $join = new ModelJoin(); + $join->setJoinType($joinType); + $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); + if ($previousJoin = $this->getPreviousJoin()) { + $join->setPreviousJoin($previousJoin); + } + + // add the ModelJoin to the current object + if ($relationAlias) { + $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); + $this->addJoinObject($join, $relationAlias); + } else { + $this->addJoinObject($join, 'Template'); + } + + return $this; + } + + /** + * Use the Template relation Template object + * + * @see useQuery() + * + * @param string $relationAlias optional alias for the relation, + * to be used as main alias in the secondary query + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return \Thelia\Model\TemplateQuery A secondary query class using the current class as primary query + */ + public function useTemplateQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + return $this + ->joinTemplate($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'Template', '\Thelia\Model\TemplateQuery'); + } + + /** + * Exclude object from result + * + * @param ChildAttributeTemplate $attributeTemplate Object to remove from the list of results + * + * @return ChildAttributeTemplateQuery The current query, for fluid interface + */ + public function prune($attributeTemplate = null) + { + if ($attributeTemplate) { + $this->addUsingAlias(AttributeTemplateTableMap::ID, $attributeTemplate->getId(), Criteria::NOT_EQUAL); + } + + return $this; + } + + /** + * Deletes all rows from the attribute_template table. + * + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). + */ + public function doDeleteAll(ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(AttributeTemplateTableMap::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->beginTransaction(); + $affectedRows += parent::doDeleteAll($con); + // Because this db requires some delete cascade/set null emulation, we have to + // clear the cached instance *after* the emulation has happened (since + // instances get re-added by the select statement contained therein). + AttributeTemplateTableMap::clearInstancePool(); + AttributeTemplateTableMap::clearRelatedInstancePool(); + + $con->commit(); + } catch (PropelException $e) { + $con->rollBack(); + throw $e; + } + + return $affectedRows; + } + + /** + * Performs a DELETE on the database, given a ChildAttributeTemplate or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or ChildAttributeTemplate object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public function delete(ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(AttributeTemplateTableMap::DATABASE_NAME); + } + + $criteria = $this; + + // Set the correct dbName + $criteria->setDbName(AttributeTemplateTableMap::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->beginTransaction(); + + + AttributeTemplateTableMap::removeInstanceFromPool($criteria); + + $affectedRows += ModelCriteria::delete($con); + AttributeTemplateTableMap::clearRelatedInstancePool(); + $con->commit(); + + return $affectedRows; + } catch (PropelException $e) { + $con->rollBack(); + throw $e; + } + } + + // timestampable behavior + + /** + * Filter by the latest updated + * + * @param int $nbDays Maximum age of the latest update in days + * + * @return ChildAttributeTemplateQuery The current query, for fluid interface + */ + public function recentlyUpdated($nbDays = 7) + { + return $this->addUsingAlias(AttributeTemplateTableMap::UPDATED_AT, time() - $nbDays * 24 * 60 * 60, Criteria::GREATER_EQUAL); + } + + /** + * Filter by the latest created + * + * @param int $nbDays Maximum age of in days + * + * @return ChildAttributeTemplateQuery The current query, for fluid interface + */ + public function recentlyCreated($nbDays = 7) + { + return $this->addUsingAlias(AttributeTemplateTableMap::CREATED_AT, time() - $nbDays * 24 * 60 * 60, Criteria::GREATER_EQUAL); + } + + /** + * Order by update date desc + * + * @return ChildAttributeTemplateQuery The current query, for fluid interface + */ + public function lastUpdatedFirst() + { + return $this->addDescendingOrderByColumn(AttributeTemplateTableMap::UPDATED_AT); + } + + /** + * Order by update date asc + * + * @return ChildAttributeTemplateQuery The current query, for fluid interface + */ + public function firstUpdatedFirst() + { + return $this->addAscendingOrderByColumn(AttributeTemplateTableMap::UPDATED_AT); + } + + /** + * Order by create date desc + * + * @return ChildAttributeTemplateQuery The current query, for fluid interface + */ + public function lastCreatedFirst() + { + return $this->addDescendingOrderByColumn(AttributeTemplateTableMap::CREATED_AT); + } + + /** + * Order by create date asc + * + * @return ChildAttributeTemplateQuery The current query, for fluid interface + */ + public function firstCreatedFirst() + { + return $this->addAscendingOrderByColumn(AttributeTemplateTableMap::CREATED_AT); + } + +} // AttributeTemplateQuery diff --git a/core/lib/Thelia/Model/Base/Category.php b/core/lib/Thelia/Model/Base/Category.php index ee56670a1..6dc9b727a 100644 --- a/core/lib/Thelia/Model/Base/Category.php +++ b/core/lib/Thelia/Model/Base/Category.php @@ -17,10 +17,6 @@ use Propel\Runtime\Exception\PropelException; use Propel\Runtime\Map\TableMap; use Propel\Runtime\Parser\AbstractParser; use Propel\Runtime\Util\PropelDateTime; -use Thelia\Model\Attribute as ChildAttribute; -use Thelia\Model\AttributeCategory as ChildAttributeCategory; -use Thelia\Model\AttributeCategoryQuery as ChildAttributeCategoryQuery; -use Thelia\Model\AttributeQuery as ChildAttributeQuery; use Thelia\Model\Category as ChildCategory; use Thelia\Model\CategoryAssociatedContent as ChildCategoryAssociatedContent; use Thelia\Model\CategoryAssociatedContentQuery as ChildCategoryAssociatedContentQuery; @@ -33,10 +29,6 @@ use Thelia\Model\CategoryImageQuery as ChildCategoryImageQuery; use Thelia\Model\CategoryQuery as ChildCategoryQuery; use Thelia\Model\CategoryVersion as ChildCategoryVersion; use Thelia\Model\CategoryVersionQuery as ChildCategoryVersionQuery; -use Thelia\Model\Feature as ChildFeature; -use Thelia\Model\FeatureCategory as ChildFeatureCategory; -use Thelia\Model\FeatureCategoryQuery as ChildFeatureCategoryQuery; -use Thelia\Model\FeatureQuery as ChildFeatureQuery; use Thelia\Model\Product as ChildProduct; use Thelia\Model\ProductCategory as ChildProductCategory; use Thelia\Model\ProductCategoryQuery as ChildProductCategoryQuery; @@ -139,18 +131,6 @@ abstract class Category implements ActiveRecordInterface protected $collProductCategories; protected $collProductCategoriesPartial; - /** - * @var ObjectCollection|ChildFeatureCategory[] Collection to store aggregation of ChildFeatureCategory objects. - */ - protected $collFeatureCategories; - protected $collFeatureCategoriesPartial; - - /** - * @var ObjectCollection|ChildAttributeCategory[] Collection to store aggregation of ChildAttributeCategory objects. - */ - protected $collAttributeCategories; - protected $collAttributeCategoriesPartial; - /** * @var ObjectCollection|ChildCategoryImage[] Collection to store aggregation of ChildCategoryImage objects. */ @@ -186,16 +166,6 @@ abstract class Category implements ActiveRecordInterface */ protected $collProducts; - /** - * @var ChildFeature[] Collection to store aggregation of ChildFeature objects. - */ - protected $collFeatures; - - /** - * @var ChildAttribute[] Collection to store aggregation of ChildAttribute objects. - */ - protected $collAttributes; - /** * Flag to prevent endless save loop, if this object is referenced * by another object which falls in this transaction. @@ -232,36 +202,12 @@ abstract class Category implements ActiveRecordInterface */ protected $productsScheduledForDeletion = null; - /** - * An array of objects scheduled for deletion. - * @var ObjectCollection - */ - protected $featuresScheduledForDeletion = null; - - /** - * An array of objects scheduled for deletion. - * @var ObjectCollection - */ - protected $attributesScheduledForDeletion = null; - /** * An array of objects scheduled for deletion. * @var ObjectCollection */ protected $productCategoriesScheduledForDeletion = null; - /** - * An array of objects scheduled for deletion. - * @var ObjectCollection - */ - protected $featureCategoriesScheduledForDeletion = null; - - /** - * An array of objects scheduled for deletion. - * @var ObjectCollection - */ - protected $attributeCategoriesScheduledForDeletion = null; - /** * An array of objects scheduled for deletion. * @var ObjectCollection @@ -1021,10 +967,6 @@ abstract class Category implements ActiveRecordInterface $this->collProductCategories = null; - $this->collFeatureCategories = null; - - $this->collAttributeCategories = null; - $this->collCategoryImages = null; $this->collCategoryDocuments = null; @@ -1036,8 +978,6 @@ abstract class Category implements ActiveRecordInterface $this->collCategoryVersions = null; $this->collProducts = null; - $this->collFeatures = null; - $this->collAttributes = null; } // if (deep) } @@ -1210,60 +1150,6 @@ abstract class Category implements ActiveRecordInterface } } - if ($this->featuresScheduledForDeletion !== null) { - if (!$this->featuresScheduledForDeletion->isEmpty()) { - $pks = array(); - $pk = $this->getPrimaryKey(); - foreach ($this->featuresScheduledForDeletion->getPrimaryKeys(false) as $remotePk) { - $pks[] = array($pk, $remotePk); - } - - FeatureCategoryQuery::create() - ->filterByPrimaryKeys($pks) - ->delete($con); - $this->featuresScheduledForDeletion = null; - } - - foreach ($this->getFeatures() as $feature) { - if ($feature->isModified()) { - $feature->save($con); - } - } - } elseif ($this->collFeatures) { - foreach ($this->collFeatures as $feature) { - if ($feature->isModified()) { - $feature->save($con); - } - } - } - - if ($this->attributesScheduledForDeletion !== null) { - if (!$this->attributesScheduledForDeletion->isEmpty()) { - $pks = array(); - $pk = $this->getPrimaryKey(); - foreach ($this->attributesScheduledForDeletion->getPrimaryKeys(false) as $remotePk) { - $pks[] = array($pk, $remotePk); - } - - AttributeCategoryQuery::create() - ->filterByPrimaryKeys($pks) - ->delete($con); - $this->attributesScheduledForDeletion = null; - } - - foreach ($this->getAttributes() as $attribute) { - if ($attribute->isModified()) { - $attribute->save($con); - } - } - } elseif ($this->collAttributes) { - foreach ($this->collAttributes as $attribute) { - if ($attribute->isModified()) { - $attribute->save($con); - } - } - } - if ($this->productCategoriesScheduledForDeletion !== null) { if (!$this->productCategoriesScheduledForDeletion->isEmpty()) { \Thelia\Model\ProductCategoryQuery::create() @@ -1281,40 +1167,6 @@ abstract class Category implements ActiveRecordInterface } } - if ($this->featureCategoriesScheduledForDeletion !== null) { - if (!$this->featureCategoriesScheduledForDeletion->isEmpty()) { - \Thelia\Model\FeatureCategoryQuery::create() - ->filterByPrimaryKeys($this->featureCategoriesScheduledForDeletion->getPrimaryKeys(false)) - ->delete($con); - $this->featureCategoriesScheduledForDeletion = null; - } - } - - if ($this->collFeatureCategories !== null) { - foreach ($this->collFeatureCategories as $referrerFK) { - if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) { - $affectedRows += $referrerFK->save($con); - } - } - } - - if ($this->attributeCategoriesScheduledForDeletion !== null) { - if (!$this->attributeCategoriesScheduledForDeletion->isEmpty()) { - \Thelia\Model\AttributeCategoryQuery::create() - ->filterByPrimaryKeys($this->attributeCategoriesScheduledForDeletion->getPrimaryKeys(false)) - ->delete($con); - $this->attributeCategoriesScheduledForDeletion = null; - } - } - - if ($this->collAttributeCategories !== null) { - foreach ($this->collAttributeCategories as $referrerFK) { - if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) { - $affectedRows += $referrerFK->save($con); - } - } - } - if ($this->categoryImagesScheduledForDeletion !== null) { if (!$this->categoryImagesScheduledForDeletion->isEmpty()) { \Thelia\Model\CategoryImageQuery::create() @@ -1629,12 +1481,6 @@ abstract class Category implements ActiveRecordInterface if (null !== $this->collProductCategories) { $result['ProductCategories'] = $this->collProductCategories->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); } - if (null !== $this->collFeatureCategories) { - $result['FeatureCategories'] = $this->collFeatureCategories->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); - } - if (null !== $this->collAttributeCategories) { - $result['AttributeCategories'] = $this->collAttributeCategories->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); - } if (null !== $this->collCategoryImages) { $result['CategoryImages'] = $this->collCategoryImages->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); } @@ -1847,18 +1693,6 @@ abstract class Category implements ActiveRecordInterface } } - foreach ($this->getFeatureCategories() as $relObj) { - if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves - $copyObj->addFeatureCategory($relObj->copy($deepCopy)); - } - } - - foreach ($this->getAttributeCategories() as $relObj) { - if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves - $copyObj->addAttributeCategory($relObj->copy($deepCopy)); - } - } - foreach ($this->getCategoryImages() as $relObj) { if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves $copyObj->addCategoryImage($relObj->copy($deepCopy)); @@ -1933,12 +1767,6 @@ abstract class Category implements ActiveRecordInterface if ('ProductCategory' == $relationName) { return $this->initProductCategories(); } - if ('FeatureCategory' == $relationName) { - return $this->initFeatureCategories(); - } - if ('AttributeCategory' == $relationName) { - return $this->initAttributeCategories(); - } if ('CategoryImage' == $relationName) { return $this->initCategoryImages(); } @@ -2202,492 +2030,6 @@ abstract class Category implements ActiveRecordInterface return $this->getProductCategories($query, $con); } - /** - * Clears out the collFeatureCategories collection - * - * This does not modify the database; however, it will remove any associated objects, causing - * them to be refetched by subsequent calls to accessor method. - * - * @return void - * @see addFeatureCategories() - */ - public function clearFeatureCategories() - { - $this->collFeatureCategories = null; // important to set this to NULL since that means it is uninitialized - } - - /** - * Reset is the collFeatureCategories collection loaded partially. - */ - public function resetPartialFeatureCategories($v = true) - { - $this->collFeatureCategoriesPartial = $v; - } - - /** - * Initializes the collFeatureCategories collection. - * - * By default this just sets the collFeatureCategories collection to an empty array (like clearcollFeatureCategories()); - * however, you may wish to override this method in your stub class to provide setting appropriate - * to your application -- for example, setting the initial array to the values stored in database. - * - * @param boolean $overrideExisting If set to true, the method call initializes - * the collection even if it is not empty - * - * @return void - */ - public function initFeatureCategories($overrideExisting = true) - { - if (null !== $this->collFeatureCategories && !$overrideExisting) { - return; - } - $this->collFeatureCategories = new ObjectCollection(); - $this->collFeatureCategories->setModel('\Thelia\Model\FeatureCategory'); - } - - /** - * Gets an array of ChildFeatureCategory objects which contain a foreign key that references this object. - * - * If the $criteria is not null, it is used to always fetch the results from the database. - * Otherwise the results are fetched from the database the first time, then cached. - * Next time the same method is called without $criteria, the cached collection is returned. - * If this ChildCategory is new, it will return - * an empty collection or the current collection; the criteria is ignored on a new object. - * - * @param Criteria $criteria optional Criteria object to narrow the query - * @param ConnectionInterface $con optional connection object - * @return Collection|ChildFeatureCategory[] List of ChildFeatureCategory objects - * @throws PropelException - */ - public function getFeatureCategories($criteria = null, ConnectionInterface $con = null) - { - $partial = $this->collFeatureCategoriesPartial && !$this->isNew(); - if (null === $this->collFeatureCategories || null !== $criteria || $partial) { - if ($this->isNew() && null === $this->collFeatureCategories) { - // return empty collection - $this->initFeatureCategories(); - } else { - $collFeatureCategories = ChildFeatureCategoryQuery::create(null, $criteria) - ->filterByCategory($this) - ->find($con); - - if (null !== $criteria) { - if (false !== $this->collFeatureCategoriesPartial && count($collFeatureCategories)) { - $this->initFeatureCategories(false); - - foreach ($collFeatureCategories as $obj) { - if (false == $this->collFeatureCategories->contains($obj)) { - $this->collFeatureCategories->append($obj); - } - } - - $this->collFeatureCategoriesPartial = true; - } - - $collFeatureCategories->getInternalIterator()->rewind(); - - return $collFeatureCategories; - } - - if ($partial && $this->collFeatureCategories) { - foreach ($this->collFeatureCategories as $obj) { - if ($obj->isNew()) { - $collFeatureCategories[] = $obj; - } - } - } - - $this->collFeatureCategories = $collFeatureCategories; - $this->collFeatureCategoriesPartial = false; - } - } - - return $this->collFeatureCategories; - } - - /** - * Sets a collection of FeatureCategory objects related by a one-to-many relationship - * to the current object. - * It will also schedule objects for deletion based on a diff between old objects (aka persisted) - * and new objects from the given Propel collection. - * - * @param Collection $featureCategories A Propel collection. - * @param ConnectionInterface $con Optional connection object - * @return ChildCategory The current object (for fluent API support) - */ - public function setFeatureCategories(Collection $featureCategories, ConnectionInterface $con = null) - { - $featureCategoriesToDelete = $this->getFeatureCategories(new Criteria(), $con)->diff($featureCategories); - - - $this->featureCategoriesScheduledForDeletion = $featureCategoriesToDelete; - - foreach ($featureCategoriesToDelete as $featureCategoryRemoved) { - $featureCategoryRemoved->setCategory(null); - } - - $this->collFeatureCategories = null; - foreach ($featureCategories as $featureCategory) { - $this->addFeatureCategory($featureCategory); - } - - $this->collFeatureCategories = $featureCategories; - $this->collFeatureCategoriesPartial = false; - - return $this; - } - - /** - * Returns the number of related FeatureCategory objects. - * - * @param Criteria $criteria - * @param boolean $distinct - * @param ConnectionInterface $con - * @return int Count of related FeatureCategory objects. - * @throws PropelException - */ - public function countFeatureCategories(Criteria $criteria = null, $distinct = false, ConnectionInterface $con = null) - { - $partial = $this->collFeatureCategoriesPartial && !$this->isNew(); - if (null === $this->collFeatureCategories || null !== $criteria || $partial) { - if ($this->isNew() && null === $this->collFeatureCategories) { - return 0; - } - - if ($partial && !$criteria) { - return count($this->getFeatureCategories()); - } - - $query = ChildFeatureCategoryQuery::create(null, $criteria); - if ($distinct) { - $query->distinct(); - } - - return $query - ->filterByCategory($this) - ->count($con); - } - - return count($this->collFeatureCategories); - } - - /** - * Method called to associate a ChildFeatureCategory object to this object - * through the ChildFeatureCategory foreign key attribute. - * - * @param ChildFeatureCategory $l ChildFeatureCategory - * @return \Thelia\Model\Category The current object (for fluent API support) - */ - public function addFeatureCategory(ChildFeatureCategory $l) - { - if ($this->collFeatureCategories === null) { - $this->initFeatureCategories(); - $this->collFeatureCategoriesPartial = true; - } - - if (!in_array($l, $this->collFeatureCategories->getArrayCopy(), true)) { // only add it if the **same** object is not already associated - $this->doAddFeatureCategory($l); - } - - return $this; - } - - /** - * @param FeatureCategory $featureCategory The featureCategory object to add. - */ - protected function doAddFeatureCategory($featureCategory) - { - $this->collFeatureCategories[]= $featureCategory; - $featureCategory->setCategory($this); - } - - /** - * @param FeatureCategory $featureCategory The featureCategory object to remove. - * @return ChildCategory The current object (for fluent API support) - */ - public function removeFeatureCategory($featureCategory) - { - if ($this->getFeatureCategories()->contains($featureCategory)) { - $this->collFeatureCategories->remove($this->collFeatureCategories->search($featureCategory)); - if (null === $this->featureCategoriesScheduledForDeletion) { - $this->featureCategoriesScheduledForDeletion = clone $this->collFeatureCategories; - $this->featureCategoriesScheduledForDeletion->clear(); - } - $this->featureCategoriesScheduledForDeletion[]= clone $featureCategory; - $featureCategory->setCategory(null); - } - - return $this; - } - - - /** - * If this collection has already been initialized with - * an identical criteria, it returns the collection. - * Otherwise if this Category is new, it will return - * an empty collection; or if this Category has previously - * been saved, it will retrieve related FeatureCategories from storage. - * - * This method is protected by default in order to keep the public - * api reasonable. You can provide public methods for those you - * actually need in Category. - * - * @param Criteria $criteria optional Criteria object to narrow the query - * @param ConnectionInterface $con optional connection object - * @param string $joinBehavior optional join type to use (defaults to Criteria::LEFT_JOIN) - * @return Collection|ChildFeatureCategory[] List of ChildFeatureCategory objects - */ - public function getFeatureCategoriesJoinFeature($criteria = null, $con = null, $joinBehavior = Criteria::LEFT_JOIN) - { - $query = ChildFeatureCategoryQuery::create(null, $criteria); - $query->joinWith('Feature', $joinBehavior); - - return $this->getFeatureCategories($query, $con); - } - - /** - * Clears out the collAttributeCategories collection - * - * This does not modify the database; however, it will remove any associated objects, causing - * them to be refetched by subsequent calls to accessor method. - * - * @return void - * @see addAttributeCategories() - */ - public function clearAttributeCategories() - { - $this->collAttributeCategories = null; // important to set this to NULL since that means it is uninitialized - } - - /** - * Reset is the collAttributeCategories collection loaded partially. - */ - public function resetPartialAttributeCategories($v = true) - { - $this->collAttributeCategoriesPartial = $v; - } - - /** - * Initializes the collAttributeCategories collection. - * - * By default this just sets the collAttributeCategories collection to an empty array (like clearcollAttributeCategories()); - * however, you may wish to override this method in your stub class to provide setting appropriate - * to your application -- for example, setting the initial array to the values stored in database. - * - * @param boolean $overrideExisting If set to true, the method call initializes - * the collection even if it is not empty - * - * @return void - */ - public function initAttributeCategories($overrideExisting = true) - { - if (null !== $this->collAttributeCategories && !$overrideExisting) { - return; - } - $this->collAttributeCategories = new ObjectCollection(); - $this->collAttributeCategories->setModel('\Thelia\Model\AttributeCategory'); - } - - /** - * Gets an array of ChildAttributeCategory objects which contain a foreign key that references this object. - * - * If the $criteria is not null, it is used to always fetch the results from the database. - * Otherwise the results are fetched from the database the first time, then cached. - * Next time the same method is called without $criteria, the cached collection is returned. - * If this ChildCategory is new, it will return - * an empty collection or the current collection; the criteria is ignored on a new object. - * - * @param Criteria $criteria optional Criteria object to narrow the query - * @param ConnectionInterface $con optional connection object - * @return Collection|ChildAttributeCategory[] List of ChildAttributeCategory objects - * @throws PropelException - */ - public function getAttributeCategories($criteria = null, ConnectionInterface $con = null) - { - $partial = $this->collAttributeCategoriesPartial && !$this->isNew(); - if (null === $this->collAttributeCategories || null !== $criteria || $partial) { - if ($this->isNew() && null === $this->collAttributeCategories) { - // return empty collection - $this->initAttributeCategories(); - } else { - $collAttributeCategories = ChildAttributeCategoryQuery::create(null, $criteria) - ->filterByCategory($this) - ->find($con); - - if (null !== $criteria) { - if (false !== $this->collAttributeCategoriesPartial && count($collAttributeCategories)) { - $this->initAttributeCategories(false); - - foreach ($collAttributeCategories as $obj) { - if (false == $this->collAttributeCategories->contains($obj)) { - $this->collAttributeCategories->append($obj); - } - } - - $this->collAttributeCategoriesPartial = true; - } - - $collAttributeCategories->getInternalIterator()->rewind(); - - return $collAttributeCategories; - } - - if ($partial && $this->collAttributeCategories) { - foreach ($this->collAttributeCategories as $obj) { - if ($obj->isNew()) { - $collAttributeCategories[] = $obj; - } - } - } - - $this->collAttributeCategories = $collAttributeCategories; - $this->collAttributeCategoriesPartial = false; - } - } - - return $this->collAttributeCategories; - } - - /** - * Sets a collection of AttributeCategory objects related by a one-to-many relationship - * to the current object. - * It will also schedule objects for deletion based on a diff between old objects (aka persisted) - * and new objects from the given Propel collection. - * - * @param Collection $attributeCategories A Propel collection. - * @param ConnectionInterface $con Optional connection object - * @return ChildCategory The current object (for fluent API support) - */ - public function setAttributeCategories(Collection $attributeCategories, ConnectionInterface $con = null) - { - $attributeCategoriesToDelete = $this->getAttributeCategories(new Criteria(), $con)->diff($attributeCategories); - - - $this->attributeCategoriesScheduledForDeletion = $attributeCategoriesToDelete; - - foreach ($attributeCategoriesToDelete as $attributeCategoryRemoved) { - $attributeCategoryRemoved->setCategory(null); - } - - $this->collAttributeCategories = null; - foreach ($attributeCategories as $attributeCategory) { - $this->addAttributeCategory($attributeCategory); - } - - $this->collAttributeCategories = $attributeCategories; - $this->collAttributeCategoriesPartial = false; - - return $this; - } - - /** - * Returns the number of related AttributeCategory objects. - * - * @param Criteria $criteria - * @param boolean $distinct - * @param ConnectionInterface $con - * @return int Count of related AttributeCategory objects. - * @throws PropelException - */ - public function countAttributeCategories(Criteria $criteria = null, $distinct = false, ConnectionInterface $con = null) - { - $partial = $this->collAttributeCategoriesPartial && !$this->isNew(); - if (null === $this->collAttributeCategories || null !== $criteria || $partial) { - if ($this->isNew() && null === $this->collAttributeCategories) { - return 0; - } - - if ($partial && !$criteria) { - return count($this->getAttributeCategories()); - } - - $query = ChildAttributeCategoryQuery::create(null, $criteria); - if ($distinct) { - $query->distinct(); - } - - return $query - ->filterByCategory($this) - ->count($con); - } - - return count($this->collAttributeCategories); - } - - /** - * Method called to associate a ChildAttributeCategory object to this object - * through the ChildAttributeCategory foreign key attribute. - * - * @param ChildAttributeCategory $l ChildAttributeCategory - * @return \Thelia\Model\Category The current object (for fluent API support) - */ - public function addAttributeCategory(ChildAttributeCategory $l) - { - if ($this->collAttributeCategories === null) { - $this->initAttributeCategories(); - $this->collAttributeCategoriesPartial = true; - } - - if (!in_array($l, $this->collAttributeCategories->getArrayCopy(), true)) { // only add it if the **same** object is not already associated - $this->doAddAttributeCategory($l); - } - - return $this; - } - - /** - * @param AttributeCategory $attributeCategory The attributeCategory object to add. - */ - protected function doAddAttributeCategory($attributeCategory) - { - $this->collAttributeCategories[]= $attributeCategory; - $attributeCategory->setCategory($this); - } - - /** - * @param AttributeCategory $attributeCategory The attributeCategory object to remove. - * @return ChildCategory The current object (for fluent API support) - */ - public function removeAttributeCategory($attributeCategory) - { - if ($this->getAttributeCategories()->contains($attributeCategory)) { - $this->collAttributeCategories->remove($this->collAttributeCategories->search($attributeCategory)); - if (null === $this->attributeCategoriesScheduledForDeletion) { - $this->attributeCategoriesScheduledForDeletion = clone $this->collAttributeCategories; - $this->attributeCategoriesScheduledForDeletion->clear(); - } - $this->attributeCategoriesScheduledForDeletion[]= clone $attributeCategory; - $attributeCategory->setCategory(null); - } - - return $this; - } - - - /** - * If this collection has already been initialized with - * an identical criteria, it returns the collection. - * Otherwise if this Category is new, it will return - * an empty collection; or if this Category has previously - * been saved, it will retrieve related AttributeCategories from storage. - * - * This method is protected by default in order to keep the public - * api reasonable. You can provide public methods for those you - * actually need in Category. - * - * @param Criteria $criteria optional Criteria object to narrow the query - * @param ConnectionInterface $con optional connection object - * @param string $joinBehavior optional join type to use (defaults to Criteria::LEFT_JOIN) - * @return Collection|ChildAttributeCategory[] List of ChildAttributeCategory objects - */ - public function getAttributeCategoriesJoinAttribute($criteria = null, $con = null, $joinBehavior = Criteria::LEFT_JOIN) - { - $query = ChildAttributeCategoryQuery::create(null, $criteria); - $query->joinWith('Attribute', $joinBehavior); - - return $this->getAttributeCategories($query, $con); - } - /** * Clears out the collCategoryImages collection * @@ -3996,372 +3338,6 @@ abstract class Category implements ActiveRecordInterface return $this; } - /** - * Clears out the collFeatures collection - * - * This does not modify the database; however, it will remove any associated objects, causing - * them to be refetched by subsequent calls to accessor method. - * - * @return void - * @see addFeatures() - */ - public function clearFeatures() - { - $this->collFeatures = null; // important to set this to NULL since that means it is uninitialized - $this->collFeaturesPartial = null; - } - - /** - * Initializes the collFeatures collection. - * - * By default this just sets the collFeatures collection to an empty collection (like clearFeatures()); - * however, you may wish to override this method in your stub class to provide setting appropriate - * to your application -- for example, setting the initial array to the values stored in database. - * - * @return void - */ - public function initFeatures() - { - $this->collFeatures = new ObjectCollection(); - $this->collFeatures->setModel('\Thelia\Model\Feature'); - } - - /** - * Gets a collection of ChildFeature objects related by a many-to-many relationship - * to the current object by way of the feature_category cross-reference table. - * - * If the $criteria is not null, it is used to always fetch the results from the database. - * Otherwise the results are fetched from the database the first time, then cached. - * Next time the same method is called without $criteria, the cached collection is returned. - * If this ChildCategory is new, it will return - * an empty collection or the current collection; the criteria is ignored on a new object. - * - * @param Criteria $criteria Optional query object to filter the query - * @param ConnectionInterface $con Optional connection object - * - * @return ObjectCollection|ChildFeature[] List of ChildFeature objects - */ - public function getFeatures($criteria = null, ConnectionInterface $con = null) - { - if (null === $this->collFeatures || null !== $criteria) { - if ($this->isNew() && null === $this->collFeatures) { - // return empty collection - $this->initFeatures(); - } else { - $collFeatures = ChildFeatureQuery::create(null, $criteria) - ->filterByCategory($this) - ->find($con); - if (null !== $criteria) { - return $collFeatures; - } - $this->collFeatures = $collFeatures; - } - } - - return $this->collFeatures; - } - - /** - * Sets a collection of Feature objects related by a many-to-many relationship - * to the current object by way of the feature_category cross-reference table. - * It will also schedule objects for deletion based on a diff between old objects (aka persisted) - * and new objects from the given Propel collection. - * - * @param Collection $features A Propel collection. - * @param ConnectionInterface $con Optional connection object - * @return ChildCategory The current object (for fluent API support) - */ - public function setFeatures(Collection $features, ConnectionInterface $con = null) - { - $this->clearFeatures(); - $currentFeatures = $this->getFeatures(); - - $this->featuresScheduledForDeletion = $currentFeatures->diff($features); - - foreach ($features as $feature) { - if (!$currentFeatures->contains($feature)) { - $this->doAddFeature($feature); - } - } - - $this->collFeatures = $features; - - return $this; - } - - /** - * Gets the number of ChildFeature objects related by a many-to-many relationship - * to the current object by way of the feature_category cross-reference table. - * - * @param Criteria $criteria Optional query object to filter the query - * @param boolean $distinct Set to true to force count distinct - * @param ConnectionInterface $con Optional connection object - * - * @return int the number of related ChildFeature objects - */ - public function countFeatures($criteria = null, $distinct = false, ConnectionInterface $con = null) - { - if (null === $this->collFeatures || null !== $criteria) { - if ($this->isNew() && null === $this->collFeatures) { - return 0; - } else { - $query = ChildFeatureQuery::create(null, $criteria); - if ($distinct) { - $query->distinct(); - } - - return $query - ->filterByCategory($this) - ->count($con); - } - } else { - return count($this->collFeatures); - } - } - - /** - * Associate a ChildFeature object to this object - * through the feature_category cross reference table. - * - * @param ChildFeature $feature The ChildFeatureCategory object to relate - * @return ChildCategory The current object (for fluent API support) - */ - public function addFeature(ChildFeature $feature) - { - if ($this->collFeatures === null) { - $this->initFeatures(); - } - - if (!$this->collFeatures->contains($feature)) { // only add it if the **same** object is not already associated - $this->doAddFeature($feature); - $this->collFeatures[] = $feature; - } - - return $this; - } - - /** - * @param Feature $feature The feature object to add. - */ - protected function doAddFeature($feature) - { - $featureCategory = new ChildFeatureCategory(); - $featureCategory->setFeature($feature); - $this->addFeatureCategory($featureCategory); - // set the back reference to this object directly as using provided method either results - // in endless loop or in multiple relations - if (!$feature->getCategories()->contains($this)) { - $foreignCollection = $feature->getCategories(); - $foreignCollection[] = $this; - } - } - - /** - * Remove a ChildFeature object to this object - * through the feature_category cross reference table. - * - * @param ChildFeature $feature The ChildFeatureCategory object to relate - * @return ChildCategory The current object (for fluent API support) - */ - public function removeFeature(ChildFeature $feature) - { - if ($this->getFeatures()->contains($feature)) { - $this->collFeatures->remove($this->collFeatures->search($feature)); - - if (null === $this->featuresScheduledForDeletion) { - $this->featuresScheduledForDeletion = clone $this->collFeatures; - $this->featuresScheduledForDeletion->clear(); - } - - $this->featuresScheduledForDeletion[] = $feature; - } - - return $this; - } - - /** - * Clears out the collAttributes collection - * - * This does not modify the database; however, it will remove any associated objects, causing - * them to be refetched by subsequent calls to accessor method. - * - * @return void - * @see addAttributes() - */ - public function clearAttributes() - { - $this->collAttributes = null; // important to set this to NULL since that means it is uninitialized - $this->collAttributesPartial = null; - } - - /** - * Initializes the collAttributes collection. - * - * By default this just sets the collAttributes collection to an empty collection (like clearAttributes()); - * however, you may wish to override this method in your stub class to provide setting appropriate - * to your application -- for example, setting the initial array to the values stored in database. - * - * @return void - */ - public function initAttributes() - { - $this->collAttributes = new ObjectCollection(); - $this->collAttributes->setModel('\Thelia\Model\Attribute'); - } - - /** - * Gets a collection of ChildAttribute objects related by a many-to-many relationship - * to the current object by way of the attribute_category cross-reference table. - * - * If the $criteria is not null, it is used to always fetch the results from the database. - * Otherwise the results are fetched from the database the first time, then cached. - * Next time the same method is called without $criteria, the cached collection is returned. - * If this ChildCategory is new, it will return - * an empty collection or the current collection; the criteria is ignored on a new object. - * - * @param Criteria $criteria Optional query object to filter the query - * @param ConnectionInterface $con Optional connection object - * - * @return ObjectCollection|ChildAttribute[] List of ChildAttribute objects - */ - public function getAttributes($criteria = null, ConnectionInterface $con = null) - { - if (null === $this->collAttributes || null !== $criteria) { - if ($this->isNew() && null === $this->collAttributes) { - // return empty collection - $this->initAttributes(); - } else { - $collAttributes = ChildAttributeQuery::create(null, $criteria) - ->filterByCategory($this) - ->find($con); - if (null !== $criteria) { - return $collAttributes; - } - $this->collAttributes = $collAttributes; - } - } - - return $this->collAttributes; - } - - /** - * Sets a collection of Attribute objects related by a many-to-many relationship - * to the current object by way of the attribute_category cross-reference table. - * It will also schedule objects for deletion based on a diff between old objects (aka persisted) - * and new objects from the given Propel collection. - * - * @param Collection $attributes A Propel collection. - * @param ConnectionInterface $con Optional connection object - * @return ChildCategory The current object (for fluent API support) - */ - public function setAttributes(Collection $attributes, ConnectionInterface $con = null) - { - $this->clearAttributes(); - $currentAttributes = $this->getAttributes(); - - $this->attributesScheduledForDeletion = $currentAttributes->diff($attributes); - - foreach ($attributes as $attribute) { - if (!$currentAttributes->contains($attribute)) { - $this->doAddAttribute($attribute); - } - } - - $this->collAttributes = $attributes; - - return $this; - } - - /** - * Gets the number of ChildAttribute objects related by a many-to-many relationship - * to the current object by way of the attribute_category cross-reference table. - * - * @param Criteria $criteria Optional query object to filter the query - * @param boolean $distinct Set to true to force count distinct - * @param ConnectionInterface $con Optional connection object - * - * @return int the number of related ChildAttribute objects - */ - public function countAttributes($criteria = null, $distinct = false, ConnectionInterface $con = null) - { - if (null === $this->collAttributes || null !== $criteria) { - if ($this->isNew() && null === $this->collAttributes) { - return 0; - } else { - $query = ChildAttributeQuery::create(null, $criteria); - if ($distinct) { - $query->distinct(); - } - - return $query - ->filterByCategory($this) - ->count($con); - } - } else { - return count($this->collAttributes); - } - } - - /** - * Associate a ChildAttribute object to this object - * through the attribute_category cross reference table. - * - * @param ChildAttribute $attribute The ChildAttributeCategory object to relate - * @return ChildCategory The current object (for fluent API support) - */ - public function addAttribute(ChildAttribute $attribute) - { - if ($this->collAttributes === null) { - $this->initAttributes(); - } - - if (!$this->collAttributes->contains($attribute)) { // only add it if the **same** object is not already associated - $this->doAddAttribute($attribute); - $this->collAttributes[] = $attribute; - } - - return $this; - } - - /** - * @param Attribute $attribute The attribute object to add. - */ - protected function doAddAttribute($attribute) - { - $attributeCategory = new ChildAttributeCategory(); - $attributeCategory->setAttribute($attribute); - $this->addAttributeCategory($attributeCategory); - // set the back reference to this object directly as using provided method either results - // in endless loop or in multiple relations - if (!$attribute->getCategories()->contains($this)) { - $foreignCollection = $attribute->getCategories(); - $foreignCollection[] = $this; - } - } - - /** - * Remove a ChildAttribute object to this object - * through the attribute_category cross reference table. - * - * @param ChildAttribute $attribute The ChildAttributeCategory object to relate - * @return ChildCategory The current object (for fluent API support) - */ - public function removeAttribute(ChildAttribute $attribute) - { - if ($this->getAttributes()->contains($attribute)) { - $this->collAttributes->remove($this->collAttributes->search($attribute)); - - if (null === $this->attributesScheduledForDeletion) { - $this->attributesScheduledForDeletion = clone $this->collAttributes; - $this->attributesScheduledForDeletion->clear(); - } - - $this->attributesScheduledForDeletion[] = $attribute; - } - - return $this; - } - /** * Clears the current object and sets all attributes to their default values */ @@ -4401,16 +3377,6 @@ abstract class Category implements ActiveRecordInterface $o->clearAllReferences($deep); } } - if ($this->collFeatureCategories) { - foreach ($this->collFeatureCategories as $o) { - $o->clearAllReferences($deep); - } - } - if ($this->collAttributeCategories) { - foreach ($this->collAttributeCategories as $o) { - $o->clearAllReferences($deep); - } - } if ($this->collCategoryImages) { foreach ($this->collCategoryImages as $o) { $o->clearAllReferences($deep); @@ -4441,16 +3407,6 @@ abstract class Category implements ActiveRecordInterface $o->clearAllReferences($deep); } } - if ($this->collFeatures) { - foreach ($this->collFeatures as $o) { - $o->clearAllReferences($deep); - } - } - if ($this->collAttributes) { - foreach ($this->collAttributes as $o) { - $o->clearAllReferences($deep); - } - } } // if ($deep) // i18n behavior @@ -4461,14 +3417,6 @@ abstract class Category implements ActiveRecordInterface $this->collProductCategories->clearIterator(); } $this->collProductCategories = null; - if ($this->collFeatureCategories instanceof Collection) { - $this->collFeatureCategories->clearIterator(); - } - $this->collFeatureCategories = null; - if ($this->collAttributeCategories instanceof Collection) { - $this->collAttributeCategories->clearIterator(); - } - $this->collAttributeCategories = null; if ($this->collCategoryImages instanceof Collection) { $this->collCategoryImages->clearIterator(); } @@ -4493,14 +3441,6 @@ abstract class Category implements ActiveRecordInterface $this->collProducts->clearIterator(); } $this->collProducts = null; - if ($this->collFeatures instanceof Collection) { - $this->collFeatures->clearIterator(); - } - $this->collFeatures = null; - if ($this->collAttributes instanceof Collection) { - $this->collAttributes->clearIterator(); - } - $this->collAttributes = null; } /** diff --git a/core/lib/Thelia/Model/Base/CategoryQuery.php b/core/lib/Thelia/Model/Base/CategoryQuery.php index 7f0fb8f1c..4ef552094 100644 --- a/core/lib/Thelia/Model/Base/CategoryQuery.php +++ b/core/lib/Thelia/Model/Base/CategoryQuery.php @@ -50,14 +50,6 @@ use Thelia\Model\Map\CategoryTableMap; * @method ChildCategoryQuery rightJoinProductCategory($relationAlias = null) Adds a RIGHT JOIN clause to the query using the ProductCategory relation * @method ChildCategoryQuery innerJoinProductCategory($relationAlias = null) Adds a INNER JOIN clause to the query using the ProductCategory relation * - * @method ChildCategoryQuery leftJoinFeatureCategory($relationAlias = null) Adds a LEFT JOIN clause to the query using the FeatureCategory relation - * @method ChildCategoryQuery rightJoinFeatureCategory($relationAlias = null) Adds a RIGHT JOIN clause to the query using the FeatureCategory relation - * @method ChildCategoryQuery innerJoinFeatureCategory($relationAlias = null) Adds a INNER JOIN clause to the query using the FeatureCategory relation - * - * @method ChildCategoryQuery leftJoinAttributeCategory($relationAlias = null) Adds a LEFT JOIN clause to the query using the AttributeCategory relation - * @method ChildCategoryQuery rightJoinAttributeCategory($relationAlias = null) Adds a RIGHT JOIN clause to the query using the AttributeCategory relation - * @method ChildCategoryQuery innerJoinAttributeCategory($relationAlias = null) Adds a INNER JOIN clause to the query using the AttributeCategory relation - * * @method ChildCategoryQuery leftJoinCategoryImage($relationAlias = null) Adds a LEFT JOIN clause to the query using the CategoryImage relation * @method ChildCategoryQuery rightJoinCategoryImage($relationAlias = null) Adds a RIGHT JOIN clause to the query using the CategoryImage relation * @method ChildCategoryQuery innerJoinCategoryImage($relationAlias = null) Adds a INNER JOIN clause to the query using the CategoryImage relation @@ -720,152 +712,6 @@ abstract class CategoryQuery extends ModelCriteria ->useQuery($relationAlias ? $relationAlias : 'ProductCategory', '\Thelia\Model\ProductCategoryQuery'); } - /** - * Filter the query by a related \Thelia\Model\FeatureCategory object - * - * @param \Thelia\Model\FeatureCategory|ObjectCollection $featureCategory the related object to use as filter - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return ChildCategoryQuery The current query, for fluid interface - */ - public function filterByFeatureCategory($featureCategory, $comparison = null) - { - if ($featureCategory instanceof \Thelia\Model\FeatureCategory) { - return $this - ->addUsingAlias(CategoryTableMap::ID, $featureCategory->getCategoryId(), $comparison); - } elseif ($featureCategory instanceof ObjectCollection) { - return $this - ->useFeatureCategoryQuery() - ->filterByPrimaryKeys($featureCategory->getPrimaryKeys()) - ->endUse(); - } else { - throw new PropelException('filterByFeatureCategory() only accepts arguments of type \Thelia\Model\FeatureCategory or Collection'); - } - } - - /** - * Adds a JOIN clause to the query using the FeatureCategory relation - * - * @param string $relationAlias optional alias for the relation - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return ChildCategoryQuery The current query, for fluid interface - */ - public function joinFeatureCategory($relationAlias = null, $joinType = Criteria::INNER_JOIN) - { - $tableMap = $this->getTableMap(); - $relationMap = $tableMap->getRelation('FeatureCategory'); - - // create a ModelJoin object for this join - $join = new ModelJoin(); - $join->setJoinType($joinType); - $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); - if ($previousJoin = $this->getPreviousJoin()) { - $join->setPreviousJoin($previousJoin); - } - - // add the ModelJoin to the current object - if ($relationAlias) { - $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); - $this->addJoinObject($join, $relationAlias); - } else { - $this->addJoinObject($join, 'FeatureCategory'); - } - - return $this; - } - - /** - * Use the FeatureCategory relation FeatureCategory object - * - * @see useQuery() - * - * @param string $relationAlias optional alias for the relation, - * to be used as main alias in the secondary query - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return \Thelia\Model\FeatureCategoryQuery A secondary query class using the current class as primary query - */ - public function useFeatureCategoryQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) - { - return $this - ->joinFeatureCategory($relationAlias, $joinType) - ->useQuery($relationAlias ? $relationAlias : 'FeatureCategory', '\Thelia\Model\FeatureCategoryQuery'); - } - - /** - * Filter the query by a related \Thelia\Model\AttributeCategory object - * - * @param \Thelia\Model\AttributeCategory|ObjectCollection $attributeCategory the related object to use as filter - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return ChildCategoryQuery The current query, for fluid interface - */ - public function filterByAttributeCategory($attributeCategory, $comparison = null) - { - if ($attributeCategory instanceof \Thelia\Model\AttributeCategory) { - return $this - ->addUsingAlias(CategoryTableMap::ID, $attributeCategory->getCategoryId(), $comparison); - } elseif ($attributeCategory instanceof ObjectCollection) { - return $this - ->useAttributeCategoryQuery() - ->filterByPrimaryKeys($attributeCategory->getPrimaryKeys()) - ->endUse(); - } else { - throw new PropelException('filterByAttributeCategory() only accepts arguments of type \Thelia\Model\AttributeCategory or Collection'); - } - } - - /** - * Adds a JOIN clause to the query using the AttributeCategory relation - * - * @param string $relationAlias optional alias for the relation - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return ChildCategoryQuery The current query, for fluid interface - */ - public function joinAttributeCategory($relationAlias = null, $joinType = Criteria::INNER_JOIN) - { - $tableMap = $this->getTableMap(); - $relationMap = $tableMap->getRelation('AttributeCategory'); - - // create a ModelJoin object for this join - $join = new ModelJoin(); - $join->setJoinType($joinType); - $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); - if ($previousJoin = $this->getPreviousJoin()) { - $join->setPreviousJoin($previousJoin); - } - - // add the ModelJoin to the current object - if ($relationAlias) { - $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); - $this->addJoinObject($join, $relationAlias); - } else { - $this->addJoinObject($join, 'AttributeCategory'); - } - - return $this; - } - - /** - * Use the AttributeCategory relation AttributeCategory object - * - * @see useQuery() - * - * @param string $relationAlias optional alias for the relation, - * to be used as main alias in the secondary query - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return \Thelia\Model\AttributeCategoryQuery A secondary query class using the current class as primary query - */ - public function useAttributeCategoryQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) - { - return $this - ->joinAttributeCategory($relationAlias, $joinType) - ->useQuery($relationAlias ? $relationAlias : 'AttributeCategory', '\Thelia\Model\AttributeCategoryQuery'); - } - /** * Filter the query by a related \Thelia\Model\CategoryImage object * @@ -1248,40 +1094,6 @@ abstract class CategoryQuery extends ModelCriteria ->endUse(); } - /** - * Filter the query by a related Feature object - * using the feature_category table as cross reference - * - * @param Feature $feature the related object to use as filter - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return ChildCategoryQuery The current query, for fluid interface - */ - public function filterByFeature($feature, $comparison = Criteria::EQUAL) - { - return $this - ->useFeatureCategoryQuery() - ->filterByFeature($feature, $comparison) - ->endUse(); - } - - /** - * Filter the query by a related Attribute object - * using the attribute_category table as cross reference - * - * @param Attribute $attribute the related object to use as filter - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return ChildCategoryQuery The current query, for fluid interface - */ - public function filterByAttribute($attribute, $comparison = Criteria::EQUAL) - { - return $this - ->useAttributeCategoryQuery() - ->filterByAttribute($attribute, $comparison) - ->endUse(); - } - /** * Exclude object from result * diff --git a/core/lib/Thelia/Model/Base/Customer.php b/core/lib/Thelia/Model/Base/Customer.php index 3d87f3e28..06553ecfe 100644 --- a/core/lib/Thelia/Model/Base/Customer.php +++ b/core/lib/Thelia/Model/Base/Customer.php @@ -135,6 +135,18 @@ abstract class Customer implements ActiveRecordInterface */ protected $discount; + /** + * The value for the remember_me_token field. + * @var string + */ + protected $remember_me_token; + + /** + * The value for the remember_me_serial field. + * @var string + */ + protected $remember_me_serial; + /** * The value for the created_at field. * @var string @@ -582,6 +594,28 @@ abstract class Customer implements ActiveRecordInterface return $this->discount; } + /** + * Get the [remember_me_token] column value. + * + * @return string + */ + public function getRememberMeToken() + { + + return $this->remember_me_token; + } + + /** + * Get the [remember_me_serial] column value. + * + * @return string + */ + public function getRememberMeSerial() + { + + return $this->remember_me_serial; + } + /** * Get the [optionally formatted] temporal [created_at] column value. * @@ -878,6 +912,48 @@ abstract class Customer implements ActiveRecordInterface return $this; } // setDiscount() + /** + * Set the value of [remember_me_token] column. + * + * @param string $v new value + * @return \Thelia\Model\Customer The current object (for fluent API support) + */ + public function setRememberMeToken($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->remember_me_token !== $v) { + $this->remember_me_token = $v; + $this->modifiedColumns[] = CustomerTableMap::REMEMBER_ME_TOKEN; + } + + + return $this; + } // setRememberMeToken() + + /** + * Set the value of [remember_me_serial] column. + * + * @param string $v new value + * @return \Thelia\Model\Customer The current object (for fluent API support) + */ + public function setRememberMeSerial($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->remember_me_serial !== $v) { + $this->remember_me_serial = $v; + $this->modifiedColumns[] = CustomerTableMap::REMEMBER_ME_SERIAL; + } + + + return $this; + } // setRememberMeSerial() + /** * Sets the value of [created_at] column to a normalized version of the date/time value specified. * @@ -993,13 +1069,19 @@ abstract class Customer implements ActiveRecordInterface $col = $row[TableMap::TYPE_NUM == $indexType ? 11 + $startcol : CustomerTableMap::translateFieldName('Discount', TableMap::TYPE_PHPNAME, $indexType)]; $this->discount = (null !== $col) ? (double) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 12 + $startcol : CustomerTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 12 + $startcol : CustomerTableMap::translateFieldName('RememberMeToken', TableMap::TYPE_PHPNAME, $indexType)]; + $this->remember_me_token = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 13 + $startcol : CustomerTableMap::translateFieldName('RememberMeSerial', TableMap::TYPE_PHPNAME, $indexType)]; + $this->remember_me_serial = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 14 + $startcol : CustomerTableMap::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 ? 13 + $startcol : CustomerTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 15 + $startcol : CustomerTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } @@ -1012,7 +1094,7 @@ abstract class Customer implements ActiveRecordInterface $this->ensureConsistency(); } - return $startcol + 14; // 14 = CustomerTableMap::NUM_HYDRATE_COLUMNS. + return $startcol + 16; // 16 = CustomerTableMap::NUM_HYDRATE_COLUMNS. } catch (Exception $e) { throw new PropelException("Error populating \Thelia\Model\Customer object", 0, $e); @@ -1342,6 +1424,12 @@ abstract class Customer implements ActiveRecordInterface if ($this->isColumnModified(CustomerTableMap::DISCOUNT)) { $modifiedColumns[':p' . $index++] = 'DISCOUNT'; } + if ($this->isColumnModified(CustomerTableMap::REMEMBER_ME_TOKEN)) { + $modifiedColumns[':p' . $index++] = 'REMEMBER_ME_TOKEN'; + } + if ($this->isColumnModified(CustomerTableMap::REMEMBER_ME_SERIAL)) { + $modifiedColumns[':p' . $index++] = 'REMEMBER_ME_SERIAL'; + } if ($this->isColumnModified(CustomerTableMap::CREATED_AT)) { $modifiedColumns[':p' . $index++] = 'CREATED_AT'; } @@ -1395,6 +1483,12 @@ abstract class Customer implements ActiveRecordInterface case 'DISCOUNT': $stmt->bindValue($identifier, $this->discount, PDO::PARAM_STR); break; + case 'REMEMBER_ME_TOKEN': + $stmt->bindValue($identifier, $this->remember_me_token, PDO::PARAM_STR); + break; + case 'REMEMBER_ME_SERIAL': + $stmt->bindValue($identifier, $this->remember_me_serial, 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; @@ -1500,9 +1594,15 @@ abstract class Customer implements ActiveRecordInterface return $this->getDiscount(); break; case 12: - return $this->getCreatedAt(); + return $this->getRememberMeToken(); break; case 13: + return $this->getRememberMeSerial(); + break; + case 14: + return $this->getCreatedAt(); + break; + case 15: return $this->getUpdatedAt(); break; default: @@ -1546,8 +1646,10 @@ abstract class Customer implements ActiveRecordInterface $keys[9] => $this->getLang(), $keys[10] => $this->getSponsor(), $keys[11] => $this->getDiscount(), - $keys[12] => $this->getCreatedAt(), - $keys[13] => $this->getUpdatedAt(), + $keys[12] => $this->getRememberMeToken(), + $keys[13] => $this->getRememberMeSerial(), + $keys[14] => $this->getCreatedAt(), + $keys[15] => $this->getUpdatedAt(), ); $virtualColumns = $this->virtualColumns; foreach($virtualColumns as $key => $virtualColumn) @@ -1639,9 +1741,15 @@ abstract class Customer implements ActiveRecordInterface $this->setDiscount($value); break; case 12: - $this->setCreatedAt($value); + $this->setRememberMeToken($value); break; case 13: + $this->setRememberMeSerial($value); + break; + case 14: + $this->setCreatedAt($value); + break; + case 15: $this->setUpdatedAt($value); break; } // switch() @@ -1680,8 +1788,10 @@ abstract class Customer implements ActiveRecordInterface if (array_key_exists($keys[9], $arr)) $this->setLang($arr[$keys[9]]); if (array_key_exists($keys[10], $arr)) $this->setSponsor($arr[$keys[10]]); if (array_key_exists($keys[11], $arr)) $this->setDiscount($arr[$keys[11]]); - if (array_key_exists($keys[12], $arr)) $this->setCreatedAt($arr[$keys[12]]); - if (array_key_exists($keys[13], $arr)) $this->setUpdatedAt($arr[$keys[13]]); + if (array_key_exists($keys[12], $arr)) $this->setRememberMeToken($arr[$keys[12]]); + if (array_key_exists($keys[13], $arr)) $this->setRememberMeSerial($arr[$keys[13]]); + if (array_key_exists($keys[14], $arr)) $this->setCreatedAt($arr[$keys[14]]); + if (array_key_exists($keys[15], $arr)) $this->setUpdatedAt($arr[$keys[15]]); } /** @@ -1705,6 +1815,8 @@ abstract class Customer implements ActiveRecordInterface if ($this->isColumnModified(CustomerTableMap::LANG)) $criteria->add(CustomerTableMap::LANG, $this->lang); if ($this->isColumnModified(CustomerTableMap::SPONSOR)) $criteria->add(CustomerTableMap::SPONSOR, $this->sponsor); if ($this->isColumnModified(CustomerTableMap::DISCOUNT)) $criteria->add(CustomerTableMap::DISCOUNT, $this->discount); + if ($this->isColumnModified(CustomerTableMap::REMEMBER_ME_TOKEN)) $criteria->add(CustomerTableMap::REMEMBER_ME_TOKEN, $this->remember_me_token); + if ($this->isColumnModified(CustomerTableMap::REMEMBER_ME_SERIAL)) $criteria->add(CustomerTableMap::REMEMBER_ME_SERIAL, $this->remember_me_serial); if ($this->isColumnModified(CustomerTableMap::CREATED_AT)) $criteria->add(CustomerTableMap::CREATED_AT, $this->created_at); if ($this->isColumnModified(CustomerTableMap::UPDATED_AT)) $criteria->add(CustomerTableMap::UPDATED_AT, $this->updated_at); @@ -1781,6 +1893,8 @@ abstract class Customer implements ActiveRecordInterface $copyObj->setLang($this->getLang()); $copyObj->setSponsor($this->getSponsor()); $copyObj->setDiscount($this->getDiscount()); + $copyObj->setRememberMeToken($this->getRememberMeToken()); + $copyObj->setRememberMeSerial($this->getRememberMeSerial()); $copyObj->setCreatedAt($this->getCreatedAt()); $copyObj->setUpdatedAt($this->getUpdatedAt()); @@ -2806,6 +2920,8 @@ abstract class Customer implements ActiveRecordInterface $this->lang = null; $this->sponsor = null; $this->discount = null; + $this->remember_me_token = null; + $this->remember_me_serial = null; $this->created_at = null; $this->updated_at = null; $this->alreadyInSave = false; diff --git a/core/lib/Thelia/Model/Base/CustomerQuery.php b/core/lib/Thelia/Model/Base/CustomerQuery.php index f02e76c24..897bb5ee9 100644 --- a/core/lib/Thelia/Model/Base/CustomerQuery.php +++ b/core/lib/Thelia/Model/Base/CustomerQuery.php @@ -33,6 +33,8 @@ use Thelia\Model\Map\CustomerTableMap; * @method ChildCustomerQuery orderByLang($order = Criteria::ASC) Order by the lang column * @method ChildCustomerQuery orderBySponsor($order = Criteria::ASC) Order by the sponsor column * @method ChildCustomerQuery orderByDiscount($order = Criteria::ASC) Order by the discount column + * @method ChildCustomerQuery orderByRememberMeToken($order = Criteria::ASC) Order by the remember_me_token column + * @method ChildCustomerQuery orderByRememberMeSerial($order = Criteria::ASC) Order by the remember_me_serial column * @method ChildCustomerQuery orderByCreatedAt($order = Criteria::ASC) Order by the created_at column * @method ChildCustomerQuery orderByUpdatedAt($order = Criteria::ASC) Order by the updated_at column * @@ -48,6 +50,8 @@ use Thelia\Model\Map\CustomerTableMap; * @method ChildCustomerQuery groupByLang() Group by the lang column * @method ChildCustomerQuery groupBySponsor() Group by the sponsor column * @method ChildCustomerQuery groupByDiscount() Group by the discount column + * @method ChildCustomerQuery groupByRememberMeToken() Group by the remember_me_token column + * @method ChildCustomerQuery groupByRememberMeSerial() Group by the remember_me_serial column * @method ChildCustomerQuery groupByCreatedAt() Group by the created_at column * @method ChildCustomerQuery groupByUpdatedAt() Group by the updated_at column * @@ -86,6 +90,8 @@ use Thelia\Model\Map\CustomerTableMap; * @method ChildCustomer findOneByLang(string $lang) Return the first ChildCustomer filtered by the lang column * @method ChildCustomer findOneBySponsor(string $sponsor) Return the first ChildCustomer filtered by the sponsor column * @method ChildCustomer findOneByDiscount(double $discount) Return the first ChildCustomer filtered by the discount column + * @method ChildCustomer findOneByRememberMeToken(string $remember_me_token) Return the first ChildCustomer filtered by the remember_me_token column + * @method ChildCustomer findOneByRememberMeSerial(string $remember_me_serial) Return the first ChildCustomer filtered by the remember_me_serial column * @method ChildCustomer findOneByCreatedAt(string $created_at) Return the first ChildCustomer filtered by the created_at column * @method ChildCustomer findOneByUpdatedAt(string $updated_at) Return the first ChildCustomer filtered by the updated_at column * @@ -101,6 +107,8 @@ use Thelia\Model\Map\CustomerTableMap; * @method array findByLang(string $lang) Return ChildCustomer objects filtered by the lang column * @method array findBySponsor(string $sponsor) Return ChildCustomer objects filtered by the sponsor column * @method array findByDiscount(double $discount) Return ChildCustomer objects filtered by the discount column + * @method array findByRememberMeToken(string $remember_me_token) Return ChildCustomer objects filtered by the remember_me_token column + * @method array findByRememberMeSerial(string $remember_me_serial) Return ChildCustomer objects filtered by the remember_me_serial column * @method array findByCreatedAt(string $created_at) Return ChildCustomer objects filtered by the created_at column * @method array findByUpdatedAt(string $updated_at) Return ChildCustomer objects filtered by the updated_at column * @@ -191,7 +199,7 @@ abstract class CustomerQuery extends ModelCriteria */ protected function findPkSimple($key, $con) { - $sql = 'SELECT ID, REF, TITLE_ID, FIRSTNAME, LASTNAME, EMAIL, PASSWORD, ALGO, RESELLER, LANG, SPONSOR, DISCOUNT, CREATED_AT, UPDATED_AT FROM customer WHERE ID = :p0'; + $sql = 'SELECT ID, REF, TITLE_ID, FIRSTNAME, LASTNAME, EMAIL, PASSWORD, ALGO, RESELLER, LANG, SPONSOR, DISCOUNT, REMEMBER_ME_TOKEN, REMEMBER_ME_SERIAL, CREATED_AT, UPDATED_AT FROM customer WHERE ID = :p0'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key, PDO::PARAM_INT); @@ -678,6 +686,64 @@ abstract class CustomerQuery extends ModelCriteria return $this->addUsingAlias(CustomerTableMap::DISCOUNT, $discount, $comparison); } + /** + * Filter the query on the remember_me_token column + * + * Example usage: + * + * $query->filterByRememberMeToken('fooValue'); // WHERE remember_me_token = 'fooValue' + * $query->filterByRememberMeToken('%fooValue%'); // WHERE remember_me_token LIKE '%fooValue%' + * + * + * @param string $rememberMeToken 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 ChildCustomerQuery The current query, for fluid interface + */ + public function filterByRememberMeToken($rememberMeToken = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($rememberMeToken)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $rememberMeToken)) { + $rememberMeToken = str_replace('*', '%', $rememberMeToken); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(CustomerTableMap::REMEMBER_ME_TOKEN, $rememberMeToken, $comparison); + } + + /** + * Filter the query on the remember_me_serial column + * + * Example usage: + * + * $query->filterByRememberMeSerial('fooValue'); // WHERE remember_me_serial = 'fooValue' + * $query->filterByRememberMeSerial('%fooValue%'); // WHERE remember_me_serial LIKE '%fooValue%' + * + * + * @param string $rememberMeSerial 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 ChildCustomerQuery The current query, for fluid interface + */ + public function filterByRememberMeSerial($rememberMeSerial = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($rememberMeSerial)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $rememberMeSerial)) { + $rememberMeSerial = str_replace('*', '%', $rememberMeSerial); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(CustomerTableMap::REMEMBER_ME_SERIAL, $rememberMeSerial, $comparison); + } + /** * Filter the query on the created_at column * diff --git a/core/lib/Thelia/Model/Base/Feature.php b/core/lib/Thelia/Model/Base/Feature.php index 2860a4155..c9b6c5ed4 100644 --- a/core/lib/Thelia/Model/Base/Feature.php +++ b/core/lib/Thelia/Model/Base/Feature.php @@ -17,18 +17,18 @@ use Propel\Runtime\Exception\PropelException; use Propel\Runtime\Map\TableMap; use Propel\Runtime\Parser\AbstractParser; use Propel\Runtime\Util\PropelDateTime; -use Thelia\Model\Category as ChildCategory; -use Thelia\Model\CategoryQuery as ChildCategoryQuery; use Thelia\Model\Feature as ChildFeature; use Thelia\Model\FeatureAv as ChildFeatureAv; use Thelia\Model\FeatureAvQuery as ChildFeatureAvQuery; -use Thelia\Model\FeatureCategory as ChildFeatureCategory; -use Thelia\Model\FeatureCategoryQuery as ChildFeatureCategoryQuery; use Thelia\Model\FeatureI18n as ChildFeatureI18n; use Thelia\Model\FeatureI18nQuery as ChildFeatureI18nQuery; use Thelia\Model\FeatureProduct as ChildFeatureProduct; use Thelia\Model\FeatureProductQuery as ChildFeatureProductQuery; use Thelia\Model\FeatureQuery as ChildFeatureQuery; +use Thelia\Model\FeatureTemplate as ChildFeatureTemplate; +use Thelia\Model\FeatureTemplateQuery as ChildFeatureTemplateQuery; +use Thelia\Model\Template as ChildTemplate; +use Thelia\Model\TemplateQuery as ChildTemplateQuery; use Thelia\Model\Map\FeatureTableMap; abstract class Feature implements ActiveRecordInterface @@ -109,10 +109,10 @@ abstract class Feature implements ActiveRecordInterface protected $collFeatureProductsPartial; /** - * @var ObjectCollection|ChildFeatureCategory[] Collection to store aggregation of ChildFeatureCategory objects. + * @var ObjectCollection|ChildFeatureTemplate[] Collection to store aggregation of ChildFeatureTemplate objects. */ - protected $collFeatureCategories; - protected $collFeatureCategoriesPartial; + protected $collFeatureTemplates; + protected $collFeatureTemplatesPartial; /** * @var ObjectCollection|ChildFeatureI18n[] Collection to store aggregation of ChildFeatureI18n objects. @@ -121,9 +121,9 @@ abstract class Feature implements ActiveRecordInterface protected $collFeatureI18nsPartial; /** - * @var ChildCategory[] Collection to store aggregation of ChildCategory objects. + * @var ChildTemplate[] Collection to store aggregation of ChildTemplate objects. */ - protected $collCategories; + protected $collTemplates; /** * Flag to prevent endless save loop, if this object is referenced @@ -151,7 +151,7 @@ abstract class Feature implements ActiveRecordInterface * An array of objects scheduled for deletion. * @var ObjectCollection */ - protected $categoriesScheduledForDeletion = null; + protected $templatesScheduledForDeletion = null; /** * An array of objects scheduled for deletion. @@ -169,7 +169,7 @@ abstract class Feature implements ActiveRecordInterface * An array of objects scheduled for deletion. * @var ObjectCollection */ - protected $featureCategoriesScheduledForDeletion = null; + protected $featureTemplatesScheduledForDeletion = null; /** * An array of objects scheduled for deletion. @@ -756,11 +756,11 @@ abstract class Feature implements ActiveRecordInterface $this->collFeatureProducts = null; - $this->collFeatureCategories = null; + $this->collFeatureTemplates = null; $this->collFeatureI18ns = null; - $this->collCategories = null; + $this->collTemplates = null; } // if (deep) } @@ -894,29 +894,29 @@ abstract class Feature implements ActiveRecordInterface $this->resetModified(); } - if ($this->categoriesScheduledForDeletion !== null) { - if (!$this->categoriesScheduledForDeletion->isEmpty()) { + if ($this->templatesScheduledForDeletion !== null) { + if (!$this->templatesScheduledForDeletion->isEmpty()) { $pks = array(); $pk = $this->getPrimaryKey(); - foreach ($this->categoriesScheduledForDeletion->getPrimaryKeys(false) as $remotePk) { - $pks[] = array($remotePk, $pk); + foreach ($this->templatesScheduledForDeletion->getPrimaryKeys(false) as $remotePk) { + $pks[] = array($pk, $remotePk); } - FeatureCategoryQuery::create() + FeatureTemplateQuery::create() ->filterByPrimaryKeys($pks) ->delete($con); - $this->categoriesScheduledForDeletion = null; + $this->templatesScheduledForDeletion = null; } - foreach ($this->getCategories() as $category) { - if ($category->isModified()) { - $category->save($con); + foreach ($this->getTemplates() as $template) { + if ($template->isModified()) { + $template->save($con); } } - } elseif ($this->collCategories) { - foreach ($this->collCategories as $category) { - if ($category->isModified()) { - $category->save($con); + } elseif ($this->collTemplates) { + foreach ($this->collTemplates as $template) { + if ($template->isModified()) { + $template->save($con); } } } @@ -955,17 +955,17 @@ abstract class Feature implements ActiveRecordInterface } } - if ($this->featureCategoriesScheduledForDeletion !== null) { - if (!$this->featureCategoriesScheduledForDeletion->isEmpty()) { - \Thelia\Model\FeatureCategoryQuery::create() - ->filterByPrimaryKeys($this->featureCategoriesScheduledForDeletion->getPrimaryKeys(false)) + if ($this->featureTemplatesScheduledForDeletion !== null) { + if (!$this->featureTemplatesScheduledForDeletion->isEmpty()) { + \Thelia\Model\FeatureTemplateQuery::create() + ->filterByPrimaryKeys($this->featureTemplatesScheduledForDeletion->getPrimaryKeys(false)) ->delete($con); - $this->featureCategoriesScheduledForDeletion = null; + $this->featureTemplatesScheduledForDeletion = null; } } - if ($this->collFeatureCategories !== null) { - foreach ($this->collFeatureCategories as $referrerFK) { + if ($this->collFeatureTemplates !== null) { + foreach ($this->collFeatureTemplates as $referrerFK) { if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) { $affectedRows += $referrerFK->save($con); } @@ -1181,8 +1181,8 @@ abstract class Feature implements ActiveRecordInterface if (null !== $this->collFeatureProducts) { $result['FeatureProducts'] = $this->collFeatureProducts->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); } - if (null !== $this->collFeatureCategories) { - $result['FeatureCategories'] = $this->collFeatureCategories->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); + if (null !== $this->collFeatureTemplates) { + $result['FeatureTemplates'] = $this->collFeatureTemplates->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); } if (null !== $this->collFeatureI18ns) { $result['FeatureI18ns'] = $this->collFeatureI18ns->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); @@ -1366,9 +1366,9 @@ abstract class Feature implements ActiveRecordInterface } } - foreach ($this->getFeatureCategories() as $relObj) { + foreach ($this->getFeatureTemplates() as $relObj) { if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves - $copyObj->addFeatureCategory($relObj->copy($deepCopy)); + $copyObj->addFeatureTemplate($relObj->copy($deepCopy)); } } @@ -1425,8 +1425,8 @@ abstract class Feature implements ActiveRecordInterface if ('FeatureProduct' == $relationName) { return $this->initFeatureProducts(); } - if ('FeatureCategory' == $relationName) { - return $this->initFeatureCategories(); + if ('FeatureTemplate' == $relationName) { + return $this->initFeatureTemplates(); } if ('FeatureI18n' == $relationName) { return $this->initFeatureI18ns(); @@ -1920,31 +1920,31 @@ abstract class Feature implements ActiveRecordInterface } /** - * Clears out the collFeatureCategories collection + * Clears out the collFeatureTemplates collection * * This does not modify the database; however, it will remove any associated objects, causing * them to be refetched by subsequent calls to accessor method. * * @return void - * @see addFeatureCategories() + * @see addFeatureTemplates() */ - public function clearFeatureCategories() + public function clearFeatureTemplates() { - $this->collFeatureCategories = null; // important to set this to NULL since that means it is uninitialized + $this->collFeatureTemplates = null; // important to set this to NULL since that means it is uninitialized } /** - * Reset is the collFeatureCategories collection loaded partially. + * Reset is the collFeatureTemplates collection loaded partially. */ - public function resetPartialFeatureCategories($v = true) + public function resetPartialFeatureTemplates($v = true) { - $this->collFeatureCategoriesPartial = $v; + $this->collFeatureTemplatesPartial = $v; } /** - * Initializes the collFeatureCategories collection. + * Initializes the collFeatureTemplates collection. * - * By default this just sets the collFeatureCategories collection to an empty array (like clearcollFeatureCategories()); + * By default this just sets the collFeatureTemplates collection to an empty array (like clearcollFeatureTemplates()); * however, you may wish to override this method in your stub class to provide setting appropriate * to your application -- for example, setting the initial array to the values stored in database. * @@ -1953,17 +1953,17 @@ abstract class Feature implements ActiveRecordInterface * * @return void */ - public function initFeatureCategories($overrideExisting = true) + public function initFeatureTemplates($overrideExisting = true) { - if (null !== $this->collFeatureCategories && !$overrideExisting) { + if (null !== $this->collFeatureTemplates && !$overrideExisting) { return; } - $this->collFeatureCategories = new ObjectCollection(); - $this->collFeatureCategories->setModel('\Thelia\Model\FeatureCategory'); + $this->collFeatureTemplates = new ObjectCollection(); + $this->collFeatureTemplates->setModel('\Thelia\Model\FeatureTemplate'); } /** - * Gets an array of ChildFeatureCategory objects which contain a foreign key that references this object. + * Gets an array of ChildFeatureTemplate objects which contain a foreign key that references this object. * * If the $criteria is not null, it is used to always fetch the results from the database. * Otherwise the results are fetched from the database the first time, then cached. @@ -1973,109 +1973,109 @@ abstract class Feature implements ActiveRecordInterface * * @param Criteria $criteria optional Criteria object to narrow the query * @param ConnectionInterface $con optional connection object - * @return Collection|ChildFeatureCategory[] List of ChildFeatureCategory objects + * @return Collection|ChildFeatureTemplate[] List of ChildFeatureTemplate objects * @throws PropelException */ - public function getFeatureCategories($criteria = null, ConnectionInterface $con = null) + public function getFeatureTemplates($criteria = null, ConnectionInterface $con = null) { - $partial = $this->collFeatureCategoriesPartial && !$this->isNew(); - if (null === $this->collFeatureCategories || null !== $criteria || $partial) { - if ($this->isNew() && null === $this->collFeatureCategories) { + $partial = $this->collFeatureTemplatesPartial && !$this->isNew(); + if (null === $this->collFeatureTemplates || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collFeatureTemplates) { // return empty collection - $this->initFeatureCategories(); + $this->initFeatureTemplates(); } else { - $collFeatureCategories = ChildFeatureCategoryQuery::create(null, $criteria) + $collFeatureTemplates = ChildFeatureTemplateQuery::create(null, $criteria) ->filterByFeature($this) ->find($con); if (null !== $criteria) { - if (false !== $this->collFeatureCategoriesPartial && count($collFeatureCategories)) { - $this->initFeatureCategories(false); + if (false !== $this->collFeatureTemplatesPartial && count($collFeatureTemplates)) { + $this->initFeatureTemplates(false); - foreach ($collFeatureCategories as $obj) { - if (false == $this->collFeatureCategories->contains($obj)) { - $this->collFeatureCategories->append($obj); + foreach ($collFeatureTemplates as $obj) { + if (false == $this->collFeatureTemplates->contains($obj)) { + $this->collFeatureTemplates->append($obj); } } - $this->collFeatureCategoriesPartial = true; + $this->collFeatureTemplatesPartial = true; } - $collFeatureCategories->getInternalIterator()->rewind(); + $collFeatureTemplates->getInternalIterator()->rewind(); - return $collFeatureCategories; + return $collFeatureTemplates; } - if ($partial && $this->collFeatureCategories) { - foreach ($this->collFeatureCategories as $obj) { + if ($partial && $this->collFeatureTemplates) { + foreach ($this->collFeatureTemplates as $obj) { if ($obj->isNew()) { - $collFeatureCategories[] = $obj; + $collFeatureTemplates[] = $obj; } } } - $this->collFeatureCategories = $collFeatureCategories; - $this->collFeatureCategoriesPartial = false; + $this->collFeatureTemplates = $collFeatureTemplates; + $this->collFeatureTemplatesPartial = false; } } - return $this->collFeatureCategories; + return $this->collFeatureTemplates; } /** - * Sets a collection of FeatureCategory objects related by a one-to-many relationship + * Sets a collection of FeatureTemplate objects related by a one-to-many relationship * to the current object. * It will also schedule objects for deletion based on a diff between old objects (aka persisted) * and new objects from the given Propel collection. * - * @param Collection $featureCategories A Propel collection. + * @param Collection $featureTemplates A Propel collection. * @param ConnectionInterface $con Optional connection object * @return ChildFeature The current object (for fluent API support) */ - public function setFeatureCategories(Collection $featureCategories, ConnectionInterface $con = null) + public function setFeatureTemplates(Collection $featureTemplates, ConnectionInterface $con = null) { - $featureCategoriesToDelete = $this->getFeatureCategories(new Criteria(), $con)->diff($featureCategories); + $featureTemplatesToDelete = $this->getFeatureTemplates(new Criteria(), $con)->diff($featureTemplates); - $this->featureCategoriesScheduledForDeletion = $featureCategoriesToDelete; + $this->featureTemplatesScheduledForDeletion = $featureTemplatesToDelete; - foreach ($featureCategoriesToDelete as $featureCategoryRemoved) { - $featureCategoryRemoved->setFeature(null); + foreach ($featureTemplatesToDelete as $featureTemplateRemoved) { + $featureTemplateRemoved->setFeature(null); } - $this->collFeatureCategories = null; - foreach ($featureCategories as $featureCategory) { - $this->addFeatureCategory($featureCategory); + $this->collFeatureTemplates = null; + foreach ($featureTemplates as $featureTemplate) { + $this->addFeatureTemplate($featureTemplate); } - $this->collFeatureCategories = $featureCategories; - $this->collFeatureCategoriesPartial = false; + $this->collFeatureTemplates = $featureTemplates; + $this->collFeatureTemplatesPartial = false; return $this; } /** - * Returns the number of related FeatureCategory objects. + * Returns the number of related FeatureTemplate objects. * * @param Criteria $criteria * @param boolean $distinct * @param ConnectionInterface $con - * @return int Count of related FeatureCategory objects. + * @return int Count of related FeatureTemplate objects. * @throws PropelException */ - public function countFeatureCategories(Criteria $criteria = null, $distinct = false, ConnectionInterface $con = null) + public function countFeatureTemplates(Criteria $criteria = null, $distinct = false, ConnectionInterface $con = null) { - $partial = $this->collFeatureCategoriesPartial && !$this->isNew(); - if (null === $this->collFeatureCategories || null !== $criteria || $partial) { - if ($this->isNew() && null === $this->collFeatureCategories) { + $partial = $this->collFeatureTemplatesPartial && !$this->isNew(); + if (null === $this->collFeatureTemplates || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collFeatureTemplates) { return 0; } if ($partial && !$criteria) { - return count($this->getFeatureCategories()); + return count($this->getFeatureTemplates()); } - $query = ChildFeatureCategoryQuery::create(null, $criteria); + $query = ChildFeatureTemplateQuery::create(null, $criteria); if ($distinct) { $query->distinct(); } @@ -2085,53 +2085,53 @@ abstract class Feature implements ActiveRecordInterface ->count($con); } - return count($this->collFeatureCategories); + return count($this->collFeatureTemplates); } /** - * Method called to associate a ChildFeatureCategory object to this object - * through the ChildFeatureCategory foreign key attribute. + * Method called to associate a ChildFeatureTemplate object to this object + * through the ChildFeatureTemplate foreign key attribute. * - * @param ChildFeatureCategory $l ChildFeatureCategory + * @param ChildFeatureTemplate $l ChildFeatureTemplate * @return \Thelia\Model\Feature The current object (for fluent API support) */ - public function addFeatureCategory(ChildFeatureCategory $l) + public function addFeatureTemplate(ChildFeatureTemplate $l) { - if ($this->collFeatureCategories === null) { - $this->initFeatureCategories(); - $this->collFeatureCategoriesPartial = true; + if ($this->collFeatureTemplates === null) { + $this->initFeatureTemplates(); + $this->collFeatureTemplatesPartial = true; } - if (!in_array($l, $this->collFeatureCategories->getArrayCopy(), true)) { // only add it if the **same** object is not already associated - $this->doAddFeatureCategory($l); + if (!in_array($l, $this->collFeatureTemplates->getArrayCopy(), true)) { // only add it if the **same** object is not already associated + $this->doAddFeatureTemplate($l); } return $this; } /** - * @param FeatureCategory $featureCategory The featureCategory object to add. + * @param FeatureTemplate $featureTemplate The featureTemplate object to add. */ - protected function doAddFeatureCategory($featureCategory) + protected function doAddFeatureTemplate($featureTemplate) { - $this->collFeatureCategories[]= $featureCategory; - $featureCategory->setFeature($this); + $this->collFeatureTemplates[]= $featureTemplate; + $featureTemplate->setFeature($this); } /** - * @param FeatureCategory $featureCategory The featureCategory object to remove. + * @param FeatureTemplate $featureTemplate The featureTemplate object to remove. * @return ChildFeature The current object (for fluent API support) */ - public function removeFeatureCategory($featureCategory) + public function removeFeatureTemplate($featureTemplate) { - if ($this->getFeatureCategories()->contains($featureCategory)) { - $this->collFeatureCategories->remove($this->collFeatureCategories->search($featureCategory)); - if (null === $this->featureCategoriesScheduledForDeletion) { - $this->featureCategoriesScheduledForDeletion = clone $this->collFeatureCategories; - $this->featureCategoriesScheduledForDeletion->clear(); + if ($this->getFeatureTemplates()->contains($featureTemplate)) { + $this->collFeatureTemplates->remove($this->collFeatureTemplates->search($featureTemplate)); + if (null === $this->featureTemplatesScheduledForDeletion) { + $this->featureTemplatesScheduledForDeletion = clone $this->collFeatureTemplates; + $this->featureTemplatesScheduledForDeletion->clear(); } - $this->featureCategoriesScheduledForDeletion[]= clone $featureCategory; - $featureCategory->setFeature(null); + $this->featureTemplatesScheduledForDeletion[]= clone $featureTemplate; + $featureTemplate->setFeature(null); } return $this; @@ -2143,7 +2143,7 @@ abstract class Feature implements ActiveRecordInterface * an identical criteria, it returns the collection. * Otherwise if this Feature is new, it will return * an empty collection; or if this Feature has previously - * been saved, it will retrieve related FeatureCategories from storage. + * been saved, it will retrieve related FeatureTemplates from storage. * * This method is protected by default in order to keep the public * api reasonable. You can provide public methods for those you @@ -2152,14 +2152,14 @@ abstract class Feature implements ActiveRecordInterface * @param Criteria $criteria optional Criteria object to narrow the query * @param ConnectionInterface $con optional connection object * @param string $joinBehavior optional join type to use (defaults to Criteria::LEFT_JOIN) - * @return Collection|ChildFeatureCategory[] List of ChildFeatureCategory objects + * @return Collection|ChildFeatureTemplate[] List of ChildFeatureTemplate objects */ - public function getFeatureCategoriesJoinCategory($criteria = null, $con = null, $joinBehavior = Criteria::LEFT_JOIN) + public function getFeatureTemplatesJoinTemplate($criteria = null, $con = null, $joinBehavior = Criteria::LEFT_JOIN) { - $query = ChildFeatureCategoryQuery::create(null, $criteria); - $query->joinWith('Category', $joinBehavior); + $query = ChildFeatureTemplateQuery::create(null, $criteria); + $query->joinWith('Template', $joinBehavior); - return $this->getFeatureCategories($query, $con); + return $this->getFeatureTemplates($query, $con); } /** @@ -2388,38 +2388,38 @@ abstract class Feature implements ActiveRecordInterface } /** - * Clears out the collCategories collection + * Clears out the collTemplates collection * * This does not modify the database; however, it will remove any associated objects, causing * them to be refetched by subsequent calls to accessor method. * * @return void - * @see addCategories() + * @see addTemplates() */ - public function clearCategories() + public function clearTemplates() { - $this->collCategories = null; // important to set this to NULL since that means it is uninitialized - $this->collCategoriesPartial = null; + $this->collTemplates = null; // important to set this to NULL since that means it is uninitialized + $this->collTemplatesPartial = null; } /** - * Initializes the collCategories collection. + * Initializes the collTemplates collection. * - * By default this just sets the collCategories collection to an empty collection (like clearCategories()); + * By default this just sets the collTemplates collection to an empty collection (like clearTemplates()); * however, you may wish to override this method in your stub class to provide setting appropriate * to your application -- for example, setting the initial array to the values stored in database. * * @return void */ - public function initCategories() + public function initTemplates() { - $this->collCategories = new ObjectCollection(); - $this->collCategories->setModel('\Thelia\Model\Category'); + $this->collTemplates = new ObjectCollection(); + $this->collTemplates->setModel('\Thelia\Model\Template'); } /** - * Gets a collection of ChildCategory objects related by a many-to-many relationship - * to the current object by way of the feature_category cross-reference table. + * Gets a collection of ChildTemplate objects related by a many-to-many relationship + * to the current object by way of the feature_template cross-reference table. * * If the $criteria is not null, it is used to always fetch the results from the database. * Otherwise the results are fetched from the database the first time, then cached. @@ -2430,73 +2430,73 @@ abstract class Feature implements ActiveRecordInterface * @param Criteria $criteria Optional query object to filter the query * @param ConnectionInterface $con Optional connection object * - * @return ObjectCollection|ChildCategory[] List of ChildCategory objects + * @return ObjectCollection|ChildTemplate[] List of ChildTemplate objects */ - public function getCategories($criteria = null, ConnectionInterface $con = null) + public function getTemplates($criteria = null, ConnectionInterface $con = null) { - if (null === $this->collCategories || null !== $criteria) { - if ($this->isNew() && null === $this->collCategories) { + if (null === $this->collTemplates || null !== $criteria) { + if ($this->isNew() && null === $this->collTemplates) { // return empty collection - $this->initCategories(); + $this->initTemplates(); } else { - $collCategories = ChildCategoryQuery::create(null, $criteria) + $collTemplates = ChildTemplateQuery::create(null, $criteria) ->filterByFeature($this) ->find($con); if (null !== $criteria) { - return $collCategories; + return $collTemplates; } - $this->collCategories = $collCategories; + $this->collTemplates = $collTemplates; } } - return $this->collCategories; + return $this->collTemplates; } /** - * Sets a collection of Category objects related by a many-to-many relationship - * to the current object by way of the feature_category cross-reference table. + * Sets a collection of Template objects related by a many-to-many relationship + * to the current object by way of the feature_template cross-reference table. * It will also schedule objects for deletion based on a diff between old objects (aka persisted) * and new objects from the given Propel collection. * - * @param Collection $categories A Propel collection. + * @param Collection $templates A Propel collection. * @param ConnectionInterface $con Optional connection object * @return ChildFeature The current object (for fluent API support) */ - public function setCategories(Collection $categories, ConnectionInterface $con = null) + public function setTemplates(Collection $templates, ConnectionInterface $con = null) { - $this->clearCategories(); - $currentCategories = $this->getCategories(); + $this->clearTemplates(); + $currentTemplates = $this->getTemplates(); - $this->categoriesScheduledForDeletion = $currentCategories->diff($categories); + $this->templatesScheduledForDeletion = $currentTemplates->diff($templates); - foreach ($categories as $category) { - if (!$currentCategories->contains($category)) { - $this->doAddCategory($category); + foreach ($templates as $template) { + if (!$currentTemplates->contains($template)) { + $this->doAddTemplate($template); } } - $this->collCategories = $categories; + $this->collTemplates = $templates; return $this; } /** - * Gets the number of ChildCategory objects related by a many-to-many relationship - * to the current object by way of the feature_category cross-reference table. + * Gets the number of ChildTemplate objects related by a many-to-many relationship + * to the current object by way of the feature_template cross-reference table. * * @param Criteria $criteria Optional query object to filter the query * @param boolean $distinct Set to true to force count distinct * @param ConnectionInterface $con Optional connection object * - * @return int the number of related ChildCategory objects + * @return int the number of related ChildTemplate objects */ - public function countCategories($criteria = null, $distinct = false, ConnectionInterface $con = null) + public function countTemplates($criteria = null, $distinct = false, ConnectionInterface $con = null) { - if (null === $this->collCategories || null !== $criteria) { - if ($this->isNew() && null === $this->collCategories) { + if (null === $this->collTemplates || null !== $criteria) { + if ($this->isNew() && null === $this->collTemplates) { return 0; } else { - $query = ChildCategoryQuery::create(null, $criteria); + $query = ChildTemplateQuery::create(null, $criteria); if ($distinct) { $query->distinct(); } @@ -2506,65 +2506,65 @@ abstract class Feature implements ActiveRecordInterface ->count($con); } } else { - return count($this->collCategories); + return count($this->collTemplates); } } /** - * Associate a ChildCategory object to this object - * through the feature_category cross reference table. + * Associate a ChildTemplate object to this object + * through the feature_template cross reference table. * - * @param ChildCategory $category The ChildFeatureCategory object to relate + * @param ChildTemplate $template The ChildFeatureTemplate object to relate * @return ChildFeature The current object (for fluent API support) */ - public function addCategory(ChildCategory $category) + public function addTemplate(ChildTemplate $template) { - if ($this->collCategories === null) { - $this->initCategories(); + if ($this->collTemplates === null) { + $this->initTemplates(); } - if (!$this->collCategories->contains($category)) { // only add it if the **same** object is not already associated - $this->doAddCategory($category); - $this->collCategories[] = $category; + if (!$this->collTemplates->contains($template)) { // only add it if the **same** object is not already associated + $this->doAddTemplate($template); + $this->collTemplates[] = $template; } return $this; } /** - * @param Category $category The category object to add. + * @param Template $template The template object to add. */ - protected function doAddCategory($category) + protected function doAddTemplate($template) { - $featureCategory = new ChildFeatureCategory(); - $featureCategory->setCategory($category); - $this->addFeatureCategory($featureCategory); + $featureTemplate = new ChildFeatureTemplate(); + $featureTemplate->setTemplate($template); + $this->addFeatureTemplate($featureTemplate); // set the back reference to this object directly as using provided method either results // in endless loop or in multiple relations - if (!$category->getFeatures()->contains($this)) { - $foreignCollection = $category->getFeatures(); + if (!$template->getFeatures()->contains($this)) { + $foreignCollection = $template->getFeatures(); $foreignCollection[] = $this; } } /** - * Remove a ChildCategory object to this object - * through the feature_category cross reference table. + * Remove a ChildTemplate object to this object + * through the feature_template cross reference table. * - * @param ChildCategory $category The ChildFeatureCategory object to relate + * @param ChildTemplate $template The ChildFeatureTemplate object to relate * @return ChildFeature The current object (for fluent API support) */ - public function removeCategory(ChildCategory $category) + public function removeTemplate(ChildTemplate $template) { - if ($this->getCategories()->contains($category)) { - $this->collCategories->remove($this->collCategories->search($category)); + if ($this->getTemplates()->contains($template)) { + $this->collTemplates->remove($this->collTemplates->search($template)); - if (null === $this->categoriesScheduledForDeletion) { - $this->categoriesScheduledForDeletion = clone $this->collCategories; - $this->categoriesScheduledForDeletion->clear(); + if (null === $this->templatesScheduledForDeletion) { + $this->templatesScheduledForDeletion = clone $this->collTemplates; + $this->templatesScheduledForDeletion->clear(); } - $this->categoriesScheduledForDeletion[] = $category; + $this->templatesScheduledForDeletion[] = $template; } return $this; @@ -2610,8 +2610,8 @@ abstract class Feature implements ActiveRecordInterface $o->clearAllReferences($deep); } } - if ($this->collFeatureCategories) { - foreach ($this->collFeatureCategories as $o) { + if ($this->collFeatureTemplates) { + foreach ($this->collFeatureTemplates as $o) { $o->clearAllReferences($deep); } } @@ -2620,8 +2620,8 @@ abstract class Feature implements ActiveRecordInterface $o->clearAllReferences($deep); } } - if ($this->collCategories) { - foreach ($this->collCategories as $o) { + if ($this->collTemplates) { + foreach ($this->collTemplates as $o) { $o->clearAllReferences($deep); } } @@ -2639,18 +2639,18 @@ abstract class Feature implements ActiveRecordInterface $this->collFeatureProducts->clearIterator(); } $this->collFeatureProducts = null; - if ($this->collFeatureCategories instanceof Collection) { - $this->collFeatureCategories->clearIterator(); + if ($this->collFeatureTemplates instanceof Collection) { + $this->collFeatureTemplates->clearIterator(); } - $this->collFeatureCategories = null; + $this->collFeatureTemplates = null; if ($this->collFeatureI18ns instanceof Collection) { $this->collFeatureI18ns->clearIterator(); } $this->collFeatureI18ns = null; - if ($this->collCategories instanceof Collection) { - $this->collCategories->clearIterator(); + if ($this->collTemplates instanceof Collection) { + $this->collTemplates->clearIterator(); } - $this->collCategories = null; + $this->collTemplates = null; } /** diff --git a/core/lib/Thelia/Model/Base/FeatureQuery.php b/core/lib/Thelia/Model/Base/FeatureQuery.php index 9b00e812e..097646c87 100644 --- a/core/lib/Thelia/Model/Base/FeatureQuery.php +++ b/core/lib/Thelia/Model/Base/FeatureQuery.php @@ -46,9 +46,9 @@ use Thelia\Model\Map\FeatureTableMap; * @method ChildFeatureQuery rightJoinFeatureProduct($relationAlias = null) Adds a RIGHT JOIN clause to the query using the FeatureProduct relation * @method ChildFeatureQuery innerJoinFeatureProduct($relationAlias = null) Adds a INNER JOIN clause to the query using the FeatureProduct relation * - * @method ChildFeatureQuery leftJoinFeatureCategory($relationAlias = null) Adds a LEFT JOIN clause to the query using the FeatureCategory relation - * @method ChildFeatureQuery rightJoinFeatureCategory($relationAlias = null) Adds a RIGHT JOIN clause to the query using the FeatureCategory relation - * @method ChildFeatureQuery innerJoinFeatureCategory($relationAlias = null) Adds a INNER JOIN clause to the query using the FeatureCategory relation + * @method ChildFeatureQuery leftJoinFeatureTemplate($relationAlias = null) Adds a LEFT JOIN clause to the query using the FeatureTemplate relation + * @method ChildFeatureQuery rightJoinFeatureTemplate($relationAlias = null) Adds a RIGHT JOIN clause to the query using the FeatureTemplate relation + * @method ChildFeatureQuery innerJoinFeatureTemplate($relationAlias = null) Adds a INNER JOIN clause to the query using the FeatureTemplate relation * * @method ChildFeatureQuery leftJoinFeatureI18n($relationAlias = null) Adds a LEFT JOIN clause to the query using the FeatureI18n relation * @method ChildFeatureQuery rightJoinFeatureI18n($relationAlias = null) Adds a RIGHT JOIN clause to the query using the FeatureI18n relation @@ -601,40 +601,40 @@ abstract class FeatureQuery extends ModelCriteria } /** - * Filter the query by a related \Thelia\Model\FeatureCategory object + * Filter the query by a related \Thelia\Model\FeatureTemplate object * - * @param \Thelia\Model\FeatureCategory|ObjectCollection $featureCategory the related object to use as filter + * @param \Thelia\Model\FeatureTemplate|ObjectCollection $featureTemplate the related object to use as filter * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL * * @return ChildFeatureQuery The current query, for fluid interface */ - public function filterByFeatureCategory($featureCategory, $comparison = null) + public function filterByFeatureTemplate($featureTemplate, $comparison = null) { - if ($featureCategory instanceof \Thelia\Model\FeatureCategory) { + if ($featureTemplate instanceof \Thelia\Model\FeatureTemplate) { return $this - ->addUsingAlias(FeatureTableMap::ID, $featureCategory->getFeatureId(), $comparison); - } elseif ($featureCategory instanceof ObjectCollection) { + ->addUsingAlias(FeatureTableMap::ID, $featureTemplate->getFeatureId(), $comparison); + } elseif ($featureTemplate instanceof ObjectCollection) { return $this - ->useFeatureCategoryQuery() - ->filterByPrimaryKeys($featureCategory->getPrimaryKeys()) + ->useFeatureTemplateQuery() + ->filterByPrimaryKeys($featureTemplate->getPrimaryKeys()) ->endUse(); } else { - throw new PropelException('filterByFeatureCategory() only accepts arguments of type \Thelia\Model\FeatureCategory or Collection'); + throw new PropelException('filterByFeatureTemplate() only accepts arguments of type \Thelia\Model\FeatureTemplate or Collection'); } } /** - * Adds a JOIN clause to the query using the FeatureCategory relation + * Adds a JOIN clause to the query using the FeatureTemplate relation * * @param string $relationAlias optional alias for the relation * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' * * @return ChildFeatureQuery The current query, for fluid interface */ - public function joinFeatureCategory($relationAlias = null, $joinType = Criteria::INNER_JOIN) + public function joinFeatureTemplate($relationAlias = null, $joinType = Criteria::INNER_JOIN) { $tableMap = $this->getTableMap(); - $relationMap = $tableMap->getRelation('FeatureCategory'); + $relationMap = $tableMap->getRelation('FeatureTemplate'); // create a ModelJoin object for this join $join = new ModelJoin(); @@ -649,14 +649,14 @@ abstract class FeatureQuery extends ModelCriteria $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); $this->addJoinObject($join, $relationAlias); } else { - $this->addJoinObject($join, 'FeatureCategory'); + $this->addJoinObject($join, 'FeatureTemplate'); } return $this; } /** - * Use the FeatureCategory relation FeatureCategory object + * Use the FeatureTemplate relation FeatureTemplate object * * @see useQuery() * @@ -664,13 +664,13 @@ abstract class FeatureQuery extends ModelCriteria * to be used as main alias in the secondary query * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' * - * @return \Thelia\Model\FeatureCategoryQuery A secondary query class using the current class as primary query + * @return \Thelia\Model\FeatureTemplateQuery A secondary query class using the current class as primary query */ - public function useFeatureCategoryQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) + public function useFeatureTemplateQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) { return $this - ->joinFeatureCategory($relationAlias, $joinType) - ->useQuery($relationAlias ? $relationAlias : 'FeatureCategory', '\Thelia\Model\FeatureCategoryQuery'); + ->joinFeatureTemplate($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'FeatureTemplate', '\Thelia\Model\FeatureTemplateQuery'); } /** @@ -747,19 +747,19 @@ abstract class FeatureQuery extends ModelCriteria } /** - * Filter the query by a related Category object - * using the feature_category table as cross reference + * Filter the query by a related Template object + * using the feature_template table as cross reference * - * @param Category $category the related object to use as filter + * @param Template $template the related object to use as filter * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL * * @return ChildFeatureQuery The current query, for fluid interface */ - public function filterByCategory($category, $comparison = Criteria::EQUAL) + public function filterByTemplate($template, $comparison = Criteria::EQUAL) { return $this - ->useFeatureCategoryQuery() - ->filterByCategory($category, $comparison) + ->useFeatureTemplateQuery() + ->filterByTemplate($template, $comparison) ->endUse(); } diff --git a/core/lib/Thelia/Model/Base/FeatureTemplate.php b/core/lib/Thelia/Model/Base/FeatureTemplate.php new file mode 100644 index 000000000..bbccd9251 --- /dev/null +++ b/core/lib/Thelia/Model/Base/FeatureTemplate.php @@ -0,0 +1,1495 @@ +modifiedColumns); + } + + /** + * Has specified column been modified? + * + * @param string $col column fully qualified name (TableMap::TYPE_COLNAME), e.g. Book::AUTHOR_ID + * @return boolean True if $col has been modified. + */ + public function isColumnModified($col) + { + return in_array($col, $this->modifiedColumns); + } + + /** + * Get the columns that have been modified in this object. + * @return array A unique list of the modified column names for this object. + */ + public function getModifiedColumns() + { + return array_unique($this->modifiedColumns); + } + + /** + * Returns whether the object has ever been saved. This will + * be false, if the object was retrieved from storage or was created + * and then saved. + * + * @return true, if the object has never been persisted. + */ + public function isNew() + { + return $this->new; + } + + /** + * Setter for the isNew attribute. This method will be called + * by Propel-generated children and objects. + * + * @param boolean $b the state of the object. + */ + public function setNew($b) + { + $this->new = (Boolean) $b; + } + + /** + * Whether this object has been deleted. + * @return boolean The deleted state of this object. + */ + public function isDeleted() + { + return $this->deleted; + } + + /** + * Specify whether this object has been deleted. + * @param boolean $b The deleted state of this object. + * @return void + */ + public function setDeleted($b) + { + $this->deleted = (Boolean) $b; + } + + /** + * Sets the modified state for the object to be false. + * @param string $col If supplied, only the specified column is reset. + * @return void + */ + public function resetModified($col = null) + { + if (null !== $col) { + while (false !== ($offset = array_search($col, $this->modifiedColumns))) { + array_splice($this->modifiedColumns, $offset, 1); + } + } else { + $this->modifiedColumns = array(); + } + } + + /** + * Compares this with another FeatureTemplate instance. If + * obj is an instance of FeatureTemplate, delegates to + * equals(FeatureTemplate). Otherwise, returns false. + * + * @param obj The object to compare to. + * @return Whether equal to the object specified. + */ + public function equals($obj) + { + $thisclazz = get_class($this); + if (!is_object($obj) || !($obj instanceof $thisclazz)) { + return false; + } + + if ($this === $obj) { + return true; + } + + if (null === $this->getPrimaryKey() + || null === $obj->getPrimaryKey()) { + return false; + } + + return $this->getPrimaryKey() === $obj->getPrimaryKey(); + } + + /** + * If the primary key is not null, return the hashcode of the + * primary key. Otherwise, return the hash code of the object. + * + * @return int Hashcode + */ + public function hashCode() + { + if (null !== $this->getPrimaryKey()) { + return crc32(serialize($this->getPrimaryKey())); + } + + return crc32(serialize(clone $this)); + } + + /** + * Get the associative array of the virtual columns in this object + * + * @param string $name The virtual column name + * + * @return array + */ + public function getVirtualColumns() + { + return $this->virtualColumns; + } + + /** + * Checks the existence of a virtual column in this object + * + * @return boolean + */ + public function hasVirtualColumn($name) + { + return array_key_exists($name, $this->virtualColumns); + } + + /** + * Get the value of a virtual column in this object + * + * @return mixed + */ + public function getVirtualColumn($name) + { + if (!$this->hasVirtualColumn($name)) { + throw new PropelException(sprintf('Cannot get value of inexistent virtual column %s.', $name)); + } + + return $this->virtualColumns[$name]; + } + + /** + * Set the value of a virtual column in this object + * + * @param string $name The virtual column name + * @param mixed $value The value to give to the virtual column + * + * @return FeatureTemplate The current object, for fluid interface + */ + public function setVirtualColumn($name, $value) + { + $this->virtualColumns[$name] = $value; + + return $this; + } + + /** + * Logs a message using Propel::log(). + * + * @param string $msg + * @param int $priority One of the Propel::LOG_* logging levels + * @return boolean + */ + protected function log($msg, $priority = Propel::LOG_INFO) + { + return Propel::log(get_class($this) . ': ' . $msg, $priority); + } + + /** + * Populate the current object from a string, using a given parser format + * + * $book = new Book(); + * $book->importFrom('JSON', '{"Id":9012,"Title":"Don Juan","ISBN":"0140422161","Price":12.99,"PublisherId":1234,"AuthorId":5678}'); + * + * + * @param mixed $parser A AbstractParser instance, + * or a format name ('XML', 'YAML', 'JSON', 'CSV') + * @param string $data The source data to import from + * + * @return FeatureTemplate The current object, for fluid interface + */ + public function importFrom($parser, $data) + { + if (!$parser instanceof AbstractParser) { + $parser = AbstractParser::getParser($parser); + } + + return $this->fromArray($parser->toArray($data), TableMap::TYPE_PHPNAME); + } + + /** + * Export the current object properties to a string, using a given parser format + * + * $book = BookQuery::create()->findPk(9012); + * echo $book->exportTo('JSON'); + * => {"Id":9012,"Title":"Don Juan","ISBN":"0140422161","Price":12.99,"PublisherId":1234,"AuthorId":5678}'); + * + * + * @param mixed $parser A AbstractParser instance, or a format name ('XML', 'YAML', 'JSON', 'CSV') + * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy load(ed) columns. Defaults to TRUE. + * @return string The exported data + */ + public function exportTo($parser, $includeLazyLoadColumns = true) + { + if (!$parser instanceof AbstractParser) { + $parser = AbstractParser::getParser($parser); + } + + return $parser->fromArray($this->toArray(TableMap::TYPE_PHPNAME, $includeLazyLoadColumns, array(), true)); + } + + /** + * Clean up internal collections prior to serializing + * Avoids recursive loops that turn into segmentation faults when serializing + */ + public function __sleep() + { + $this->clearAllReferences(); + + return array_keys(get_object_vars($this)); + } + + /** + * Get the [id] column value. + * + * @return int + */ + public function getId() + { + + return $this->id; + } + + /** + * Get the [feature_id] column value. + * + * @return int + */ + public function getFeatureId() + { + + return $this->feature_id; + } + + /** + * Get the [template_id] column value. + * + * @return int + */ + public function getTemplateId() + { + + return $this->template_id; + } + + /** + * 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 !== null ? $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 !== null ? $this->updated_at->format($format) : null; + } + } + + /** + * Set the value of [id] column. + * + * @param int $v new value + * @return \Thelia\Model\FeatureTemplate The current object (for fluent API support) + */ + public function setId($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->id !== $v) { + $this->id = $v; + $this->modifiedColumns[] = FeatureTemplateTableMap::ID; + } + + + return $this; + } // setId() + + /** + * Set the value of [feature_id] column. + * + * @param int $v new value + * @return \Thelia\Model\FeatureTemplate The current object (for fluent API support) + */ + public function setFeatureId($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->feature_id !== $v) { + $this->feature_id = $v; + $this->modifiedColumns[] = FeatureTemplateTableMap::FEATURE_ID; + } + + if ($this->aFeature !== null && $this->aFeature->getId() !== $v) { + $this->aFeature = null; + } + + + return $this; + } // setFeatureId() + + /** + * Set the value of [template_id] column. + * + * @param int $v new value + * @return \Thelia\Model\FeatureTemplate The current object (for fluent API support) + */ + public function setTemplateId($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->template_id !== $v) { + $this->template_id = $v; + $this->modifiedColumns[] = FeatureTemplateTableMap::TEMPLATE_ID; + } + + if ($this->aTemplate !== null && $this->aTemplate->getId() !== $v) { + $this->aTemplate = null; + } + + + return $this; + } // setTemplateId() + + /** + * 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\FeatureTemplate 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[] = FeatureTemplateTableMap::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\FeatureTemplate 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[] = FeatureTemplateTableMap::UPDATED_AT; + } + } // if either are not null + + + return $this; + } // setUpdatedAt() + + /** + * Indicates whether the columns in this object are only set to default values. + * + * This method can be used in conjunction with isModified() to indicate whether an object is both + * modified _and_ has some values set which are non-default. + * + * @return boolean Whether the columns in this object are only been set with default values. + */ + public function hasOnlyDefaultValues() + { + // otherwise, everything was equal, so return TRUE + return true; + } // hasOnlyDefaultValues() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (0-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param array $row The row returned by DataFetcher->fetch(). + * @param int $startcol 0-based offset column which indicates which restultset column to start with. + * @param boolean $rehydrate Whether this object is being re-hydrated from the database. + * @param string $indexType The index type of $row. Mostly DataFetcher->getIndexType(). + One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate($row, $startcol = 0, $rehydrate = false, $indexType = TableMap::TYPE_NUM) + { + try { + + + $col = $row[TableMap::TYPE_NUM == $indexType ? 0 + $startcol : FeatureTemplateTableMap::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)]; + $this->id = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 1 + $startcol : FeatureTemplateTableMap::translateFieldName('FeatureId', TableMap::TYPE_PHPNAME, $indexType)]; + $this->feature_id = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : FeatureTemplateTableMap::translateFieldName('TemplateId', TableMap::TYPE_PHPNAME, $indexType)]; + $this->template_id = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : FeatureTemplateTableMap::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 ? 4 + $startcol : FeatureTemplateTableMap::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); + + if ($rehydrate) { + $this->ensureConsistency(); + } + + return $startcol + 5; // 5 = FeatureTemplateTableMap::NUM_HYDRATE_COLUMNS. + + } catch (Exception $e) { + throw new PropelException("Error populating \Thelia\Model\FeatureTemplate object", 0, $e); + } + } + + /** + * Checks and repairs the internal consistency of the object. + * + * This method is executed after an already-instantiated object is re-hydrated + * from the database. It exists to check any foreign keys to make sure that + * the objects related to the current object are correct based on foreign key. + * + * You can override this method in the stub class, but you should always invoke + * the base method from the overridden method (i.e. parent::ensureConsistency()), + * in case your model changes. + * + * @throws PropelException + */ + public function ensureConsistency() + { + if ($this->aFeature !== null && $this->feature_id !== $this->aFeature->getId()) { + $this->aFeature = null; + } + if ($this->aTemplate !== null && $this->template_id !== $this->aTemplate->getId()) { + $this->aTemplate = null; + } + } // ensureConsistency + + /** + * Reloads this object from datastore based on primary key and (optionally) resets all associated objects. + * + * This will only work if the object has been saved and has a valid primary key set. + * + * @param boolean $deep (optional) Whether to also de-associated any related objects. + * @param ConnectionInterface $con (optional) The ConnectionInterface connection to use. + * @return void + * @throws PropelException - if this object is deleted, unsaved or doesn't have pk match in db + */ + public function reload($deep = false, ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("Cannot reload a deleted object."); + } + + if ($this->isNew()) { + throw new PropelException("Cannot reload an unsaved object."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getReadConnection(FeatureTemplateTableMap::DATABASE_NAME); + } + + // We don't need to alter the object instance pool; we're just modifying this instance + // already in the pool. + + $dataFetcher = ChildFeatureTemplateQuery::create(null, $this->buildPkeyCriteria())->setFormatter(ModelCriteria::FORMAT_STATEMENT)->find($con); + $row = $dataFetcher->fetch(); + $dataFetcher->close(); + if (!$row) { + throw new PropelException('Cannot find matching row in the database to reload object values.'); + } + $this->hydrate($row, 0, true, $dataFetcher->getIndexType()); // rehydrate + + if ($deep) { // also de-associate any related objects? + + $this->aFeature = null; + $this->aTemplate = null; + } // if (deep) + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param ConnectionInterface $con + * @return void + * @throws PropelException + * @see FeatureTemplate::setDeleted() + * @see FeatureTemplate::isDeleted() + */ + public function delete(ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getWriteConnection(FeatureTemplateTableMap::DATABASE_NAME); + } + + $con->beginTransaction(); + try { + $deleteQuery = ChildFeatureTemplateQuery::create() + ->filterByPrimaryKey($this->getPrimaryKey()); + $ret = $this->preDelete($con); + if ($ret) { + $deleteQuery->delete($con); + $this->postDelete($con); + $con->commit(); + $this->setDeleted(true); + } else { + $con->commit(); + } + } catch (Exception $e) { + $con->rollBack(); + throw $e; + } + } + + /** + * Persists this object to the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All modified related objects will also be persisted in the doSave() + * method. This method wraps all precipitate database operations in a + * single transaction. + * + * @param ConnectionInterface $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save(ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getWriteConnection(FeatureTemplateTableMap::DATABASE_NAME); + } + + $con->beginTransaction(); + $isInsert = $this->isNew(); + try { + $ret = $this->preSave($con); + if ($isInsert) { + $ret = $ret && $this->preInsert($con); + // timestampable behavior + if (!$this->isColumnModified(FeatureTemplateTableMap::CREATED_AT)) { + $this->setCreatedAt(time()); + } + if (!$this->isColumnModified(FeatureTemplateTableMap::UPDATED_AT)) { + $this->setUpdatedAt(time()); + } + } else { + $ret = $ret && $this->preUpdate($con); + // timestampable behavior + if ($this->isModified() && !$this->isColumnModified(FeatureTemplateTableMap::UPDATED_AT)) { + $this->setUpdatedAt(time()); + } + } + if ($ret) { + $affectedRows = $this->doSave($con); + if ($isInsert) { + $this->postInsert($con); + } else { + $this->postUpdate($con); + } + $this->postSave($con); + FeatureTemplateTableMap::addInstanceToPool($this); + } else { + $affectedRows = 0; + } + $con->commit(); + + return $affectedRows; + } catch (Exception $e) { + $con->rollBack(); + throw $e; + } + } + + /** + * Performs the work of inserting or updating the row in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param ConnectionInterface $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave(ConnectionInterface $con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + // We call the save method on the following object(s) if they + // were passed to this object by their corresponding set + // method. This object relates to these object(s) by a + // foreign key reference. + + if ($this->aFeature !== null) { + if ($this->aFeature->isModified() || $this->aFeature->isNew()) { + $affectedRows += $this->aFeature->save($con); + } + $this->setFeature($this->aFeature); + } + + if ($this->aTemplate !== null) { + if ($this->aTemplate->isModified() || $this->aTemplate->isNew()) { + $affectedRows += $this->aTemplate->save($con); + } + $this->setTemplate($this->aTemplate); + } + + if ($this->isNew() || $this->isModified()) { + // persist changes + if ($this->isNew()) { + $this->doInsert($con); + } else { + $this->doUpdate($con); + } + $affectedRows += 1; + $this->resetModified(); + } + + $this->alreadyInSave = false; + + } + + return $affectedRows; + } // doSave() + + /** + * Insert the row in the database. + * + * @param ConnectionInterface $con + * + * @throws PropelException + * @see doSave() + */ + protected function doInsert(ConnectionInterface $con) + { + $modifiedColumns = array(); + $index = 0; + + $this->modifiedColumns[] = FeatureTemplateTableMap::ID; + if (null !== $this->id) { + throw new PropelException('Cannot insert a value for auto-increment primary key (' . FeatureTemplateTableMap::ID . ')'); + } + + // check the columns in natural order for more readable SQL queries + if ($this->isColumnModified(FeatureTemplateTableMap::ID)) { + $modifiedColumns[':p' . $index++] = 'ID'; + } + if ($this->isColumnModified(FeatureTemplateTableMap::FEATURE_ID)) { + $modifiedColumns[':p' . $index++] = 'FEATURE_ID'; + } + if ($this->isColumnModified(FeatureTemplateTableMap::TEMPLATE_ID)) { + $modifiedColumns[':p' . $index++] = 'TEMPLATE_ID'; + } + if ($this->isColumnModified(FeatureTemplateTableMap::CREATED_AT)) { + $modifiedColumns[':p' . $index++] = 'CREATED_AT'; + } + if ($this->isColumnModified(FeatureTemplateTableMap::UPDATED_AT)) { + $modifiedColumns[':p' . $index++] = 'UPDATED_AT'; + } + + $sql = sprintf( + 'INSERT INTO feature_template (%s) VALUES (%s)', + implode(', ', $modifiedColumns), + implode(', ', array_keys($modifiedColumns)) + ); + + try { + $stmt = $con->prepare($sql); + foreach ($modifiedColumns as $identifier => $columnName) { + switch ($columnName) { + case 'ID': + $stmt->bindValue($identifier, $this->id, PDO::PARAM_INT); + break; + case 'FEATURE_ID': + $stmt->bindValue($identifier, $this->feature_id, PDO::PARAM_INT); + break; + case 'TEMPLATE_ID': + $stmt->bindValue($identifier, $this->template_id, PDO::PARAM_INT); + 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(); + } catch (Exception $e) { + Propel::log($e->getMessage(), Propel::LOG_ERR); + throw new PropelException(sprintf('Unable to execute INSERT statement [%s]', $sql), 0, $e); + } + + try { + $pk = $con->lastInsertId(); + } catch (Exception $e) { + throw new PropelException('Unable to get autoincrement id.', 0, $e); + } + $this->setId($pk); + + $this->setNew(false); + } + + /** + * Update the row in the database. + * + * @param ConnectionInterface $con + * + * @return Integer Number of updated rows + * @see doSave() + */ + protected function doUpdate(ConnectionInterface $con) + { + $selectCriteria = $this->buildPkeyCriteria(); + $valuesCriteria = $this->buildCriteria(); + + return $selectCriteria->doUpdate($valuesCriteria, $con); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @return mixed Value of field. + */ + public function getByName($name, $type = TableMap::TYPE_PHPNAME) + { + $pos = FeatureTemplateTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); + $field = $this->getByPosition($pos); + + return $field; + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch ($pos) { + case 0: + return $this->getId(); + break; + case 1: + return $this->getFeatureId(); + break; + case 2: + return $this->getTemplateId(); + break; + case 3: + return $this->getCreatedAt(); + break; + case 4: + return $this->getUpdatedAt(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType (optional) One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME, + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to TRUE. + * @param array $alreadyDumpedObjects List of objects to skip to avoid recursion + * @param boolean $includeForeignObjects (optional) Whether to include hydrated related objects. Default to FALSE. + * + * @return array an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = TableMap::TYPE_PHPNAME, $includeLazyLoadColumns = true, $alreadyDumpedObjects = array(), $includeForeignObjects = false) + { + if (isset($alreadyDumpedObjects['FeatureTemplate'][$this->getPrimaryKey()])) { + return '*RECURSION*'; + } + $alreadyDumpedObjects['FeatureTemplate'][$this->getPrimaryKey()] = true; + $keys = FeatureTemplateTableMap::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getId(), + $keys[1] => $this->getFeatureId(), + $keys[2] => $this->getTemplateId(), + $keys[3] => $this->getCreatedAt(), + $keys[4] => $this->getUpdatedAt(), + ); + $virtualColumns = $this->virtualColumns; + foreach($virtualColumns as $key => $virtualColumn) + { + $result[$key] = $virtualColumn; + } + + if ($includeForeignObjects) { + if (null !== $this->aFeature) { + $result['Feature'] = $this->aFeature->toArray($keyType, $includeLazyLoadColumns, $alreadyDumpedObjects, true); + } + if (null !== $this->aTemplate) { + $result['Template'] = $this->aTemplate->toArray($keyType, $includeLazyLoadColumns, $alreadyDumpedObjects, true); + } + } + + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @return void + */ + public function setByName($name, $value, $type = TableMap::TYPE_PHPNAME) + { + $pos = FeatureTemplateTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); + + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch ($pos) { + case 0: + $this->setId($value); + break; + case 1: + $this->setFeatureId($value); + break; + case 2: + $this->setTemplateId($value); + break; + case 3: + $this->setCreatedAt($value); + break; + case 4: + $this->setUpdatedAt($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME, + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * The default key type is the column's TableMap::TYPE_PHPNAME. + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = TableMap::TYPE_PHPNAME) + { + $keys = FeatureTemplateTableMap::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setFeatureId($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setTemplateId($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setCreatedAt($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setUpdatedAt($arr[$keys[4]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(FeatureTemplateTableMap::DATABASE_NAME); + + if ($this->isColumnModified(FeatureTemplateTableMap::ID)) $criteria->add(FeatureTemplateTableMap::ID, $this->id); + if ($this->isColumnModified(FeatureTemplateTableMap::FEATURE_ID)) $criteria->add(FeatureTemplateTableMap::FEATURE_ID, $this->feature_id); + if ($this->isColumnModified(FeatureTemplateTableMap::TEMPLATE_ID)) $criteria->add(FeatureTemplateTableMap::TEMPLATE_ID, $this->template_id); + if ($this->isColumnModified(FeatureTemplateTableMap::CREATED_AT)) $criteria->add(FeatureTemplateTableMap::CREATED_AT, $this->created_at); + if ($this->isColumnModified(FeatureTemplateTableMap::UPDATED_AT)) $criteria->add(FeatureTemplateTableMap::UPDATED_AT, $this->updated_at); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(FeatureTemplateTableMap::DATABASE_NAME); + $criteria->add(FeatureTemplateTableMap::ID, $this->id); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return int + */ + public function getPrimaryKey() + { + return $this->getId(); + } + + /** + * Generic method to set the primary key (id column). + * + * @param int $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setId($key); + } + + /** + * Returns true if the primary key for this object is null. + * @return boolean + */ + public function isPrimaryKeyNull() + { + + return null === $this->getId(); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of \Thelia\Model\FeatureTemplate (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @param boolean $makeNew Whether to reset autoincrement PKs and make the object new. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false, $makeNew = true) + { + $copyObj->setFeatureId($this->getFeatureId()); + $copyObj->setTemplateId($this->getTemplateId()); + $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 + } + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return \Thelia\Model\FeatureTemplate Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + + return $copyObj; + } + + /** + * Declares an association between this object and a ChildFeature object. + * + * @param ChildFeature $v + * @return \Thelia\Model\FeatureTemplate The current object (for fluent API support) + * @throws PropelException + */ + public function setFeature(ChildFeature $v = null) + { + if ($v === null) { + $this->setFeatureId(NULL); + } else { + $this->setFeatureId($v->getId()); + } + + $this->aFeature = $v; + + // Add binding for other direction of this n:n relationship. + // If this object has already been added to the ChildFeature object, it will not be re-added. + if ($v !== null) { + $v->addFeatureTemplate($this); + } + + + return $this; + } + + + /** + * Get the associated ChildFeature object + * + * @param ConnectionInterface $con Optional Connection object. + * @return ChildFeature The associated ChildFeature object. + * @throws PropelException + */ + public function getFeature(ConnectionInterface $con = null) + { + if ($this->aFeature === null && ($this->feature_id !== null)) { + $this->aFeature = ChildFeatureQuery::create()->findPk($this->feature_id, $con); + /* The following can be used additionally to + guarantee the related object contains a reference + to this object. This level of coupling may, however, be + undesirable since it could result in an only partially populated collection + in the referenced object. + $this->aFeature->addFeatureTemplates($this); + */ + } + + return $this->aFeature; + } + + /** + * Declares an association between this object and a ChildTemplate object. + * + * @param ChildTemplate $v + * @return \Thelia\Model\FeatureTemplate The current object (for fluent API support) + * @throws PropelException + */ + public function setTemplate(ChildTemplate $v = null) + { + if ($v === null) { + $this->setTemplateId(NULL); + } else { + $this->setTemplateId($v->getId()); + } + + $this->aTemplate = $v; + + // Add binding for other direction of this n:n relationship. + // If this object has already been added to the ChildTemplate object, it will not be re-added. + if ($v !== null) { + $v->addFeatureTemplate($this); + } + + + return $this; + } + + + /** + * Get the associated ChildTemplate object + * + * @param ConnectionInterface $con Optional Connection object. + * @return ChildTemplate The associated ChildTemplate object. + * @throws PropelException + */ + public function getTemplate(ConnectionInterface $con = null) + { + if ($this->aTemplate === null && ($this->template_id !== null)) { + $this->aTemplate = ChildTemplateQuery::create()->findPk($this->template_id, $con); + /* The following can be used additionally to + guarantee the related object contains a reference + to this object. This level of coupling may, however, be + undesirable since it could result in an only partially populated collection + in the referenced object. + $this->aTemplate->addFeatureTemplates($this); + */ + } + + return $this->aTemplate; + } + + /** + * Clears the current object and sets all attributes to their default values + */ + public function clear() + { + $this->id = null; + $this->feature_id = null; + $this->template_id = null; + $this->created_at = null; + $this->updated_at = null; + $this->alreadyInSave = false; + $this->clearAllReferences(); + $this->resetModified(); + $this->setNew(true); + $this->setDeleted(false); + } + + /** + * Resets all references to other model objects or collections of model objects. + * + * This method is a user-space workaround for PHP's inability to garbage collect + * objects with circular references (even in PHP 5.3). This is currently necessary + * when using Propel in certain daemon or large-volume/high-memory operations. + * + * @param boolean $deep Whether to also clear the references on all referrer objects. + */ + public function clearAllReferences($deep = false) + { + if ($deep) { + } // if ($deep) + + $this->aFeature = null; + $this->aTemplate = null; + } + + /** + * Return the string representation of this object + * + * @return string + */ + public function __toString() + { + return (string) $this->exportTo(FeatureTemplateTableMap::DEFAULT_STRING_FORMAT); + } + + // timestampable behavior + + /** + * Mark the current object so that the update date doesn't get updated during next save + * + * @return ChildFeatureTemplate The current object (for fluent API support) + */ + public function keepUpdateDateUnchanged() + { + $this->modifiedColumns[] = FeatureTemplateTableMap::UPDATED_AT; + + return $this; + } + + /** + * Code to be run before persisting the object + * @param ConnectionInterface $con + * @return boolean + */ + public function preSave(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after persisting the object + * @param ConnectionInterface $con + */ + public function postSave(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before inserting to database + * @param ConnectionInterface $con + * @return boolean + */ + public function preInsert(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after inserting to database + * @param ConnectionInterface $con + */ + public function postInsert(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before updating the object in database + * @param ConnectionInterface $con + * @return boolean + */ + public function preUpdate(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after updating the object in database + * @param ConnectionInterface $con + */ + public function postUpdate(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before deleting the object in database + * @param ConnectionInterface $con + * @return boolean + */ + public function preDelete(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after deleting the object in database + * @param ConnectionInterface $con + */ + public function postDelete(ConnectionInterface $con = null) + { + + } + + + /** + * Derived method to catches calls to undefined methods. + * + * Provides magic import/export method support (fromXML()/toXML(), fromYAML()/toYAML(), etc.). + * Allows to define default __call() behavior if you overwrite __call() + * + * @param string $name + * @param mixed $params + * + * @return array|string + */ + public function __call($name, $params) + { + if (0 === strpos($name, 'get')) { + $virtualColumn = substr($name, 3); + if ($this->hasVirtualColumn($virtualColumn)) { + return $this->getVirtualColumn($virtualColumn); + } + + $virtualColumn = lcfirst($virtualColumn); + if ($this->hasVirtualColumn($virtualColumn)) { + return $this->getVirtualColumn($virtualColumn); + } + } + + if (0 === strpos($name, 'from')) { + $format = substr($name, 4); + + return $this->importFrom($format, reset($params)); + } + + if (0 === strpos($name, 'to')) { + $format = substr($name, 2); + $includeLazyLoadColumns = isset($params[0]) ? $params[0] : true; + + return $this->exportTo($format, $includeLazyLoadColumns); + } + + throw new BadMethodCallException(sprintf('Call to undefined method: %s.', $name)); + } + +} diff --git a/core/lib/Thelia/Model/Base/FeatureTemplateQuery.php b/core/lib/Thelia/Model/Base/FeatureTemplateQuery.php new file mode 100644 index 000000000..c99c1305f --- /dev/null +++ b/core/lib/Thelia/Model/Base/FeatureTemplateQuery.php @@ -0,0 +1,759 @@ +setModelAlias($modelAlias); + } + if ($criteria instanceof Criteria) { + $query->mergeWith($criteria); + } + + return $query; + } + + /** + * Find object by primary key. + * Propel uses the instance pool to skip the database if the object exists. + * Go fast if the query is untouched. + * + * + * $obj = $c->findPk(12, $con); + * + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con an optional connection object + * + * @return ChildFeatureTemplate|array|mixed the result, formatted by the current formatter + */ + public function findPk($key, $con = null) + { + if ($key === null) { + return null; + } + if ((null !== ($obj = FeatureTemplateTableMap::getInstanceFromPool((string) $key))) && !$this->formatter) { + // the object is already in the instance pool + return $obj; + } + if ($con === null) { + $con = Propel::getServiceContainer()->getReadConnection(FeatureTemplateTableMap::DATABASE_NAME); + } + $this->basePreSelect($con); + if ($this->formatter || $this->modelAlias || $this->with || $this->select + || $this->selectColumns || $this->asColumns || $this->selectModifiers + || $this->map || $this->having || $this->joins) { + return $this->findPkComplex($key, $con); + } else { + return $this->findPkSimple($key, $con); + } + } + + /** + * Find object by primary key using raw SQL to go fast. + * Bypass doSelect() and the object formatter by using generated code. + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con A connection object + * + * @return ChildFeatureTemplate A model object, or null if the key is not found + */ + protected function findPkSimple($key, $con) + { + $sql = 'SELECT ID, FEATURE_ID, TEMPLATE_ID, CREATED_AT, UPDATED_AT FROM feature_template WHERE ID = :p0'; + try { + $stmt = $con->prepare($sql); + $stmt->bindValue(':p0', $key, PDO::PARAM_INT); + $stmt->execute(); + } catch (Exception $e) { + Propel::log($e->getMessage(), Propel::LOG_ERR); + throw new PropelException(sprintf('Unable to execute SELECT statement [%s]', $sql), 0, $e); + } + $obj = null; + if ($row = $stmt->fetch(\PDO::FETCH_NUM)) { + $obj = new ChildFeatureTemplate(); + $obj->hydrate($row); + FeatureTemplateTableMap::addInstanceToPool($obj, (string) $key); + } + $stmt->closeCursor(); + + return $obj; + } + + /** + * Find object by primary key. + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con A connection object + * + * @return ChildFeatureTemplate|array|mixed the result, formatted by the current formatter + */ + protected function findPkComplex($key, $con) + { + // As the query uses a PK condition, no limit(1) is necessary. + $criteria = $this->isKeepQuery() ? clone $this : $this; + $dataFetcher = $criteria + ->filterByPrimaryKey($key) + ->doSelect($con); + + return $criteria->getFormatter()->init($criteria)->formatOne($dataFetcher); + } + + /** + * Find objects by primary key + * + * $objs = $c->findPks(array(12, 56, 832), $con); + * + * @param array $keys Primary keys to use for the query + * @param ConnectionInterface $con an optional connection object + * + * @return ObjectCollection|array|mixed the list of results, formatted by the current formatter + */ + public function findPks($keys, $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getReadConnection($this->getDbName()); + } + $this->basePreSelect($con); + $criteria = $this->isKeepQuery() ? clone $this : $this; + $dataFetcher = $criteria + ->filterByPrimaryKeys($keys) + ->doSelect($con); + + return $criteria->getFormatter()->init($criteria)->format($dataFetcher); + } + + /** + * Filter the query by primary key + * + * @param mixed $key Primary key to use for the query + * + * @return ChildFeatureTemplateQuery The current query, for fluid interface + */ + public function filterByPrimaryKey($key) + { + + return $this->addUsingAlias(FeatureTemplateTableMap::ID, $key, Criteria::EQUAL); + } + + /** + * Filter the query by a list of primary keys + * + * @param array $keys The list of primary key to use for the query + * + * @return ChildFeatureTemplateQuery The current query, for fluid interface + */ + public function filterByPrimaryKeys($keys) + { + + return $this->addUsingAlias(FeatureTemplateTableMap::ID, $keys, Criteria::IN); + } + + /** + * Filter the query on the id column + * + * Example usage: + * + * $query->filterById(1234); // WHERE id = 1234 + * $query->filterById(array(12, 34)); // WHERE id IN (12, 34) + * $query->filterById(array('min' => 12)); // WHERE id > 12 + * + * + * @param mixed $id The value to use as filter. + * 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 ChildFeatureTemplateQuery The current query, for fluid interface + */ + public function filterById($id = null, $comparison = null) + { + if (is_array($id)) { + $useMinMax = false; + if (isset($id['min'])) { + $this->addUsingAlias(FeatureTemplateTableMap::ID, $id['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($id['max'])) { + $this->addUsingAlias(FeatureTemplateTableMap::ID, $id['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(FeatureTemplateTableMap::ID, $id, $comparison); + } + + /** + * Filter the query on the feature_id column + * + * Example usage: + * + * $query->filterByFeatureId(1234); // WHERE feature_id = 1234 + * $query->filterByFeatureId(array(12, 34)); // WHERE feature_id IN (12, 34) + * $query->filterByFeatureId(array('min' => 12)); // WHERE feature_id > 12 + * + * + * @see filterByFeature() + * + * @param mixed $featureId The value to use as filter. + * 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 ChildFeatureTemplateQuery The current query, for fluid interface + */ + public function filterByFeatureId($featureId = null, $comparison = null) + { + if (is_array($featureId)) { + $useMinMax = false; + if (isset($featureId['min'])) { + $this->addUsingAlias(FeatureTemplateTableMap::FEATURE_ID, $featureId['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($featureId['max'])) { + $this->addUsingAlias(FeatureTemplateTableMap::FEATURE_ID, $featureId['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(FeatureTemplateTableMap::FEATURE_ID, $featureId, $comparison); + } + + /** + * Filter the query on the template_id column + * + * Example usage: + * + * $query->filterByTemplateId(1234); // WHERE template_id = 1234 + * $query->filterByTemplateId(array(12, 34)); // WHERE template_id IN (12, 34) + * $query->filterByTemplateId(array('min' => 12)); // WHERE template_id > 12 + * + * + * @see filterByTemplate() + * + * @param mixed $templateId The value to use as filter. + * 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 ChildFeatureTemplateQuery The current query, for fluid interface + */ + public function filterByTemplateId($templateId = null, $comparison = null) + { + if (is_array($templateId)) { + $useMinMax = false; + if (isset($templateId['min'])) { + $this->addUsingAlias(FeatureTemplateTableMap::TEMPLATE_ID, $templateId['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($templateId['max'])) { + $this->addUsingAlias(FeatureTemplateTableMap::TEMPLATE_ID, $templateId['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(FeatureTemplateTableMap::TEMPLATE_ID, $templateId, $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 ChildFeatureTemplateQuery 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(FeatureTemplateTableMap::CREATED_AT, $createdAt['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($createdAt['max'])) { + $this->addUsingAlias(FeatureTemplateTableMap::CREATED_AT, $createdAt['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(FeatureTemplateTableMap::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 ChildFeatureTemplateQuery 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(FeatureTemplateTableMap::UPDATED_AT, $updatedAt['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($updatedAt['max'])) { + $this->addUsingAlias(FeatureTemplateTableMap::UPDATED_AT, $updatedAt['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(FeatureTemplateTableMap::UPDATED_AT, $updatedAt, $comparison); + } + + /** + * Filter the query by a related \Thelia\Model\Feature object + * + * @param \Thelia\Model\Feature|ObjectCollection $feature The related object(s) to use as filter + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildFeatureTemplateQuery The current query, for fluid interface + */ + public function filterByFeature($feature, $comparison = null) + { + if ($feature instanceof \Thelia\Model\Feature) { + return $this + ->addUsingAlias(FeatureTemplateTableMap::FEATURE_ID, $feature->getId(), $comparison); + } elseif ($feature instanceof ObjectCollection) { + if (null === $comparison) { + $comparison = Criteria::IN; + } + + return $this + ->addUsingAlias(FeatureTemplateTableMap::FEATURE_ID, $feature->toKeyValue('PrimaryKey', 'Id'), $comparison); + } else { + throw new PropelException('filterByFeature() only accepts arguments of type \Thelia\Model\Feature or Collection'); + } + } + + /** + * Adds a JOIN clause to the query using the Feature relation + * + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return ChildFeatureTemplateQuery The current query, for fluid interface + */ + public function joinFeature($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + $tableMap = $this->getTableMap(); + $relationMap = $tableMap->getRelation('Feature'); + + // create a ModelJoin object for this join + $join = new ModelJoin(); + $join->setJoinType($joinType); + $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); + if ($previousJoin = $this->getPreviousJoin()) { + $join->setPreviousJoin($previousJoin); + } + + // add the ModelJoin to the current object + if ($relationAlias) { + $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); + $this->addJoinObject($join, $relationAlias); + } else { + $this->addJoinObject($join, 'Feature'); + } + + return $this; + } + + /** + * Use the Feature relation Feature object + * + * @see useQuery() + * + * @param string $relationAlias optional alias for the relation, + * to be used as main alias in the secondary query + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return \Thelia\Model\FeatureQuery A secondary query class using the current class as primary query + */ + public function useFeatureQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + return $this + ->joinFeature($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'Feature', '\Thelia\Model\FeatureQuery'); + } + + /** + * Filter the query by a related \Thelia\Model\Template object + * + * @param \Thelia\Model\Template|ObjectCollection $template The related object(s) to use as filter + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildFeatureTemplateQuery The current query, for fluid interface + */ + public function filterByTemplate($template, $comparison = null) + { + if ($template instanceof \Thelia\Model\Template) { + return $this + ->addUsingAlias(FeatureTemplateTableMap::TEMPLATE_ID, $template->getId(), $comparison); + } elseif ($template instanceof ObjectCollection) { + if (null === $comparison) { + $comparison = Criteria::IN; + } + + return $this + ->addUsingAlias(FeatureTemplateTableMap::TEMPLATE_ID, $template->toKeyValue('PrimaryKey', 'Id'), $comparison); + } else { + throw new PropelException('filterByTemplate() only accepts arguments of type \Thelia\Model\Template or Collection'); + } + } + + /** + * Adds a JOIN clause to the query using the Template relation + * + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return ChildFeatureTemplateQuery The current query, for fluid interface + */ + public function joinTemplate($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + $tableMap = $this->getTableMap(); + $relationMap = $tableMap->getRelation('Template'); + + // create a ModelJoin object for this join + $join = new ModelJoin(); + $join->setJoinType($joinType); + $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); + if ($previousJoin = $this->getPreviousJoin()) { + $join->setPreviousJoin($previousJoin); + } + + // add the ModelJoin to the current object + if ($relationAlias) { + $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); + $this->addJoinObject($join, $relationAlias); + } else { + $this->addJoinObject($join, 'Template'); + } + + return $this; + } + + /** + * Use the Template relation Template object + * + * @see useQuery() + * + * @param string $relationAlias optional alias for the relation, + * to be used as main alias in the secondary query + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return \Thelia\Model\TemplateQuery A secondary query class using the current class as primary query + */ + public function useTemplateQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + return $this + ->joinTemplate($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'Template', '\Thelia\Model\TemplateQuery'); + } + + /** + * Exclude object from result + * + * @param ChildFeatureTemplate $featureTemplate Object to remove from the list of results + * + * @return ChildFeatureTemplateQuery The current query, for fluid interface + */ + public function prune($featureTemplate = null) + { + if ($featureTemplate) { + $this->addUsingAlias(FeatureTemplateTableMap::ID, $featureTemplate->getId(), Criteria::NOT_EQUAL); + } + + return $this; + } + + /** + * Deletes all rows from the feature_template table. + * + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). + */ + public function doDeleteAll(ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(FeatureTemplateTableMap::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->beginTransaction(); + $affectedRows += parent::doDeleteAll($con); + // Because this db requires some delete cascade/set null emulation, we have to + // clear the cached instance *after* the emulation has happened (since + // instances get re-added by the select statement contained therein). + FeatureTemplateTableMap::clearInstancePool(); + FeatureTemplateTableMap::clearRelatedInstancePool(); + + $con->commit(); + } catch (PropelException $e) { + $con->rollBack(); + throw $e; + } + + return $affectedRows; + } + + /** + * Performs a DELETE on the database, given a ChildFeatureTemplate or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or ChildFeatureTemplate object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public function delete(ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(FeatureTemplateTableMap::DATABASE_NAME); + } + + $criteria = $this; + + // Set the correct dbName + $criteria->setDbName(FeatureTemplateTableMap::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->beginTransaction(); + + + FeatureTemplateTableMap::removeInstanceFromPool($criteria); + + $affectedRows += ModelCriteria::delete($con); + FeatureTemplateTableMap::clearRelatedInstancePool(); + $con->commit(); + + return $affectedRows; + } catch (PropelException $e) { + $con->rollBack(); + throw $e; + } + } + + // timestampable behavior + + /** + * Filter by the latest updated + * + * @param int $nbDays Maximum age of the latest update in days + * + * @return ChildFeatureTemplateQuery The current query, for fluid interface + */ + public function recentlyUpdated($nbDays = 7) + { + return $this->addUsingAlias(FeatureTemplateTableMap::UPDATED_AT, time() - $nbDays * 24 * 60 * 60, Criteria::GREATER_EQUAL); + } + + /** + * Filter by the latest created + * + * @param int $nbDays Maximum age of in days + * + * @return ChildFeatureTemplateQuery The current query, for fluid interface + */ + public function recentlyCreated($nbDays = 7) + { + return $this->addUsingAlias(FeatureTemplateTableMap::CREATED_AT, time() - $nbDays * 24 * 60 * 60, Criteria::GREATER_EQUAL); + } + + /** + * Order by update date desc + * + * @return ChildFeatureTemplateQuery The current query, for fluid interface + */ + public function lastUpdatedFirst() + { + return $this->addDescendingOrderByColumn(FeatureTemplateTableMap::UPDATED_AT); + } + + /** + * Order by update date asc + * + * @return ChildFeatureTemplateQuery The current query, for fluid interface + */ + public function firstUpdatedFirst() + { + return $this->addAscendingOrderByColumn(FeatureTemplateTableMap::UPDATED_AT); + } + + /** + * Order by create date desc + * + * @return ChildFeatureTemplateQuery The current query, for fluid interface + */ + public function lastCreatedFirst() + { + return $this->addDescendingOrderByColumn(FeatureTemplateTableMap::CREATED_AT); + } + + /** + * Order by create date asc + * + * @return ChildFeatureTemplateQuery The current query, for fluid interface + */ + public function firstCreatedFirst() + { + return $this->addAscendingOrderByColumn(FeatureTemplateTableMap::CREATED_AT); + } + +} // FeatureTemplateQuery diff --git a/core/lib/Thelia/Model/Base/Product.php b/core/lib/Thelia/Model/Base/Product.php index f7457d47b..9ec203fec 100644 --- a/core/lib/Thelia/Model/Base/Product.php +++ b/core/lib/Thelia/Model/Base/Product.php @@ -43,6 +43,8 @@ use Thelia\Model\ProductVersion as ChildProductVersion; use Thelia\Model\ProductVersionQuery as ChildProductVersionQuery; use Thelia\Model\TaxRule as ChildTaxRule; use Thelia\Model\TaxRuleQuery as ChildTaxRuleQuery; +use Thelia\Model\Template as ChildTemplate; +use Thelia\Model\TemplateQuery as ChildTemplateQuery; use Thelia\Model\Map\ProductTableMap; use Thelia\Model\Map\ProductVersionTableMap; @@ -111,6 +113,12 @@ abstract class Product implements ActiveRecordInterface */ protected $position; + /** + * The value for the template_id field. + * @var int + */ + protected $template_id; + /** * The value for the created_at field. * @var string @@ -147,6 +155,11 @@ abstract class Product implements ActiveRecordInterface */ protected $aTaxRule; + /** + * @var Template + */ + protected $aTemplate; + /** * @var ObjectCollection|ChildProductCategory[] Collection to store aggregation of ChildProductCategory objects. */ @@ -665,6 +678,17 @@ abstract class Product implements ActiveRecordInterface return $this->position; } + /** + * Get the [template_id] column value. + * + * @return int + */ + public function getTemplateId() + { + + return $this->template_id; + } + /** * Get the [optionally formatted] temporal [created_at] column value. * @@ -856,6 +880,31 @@ abstract class Product implements ActiveRecordInterface return $this; } // setPosition() + /** + * Set the value of [template_id] column. + * + * @param int $v new value + * @return \Thelia\Model\Product The current object (for fluent API support) + */ + public function setTemplateId($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->template_id !== $v) { + $this->template_id = $v; + $this->modifiedColumns[] = ProductTableMap::TEMPLATE_ID; + } + + if ($this->aTemplate !== null && $this->aTemplate->getId() !== $v) { + $this->aTemplate = null; + } + + + return $this; + } // setTemplateId() + /** * Sets the value of [created_at] column to a normalized version of the date/time value specified. * @@ -1021,28 +1070,31 @@ abstract class Product implements ActiveRecordInterface $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : ProductTableMap::translateFieldName('Position', TableMap::TYPE_PHPNAME, $indexType)]; $this->position = (null !== $col) ? (int) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : ProductTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : ProductTableMap::translateFieldName('TemplateId', TableMap::TYPE_PHPNAME, $indexType)]; + $this->template_id = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : ProductTableMap::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 : ProductTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : ProductTableMap::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; - $col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : ProductTableMap::translateFieldName('Version', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 8 + $startcol : ProductTableMap::translateFieldName('Version', TableMap::TYPE_PHPNAME, $indexType)]; $this->version = (null !== $col) ? (int) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 8 + $startcol : ProductTableMap::translateFieldName('VersionCreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 9 + $startcol : ProductTableMap::translateFieldName('VersionCreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } $this->version_created_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 9 + $startcol : ProductTableMap::translateFieldName('VersionCreatedBy', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 10 + $startcol : ProductTableMap::translateFieldName('VersionCreatedBy', TableMap::TYPE_PHPNAME, $indexType)]; $this->version_created_by = (null !== $col) ? (string) $col : null; $this->resetModified(); @@ -1052,7 +1104,7 @@ abstract class Product implements ActiveRecordInterface $this->ensureConsistency(); } - return $startcol + 10; // 10 = ProductTableMap::NUM_HYDRATE_COLUMNS. + return $startcol + 11; // 11 = ProductTableMap::NUM_HYDRATE_COLUMNS. } catch (Exception $e) { throw new PropelException("Error populating \Thelia\Model\Product object", 0, $e); @@ -1077,6 +1129,9 @@ abstract class Product implements ActiveRecordInterface if ($this->aTaxRule !== null && $this->tax_rule_id !== $this->aTaxRule->getId()) { $this->aTaxRule = null; } + if ($this->aTemplate !== null && $this->template_id !== $this->aTemplate->getId()) { + $this->aTemplate = null; + } } // ensureConsistency /** @@ -1117,6 +1172,7 @@ abstract class Product implements ActiveRecordInterface if ($deep) { // also de-associate any related objects? $this->aTaxRule = null; + $this->aTemplate = null; $this->collProductCategories = null; $this->collFeatureProducts = null; @@ -1288,6 +1344,13 @@ abstract class Product implements ActiveRecordInterface $this->setTaxRule($this->aTaxRule); } + if ($this->aTemplate !== null) { + if ($this->aTemplate->isModified() || $this->aTemplate->isNew()) { + $affectedRows += $this->aTemplate->save($con); + } + $this->setTemplate($this->aTemplate); + } + if ($this->isNew() || $this->isModified()) { // persist changes if ($this->isNew()) { @@ -1608,6 +1671,9 @@ abstract class Product implements ActiveRecordInterface if ($this->isColumnModified(ProductTableMap::POSITION)) { $modifiedColumns[':p' . $index++] = 'POSITION'; } + if ($this->isColumnModified(ProductTableMap::TEMPLATE_ID)) { + $modifiedColumns[':p' . $index++] = 'TEMPLATE_ID'; + } if ($this->isColumnModified(ProductTableMap::CREATED_AT)) { $modifiedColumns[':p' . $index++] = 'CREATED_AT'; } @@ -1649,6 +1715,9 @@ abstract class Product implements ActiveRecordInterface case 'POSITION': $stmt->bindValue($identifier, $this->position, PDO::PARAM_INT); break; + case 'TEMPLATE_ID': + $stmt->bindValue($identifier, $this->template_id, PDO::PARAM_INT); + 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; @@ -1742,18 +1811,21 @@ abstract class Product implements ActiveRecordInterface return $this->getPosition(); break; case 5: - return $this->getCreatedAt(); + return $this->getTemplateId(); break; case 6: - return $this->getUpdatedAt(); + return $this->getCreatedAt(); break; case 7: - return $this->getVersion(); + return $this->getUpdatedAt(); break; case 8: - return $this->getVersionCreatedAt(); + return $this->getVersion(); break; case 9: + return $this->getVersionCreatedAt(); + break; + case 10: return $this->getVersionCreatedBy(); break; default: @@ -1790,11 +1862,12 @@ abstract class Product implements ActiveRecordInterface $keys[2] => $this->getRef(), $keys[3] => $this->getVisible(), $keys[4] => $this->getPosition(), - $keys[5] => $this->getCreatedAt(), - $keys[6] => $this->getUpdatedAt(), - $keys[7] => $this->getVersion(), - $keys[8] => $this->getVersionCreatedAt(), - $keys[9] => $this->getVersionCreatedBy(), + $keys[5] => $this->getTemplateId(), + $keys[6] => $this->getCreatedAt(), + $keys[7] => $this->getUpdatedAt(), + $keys[8] => $this->getVersion(), + $keys[9] => $this->getVersionCreatedAt(), + $keys[10] => $this->getVersionCreatedBy(), ); $virtualColumns = $this->virtualColumns; foreach($virtualColumns as $key => $virtualColumn) @@ -1806,6 +1879,9 @@ abstract class Product implements ActiveRecordInterface if (null !== $this->aTaxRule) { $result['TaxRule'] = $this->aTaxRule->toArray($keyType, $includeLazyLoadColumns, $alreadyDumpedObjects, true); } + if (null !== $this->aTemplate) { + $result['Template'] = $this->aTemplate->toArray($keyType, $includeLazyLoadColumns, $alreadyDumpedObjects, true); + } if (null !== $this->collProductCategories) { $result['ProductCategories'] = $this->collProductCategories->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); } @@ -1889,18 +1965,21 @@ abstract class Product implements ActiveRecordInterface $this->setPosition($value); break; case 5: - $this->setCreatedAt($value); + $this->setTemplateId($value); break; case 6: - $this->setUpdatedAt($value); + $this->setCreatedAt($value); break; case 7: - $this->setVersion($value); + $this->setUpdatedAt($value); break; case 8: - $this->setVersionCreatedAt($value); + $this->setVersion($value); break; case 9: + $this->setVersionCreatedAt($value); + break; + case 10: $this->setVersionCreatedBy($value); break; } // switch() @@ -1932,11 +2011,12 @@ abstract class Product implements ActiveRecordInterface if (array_key_exists($keys[2], $arr)) $this->setRef($arr[$keys[2]]); if (array_key_exists($keys[3], $arr)) $this->setVisible($arr[$keys[3]]); if (array_key_exists($keys[4], $arr)) $this->setPosition($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]]); - if (array_key_exists($keys[7], $arr)) $this->setVersion($arr[$keys[7]]); - if (array_key_exists($keys[8], $arr)) $this->setVersionCreatedAt($arr[$keys[8]]); - if (array_key_exists($keys[9], $arr)) $this->setVersionCreatedBy($arr[$keys[9]]); + if (array_key_exists($keys[5], $arr)) $this->setTemplateId($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setCreatedAt($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setUpdatedAt($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setVersion($arr[$keys[8]]); + if (array_key_exists($keys[9], $arr)) $this->setVersionCreatedAt($arr[$keys[9]]); + if (array_key_exists($keys[10], $arr)) $this->setVersionCreatedBy($arr[$keys[10]]); } /** @@ -1953,6 +2033,7 @@ abstract class Product implements ActiveRecordInterface if ($this->isColumnModified(ProductTableMap::REF)) $criteria->add(ProductTableMap::REF, $this->ref); if ($this->isColumnModified(ProductTableMap::VISIBLE)) $criteria->add(ProductTableMap::VISIBLE, $this->visible); if ($this->isColumnModified(ProductTableMap::POSITION)) $criteria->add(ProductTableMap::POSITION, $this->position); + if ($this->isColumnModified(ProductTableMap::TEMPLATE_ID)) $criteria->add(ProductTableMap::TEMPLATE_ID, $this->template_id); if ($this->isColumnModified(ProductTableMap::CREATED_AT)) $criteria->add(ProductTableMap::CREATED_AT, $this->created_at); if ($this->isColumnModified(ProductTableMap::UPDATED_AT)) $criteria->add(ProductTableMap::UPDATED_AT, $this->updated_at); if ($this->isColumnModified(ProductTableMap::VERSION)) $criteria->add(ProductTableMap::VERSION, $this->version); @@ -2025,6 +2106,7 @@ abstract class Product implements ActiveRecordInterface $copyObj->setRef($this->getRef()); $copyObj->setVisible($this->getVisible()); $copyObj->setPosition($this->getPosition()); + $copyObj->setTemplateId($this->getTemplateId()); $copyObj->setCreatedAt($this->getCreatedAt()); $copyObj->setUpdatedAt($this->getUpdatedAt()); $copyObj->setVersion($this->getVersion()); @@ -2183,6 +2265,57 @@ abstract class Product implements ActiveRecordInterface return $this->aTaxRule; } + /** + * Declares an association between this object and a ChildTemplate object. + * + * @param ChildTemplate $v + * @return \Thelia\Model\Product The current object (for fluent API support) + * @throws PropelException + */ + public function setTemplate(ChildTemplate $v = null) + { + if ($v === null) { + $this->setTemplateId(NULL); + } else { + $this->setTemplateId($v->getId()); + } + + $this->aTemplate = $v; + + // Add binding for other direction of this n:n relationship. + // If this object has already been added to the ChildTemplate object, it will not be re-added. + if ($v !== null) { + $v->addProduct($this); + } + + + return $this; + } + + + /** + * Get the associated ChildTemplate object + * + * @param ConnectionInterface $con Optional Connection object. + * @return ChildTemplate The associated ChildTemplate object. + * @throws PropelException + */ + public function getTemplate(ConnectionInterface $con = null) + { + if ($this->aTemplate === null && ($this->template_id !== null)) { + $this->aTemplate = ChildTemplateQuery::create()->findPk($this->template_id, $con); + /* The following can be used additionally to + guarantee the related object contains a reference + to this object. This level of coupling may, however, be + undesirable since it could result in an only partially populated collection + in the referenced object. + $this->aTemplate->addProducts($this); + */ + } + + return $this->aTemplate; + } + /** * Initializes a collection based on the name of a relation. @@ -5349,6 +5482,7 @@ abstract class Product implements ActiveRecordInterface $this->ref = null; $this->visible = null; $this->position = null; + $this->template_id = null; $this->created_at = null; $this->updated_at = null; $this->version = null; @@ -5507,6 +5641,7 @@ abstract class Product implements ActiveRecordInterface } $this->collProductsRelatedByProductId = null; $this->aTaxRule = null; + $this->aTemplate = null; } /** @@ -5781,6 +5916,7 @@ abstract class Product implements ActiveRecordInterface $version->setRef($this->getRef()); $version->setVisible($this->getVisible()); $version->setPosition($this->getPosition()); + $version->setTemplateId($this->getTemplateId()); $version->setCreatedAt($this->getCreatedAt()); $version->setUpdatedAt($this->getUpdatedAt()); $version->setVersion($this->getVersion()); @@ -5828,6 +5964,7 @@ abstract class Product implements ActiveRecordInterface $this->setRef($version->getRef()); $this->setVisible($version->getVisible()); $this->setPosition($version->getPosition()); + $this->setTemplateId($version->getTemplateId()); $this->setCreatedAt($version->getCreatedAt()); $this->setUpdatedAt($version->getUpdatedAt()); $this->setVersion($version->getVersion()); diff --git a/core/lib/Thelia/Model/Base/ProductQuery.php b/core/lib/Thelia/Model/Base/ProductQuery.php index 75f05dfcf..9b1710f03 100644 --- a/core/lib/Thelia/Model/Base/ProductQuery.php +++ b/core/lib/Thelia/Model/Base/ProductQuery.php @@ -27,6 +27,7 @@ use Thelia\Model\Map\ProductTableMap; * @method ChildProductQuery orderByRef($order = Criteria::ASC) Order by the ref column * @method ChildProductQuery orderByVisible($order = Criteria::ASC) Order by the visible column * @method ChildProductQuery orderByPosition($order = Criteria::ASC) Order by the position column + * @method ChildProductQuery orderByTemplateId($order = Criteria::ASC) Order by the template_id column * @method ChildProductQuery orderByCreatedAt($order = Criteria::ASC) Order by the created_at column * @method ChildProductQuery orderByUpdatedAt($order = Criteria::ASC) Order by the updated_at column * @method ChildProductQuery orderByVersion($order = Criteria::ASC) Order by the version column @@ -38,6 +39,7 @@ use Thelia\Model\Map\ProductTableMap; * @method ChildProductQuery groupByRef() Group by the ref column * @method ChildProductQuery groupByVisible() Group by the visible column * @method ChildProductQuery groupByPosition() Group by the position column + * @method ChildProductQuery groupByTemplateId() Group by the template_id column * @method ChildProductQuery groupByCreatedAt() Group by the created_at column * @method ChildProductQuery groupByUpdatedAt() Group by the updated_at column * @method ChildProductQuery groupByVersion() Group by the version column @@ -52,6 +54,10 @@ use Thelia\Model\Map\ProductTableMap; * @method ChildProductQuery rightJoinTaxRule($relationAlias = null) Adds a RIGHT JOIN clause to the query using the TaxRule relation * @method ChildProductQuery innerJoinTaxRule($relationAlias = null) Adds a INNER JOIN clause to the query using the TaxRule relation * + * @method ChildProductQuery leftJoinTemplate($relationAlias = null) Adds a LEFT JOIN clause to the query using the Template relation + * @method ChildProductQuery rightJoinTemplate($relationAlias = null) Adds a RIGHT JOIN clause to the query using the Template relation + * @method ChildProductQuery innerJoinTemplate($relationAlias = null) Adds a INNER JOIN clause to the query using the Template relation + * * @method ChildProductQuery leftJoinProductCategory($relationAlias = null) Adds a LEFT JOIN clause to the query using the ProductCategory relation * @method ChildProductQuery rightJoinProductCategory($relationAlias = null) Adds a RIGHT JOIN clause to the query using the ProductCategory relation * @method ChildProductQuery innerJoinProductCategory($relationAlias = null) Adds a INNER JOIN clause to the query using the ProductCategory relation @@ -104,6 +110,7 @@ use Thelia\Model\Map\ProductTableMap; * @method ChildProduct findOneByRef(string $ref) Return the first ChildProduct filtered by the ref column * @method ChildProduct findOneByVisible(int $visible) Return the first ChildProduct filtered by the visible column * @method ChildProduct findOneByPosition(int $position) Return the first ChildProduct filtered by the position column + * @method ChildProduct findOneByTemplateId(int $template_id) Return the first ChildProduct filtered by the template_id column * @method ChildProduct findOneByCreatedAt(string $created_at) Return the first ChildProduct filtered by the created_at column * @method ChildProduct findOneByUpdatedAt(string $updated_at) Return the first ChildProduct filtered by the updated_at column * @method ChildProduct findOneByVersion(int $version) Return the first ChildProduct filtered by the version column @@ -115,6 +122,7 @@ use Thelia\Model\Map\ProductTableMap; * @method array findByRef(string $ref) Return ChildProduct objects filtered by the ref column * @method array findByVisible(int $visible) Return ChildProduct objects filtered by the visible column * @method array findByPosition(int $position) Return ChildProduct objects filtered by the position column + * @method array findByTemplateId(int $template_id) Return ChildProduct objects filtered by the template_id column * @method array findByCreatedAt(string $created_at) Return ChildProduct objects filtered by the created_at column * @method array findByUpdatedAt(string $updated_at) Return ChildProduct objects filtered by the updated_at column * @method array findByVersion(int $version) Return ChildProduct objects filtered by the version column @@ -215,7 +223,7 @@ abstract class ProductQuery extends ModelCriteria */ protected function findPkSimple($key, $con) { - $sql = 'SELECT ID, TAX_RULE_ID, REF, VISIBLE, POSITION, CREATED_AT, UPDATED_AT, VERSION, VERSION_CREATED_AT, VERSION_CREATED_BY FROM product WHERE ID = :p0'; + $sql = 'SELECT ID, TAX_RULE_ID, REF, VISIBLE, POSITION, TEMPLATE_ID, CREATED_AT, UPDATED_AT, VERSION, VERSION_CREATED_AT, VERSION_CREATED_BY FROM product WHERE ID = :p0'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key, PDO::PARAM_INT); @@ -499,6 +507,49 @@ abstract class ProductQuery extends ModelCriteria return $this->addUsingAlias(ProductTableMap::POSITION, $position, $comparison); } + /** + * Filter the query on the template_id column + * + * Example usage: + * + * $query->filterByTemplateId(1234); // WHERE template_id = 1234 + * $query->filterByTemplateId(array(12, 34)); // WHERE template_id IN (12, 34) + * $query->filterByTemplateId(array('min' => 12)); // WHERE template_id > 12 + * + * + * @see filterByTemplate() + * + * @param mixed $templateId The value to use as filter. + * 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 ChildProductQuery The current query, for fluid interface + */ + public function filterByTemplateId($templateId = null, $comparison = null) + { + if (is_array($templateId)) { + $useMinMax = false; + if (isset($templateId['min'])) { + $this->addUsingAlias(ProductTableMap::TEMPLATE_ID, $templateId['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($templateId['max'])) { + $this->addUsingAlias(ProductTableMap::TEMPLATE_ID, $templateId['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(ProductTableMap::TEMPLATE_ID, $templateId, $comparison); + } + /** * Filter the query on the created_at column * @@ -773,6 +824,81 @@ abstract class ProductQuery extends ModelCriteria ->useQuery($relationAlias ? $relationAlias : 'TaxRule', '\Thelia\Model\TaxRuleQuery'); } + /** + * Filter the query by a related \Thelia\Model\Template object + * + * @param \Thelia\Model\Template|ObjectCollection $template The related object(s) to use as filter + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildProductQuery The current query, for fluid interface + */ + public function filterByTemplate($template, $comparison = null) + { + if ($template instanceof \Thelia\Model\Template) { + return $this + ->addUsingAlias(ProductTableMap::TEMPLATE_ID, $template->getId(), $comparison); + } elseif ($template instanceof ObjectCollection) { + if (null === $comparison) { + $comparison = Criteria::IN; + } + + return $this + ->addUsingAlias(ProductTableMap::TEMPLATE_ID, $template->toKeyValue('PrimaryKey', 'Id'), $comparison); + } else { + throw new PropelException('filterByTemplate() only accepts arguments of type \Thelia\Model\Template or Collection'); + } + } + + /** + * Adds a JOIN clause to the query using the Template relation + * + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return ChildProductQuery The current query, for fluid interface + */ + public function joinTemplate($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + $tableMap = $this->getTableMap(); + $relationMap = $tableMap->getRelation('Template'); + + // create a ModelJoin object for this join + $join = new ModelJoin(); + $join->setJoinType($joinType); + $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); + if ($previousJoin = $this->getPreviousJoin()) { + $join->setPreviousJoin($previousJoin); + } + + // add the ModelJoin to the current object + if ($relationAlias) { + $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); + $this->addJoinObject($join, $relationAlias); + } else { + $this->addJoinObject($join, 'Template'); + } + + return $this; + } + + /** + * Use the Template relation Template object + * + * @see useQuery() + * + * @param string $relationAlias optional alias for the relation, + * to be used as main alias in the secondary query + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return \Thelia\Model\TemplateQuery A secondary query class using the current class as primary query + */ + public function useTemplateQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + return $this + ->joinTemplate($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'Template', '\Thelia\Model\TemplateQuery'); + } + /** * Filter the query by a related \Thelia\Model\ProductCategory object * diff --git a/core/lib/Thelia/Model/Base/ProductVersion.php b/core/lib/Thelia/Model/Base/ProductVersion.php index 071dfc742..a5d22e498 100644 --- a/core/lib/Thelia/Model/Base/ProductVersion.php +++ b/core/lib/Thelia/Model/Base/ProductVersion.php @@ -86,6 +86,12 @@ abstract class ProductVersion implements ActiveRecordInterface */ protected $position; + /** + * The value for the template_id field. + * @var int + */ + protected $template_id; + /** * The value for the created_at field. * @var string @@ -453,6 +459,17 @@ abstract class ProductVersion implements ActiveRecordInterface return $this->position; } + /** + * Get the [template_id] column value. + * + * @return int + */ + public function getTemplateId() + { + + return $this->template_id; + } + /** * Get the [optionally formatted] temporal [created_at] column value. * @@ -644,6 +661,27 @@ abstract class ProductVersion implements ActiveRecordInterface return $this; } // setPosition() + /** + * Set the value of [template_id] column. + * + * @param int $v new value + * @return \Thelia\Model\ProductVersion The current object (for fluent API support) + */ + public function setTemplateId($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->template_id !== $v) { + $this->template_id = $v; + $this->modifiedColumns[] = ProductVersionTableMap::TEMPLATE_ID; + } + + + return $this; + } // setTemplateId() + /** * Sets the value of [created_at] column to a normalized version of the date/time value specified. * @@ -809,28 +847,31 @@ abstract class ProductVersion implements ActiveRecordInterface $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : ProductVersionTableMap::translateFieldName('Position', TableMap::TYPE_PHPNAME, $indexType)]; $this->position = (null !== $col) ? (int) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : ProductVersionTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : ProductVersionTableMap::translateFieldName('TemplateId', TableMap::TYPE_PHPNAME, $indexType)]; + $this->template_id = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : ProductVersionTableMap::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 : ProductVersionTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : ProductVersionTableMap::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; - $col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : ProductVersionTableMap::translateFieldName('Version', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 8 + $startcol : ProductVersionTableMap::translateFieldName('Version', TableMap::TYPE_PHPNAME, $indexType)]; $this->version = (null !== $col) ? (int) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 8 + $startcol : ProductVersionTableMap::translateFieldName('VersionCreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 9 + $startcol : ProductVersionTableMap::translateFieldName('VersionCreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } $this->version_created_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 9 + $startcol : ProductVersionTableMap::translateFieldName('VersionCreatedBy', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 10 + $startcol : ProductVersionTableMap::translateFieldName('VersionCreatedBy', TableMap::TYPE_PHPNAME, $indexType)]; $this->version_created_by = (null !== $col) ? (string) $col : null; $this->resetModified(); @@ -840,7 +881,7 @@ abstract class ProductVersion implements ActiveRecordInterface $this->ensureConsistency(); } - return $startcol + 10; // 10 = ProductVersionTableMap::NUM_HYDRATE_COLUMNS. + return $startcol + 11; // 11 = ProductVersionTableMap::NUM_HYDRATE_COLUMNS. } catch (Exception $e) { throw new PropelException("Error populating \Thelia\Model\ProductVersion object", 0, $e); @@ -1076,6 +1117,9 @@ abstract class ProductVersion implements ActiveRecordInterface if ($this->isColumnModified(ProductVersionTableMap::POSITION)) { $modifiedColumns[':p' . $index++] = 'POSITION'; } + if ($this->isColumnModified(ProductVersionTableMap::TEMPLATE_ID)) { + $modifiedColumns[':p' . $index++] = 'TEMPLATE_ID'; + } if ($this->isColumnModified(ProductVersionTableMap::CREATED_AT)) { $modifiedColumns[':p' . $index++] = 'CREATED_AT'; } @@ -1117,6 +1161,9 @@ abstract class ProductVersion implements ActiveRecordInterface case 'POSITION': $stmt->bindValue($identifier, $this->position, PDO::PARAM_INT); break; + case 'TEMPLATE_ID': + $stmt->bindValue($identifier, $this->template_id, PDO::PARAM_INT); + 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; @@ -1203,18 +1250,21 @@ abstract class ProductVersion implements ActiveRecordInterface return $this->getPosition(); break; case 5: - return $this->getCreatedAt(); + return $this->getTemplateId(); break; case 6: - return $this->getUpdatedAt(); + return $this->getCreatedAt(); break; case 7: - return $this->getVersion(); + return $this->getUpdatedAt(); break; case 8: - return $this->getVersionCreatedAt(); + return $this->getVersion(); break; case 9: + return $this->getVersionCreatedAt(); + break; + case 10: return $this->getVersionCreatedBy(); break; default: @@ -1251,11 +1301,12 @@ abstract class ProductVersion implements ActiveRecordInterface $keys[2] => $this->getRef(), $keys[3] => $this->getVisible(), $keys[4] => $this->getPosition(), - $keys[5] => $this->getCreatedAt(), - $keys[6] => $this->getUpdatedAt(), - $keys[7] => $this->getVersion(), - $keys[8] => $this->getVersionCreatedAt(), - $keys[9] => $this->getVersionCreatedBy(), + $keys[5] => $this->getTemplateId(), + $keys[6] => $this->getCreatedAt(), + $keys[7] => $this->getUpdatedAt(), + $keys[8] => $this->getVersion(), + $keys[9] => $this->getVersionCreatedAt(), + $keys[10] => $this->getVersionCreatedBy(), ); $virtualColumns = $this->virtualColumns; foreach($virtualColumns as $key => $virtualColumn) @@ -1317,18 +1368,21 @@ abstract class ProductVersion implements ActiveRecordInterface $this->setPosition($value); break; case 5: - $this->setCreatedAt($value); + $this->setTemplateId($value); break; case 6: - $this->setUpdatedAt($value); + $this->setCreatedAt($value); break; case 7: - $this->setVersion($value); + $this->setUpdatedAt($value); break; case 8: - $this->setVersionCreatedAt($value); + $this->setVersion($value); break; case 9: + $this->setVersionCreatedAt($value); + break; + case 10: $this->setVersionCreatedBy($value); break; } // switch() @@ -1360,11 +1414,12 @@ abstract class ProductVersion implements ActiveRecordInterface if (array_key_exists($keys[2], $arr)) $this->setRef($arr[$keys[2]]); if (array_key_exists($keys[3], $arr)) $this->setVisible($arr[$keys[3]]); if (array_key_exists($keys[4], $arr)) $this->setPosition($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]]); - if (array_key_exists($keys[7], $arr)) $this->setVersion($arr[$keys[7]]); - if (array_key_exists($keys[8], $arr)) $this->setVersionCreatedAt($arr[$keys[8]]); - if (array_key_exists($keys[9], $arr)) $this->setVersionCreatedBy($arr[$keys[9]]); + if (array_key_exists($keys[5], $arr)) $this->setTemplateId($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setCreatedAt($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setUpdatedAt($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setVersion($arr[$keys[8]]); + if (array_key_exists($keys[9], $arr)) $this->setVersionCreatedAt($arr[$keys[9]]); + if (array_key_exists($keys[10], $arr)) $this->setVersionCreatedBy($arr[$keys[10]]); } /** @@ -1381,6 +1436,7 @@ abstract class ProductVersion implements ActiveRecordInterface if ($this->isColumnModified(ProductVersionTableMap::REF)) $criteria->add(ProductVersionTableMap::REF, $this->ref); if ($this->isColumnModified(ProductVersionTableMap::VISIBLE)) $criteria->add(ProductVersionTableMap::VISIBLE, $this->visible); if ($this->isColumnModified(ProductVersionTableMap::POSITION)) $criteria->add(ProductVersionTableMap::POSITION, $this->position); + if ($this->isColumnModified(ProductVersionTableMap::TEMPLATE_ID)) $criteria->add(ProductVersionTableMap::TEMPLATE_ID, $this->template_id); if ($this->isColumnModified(ProductVersionTableMap::CREATED_AT)) $criteria->add(ProductVersionTableMap::CREATED_AT, $this->created_at); if ($this->isColumnModified(ProductVersionTableMap::UPDATED_AT)) $criteria->add(ProductVersionTableMap::UPDATED_AT, $this->updated_at); if ($this->isColumnModified(ProductVersionTableMap::VERSION)) $criteria->add(ProductVersionTableMap::VERSION, $this->version); @@ -1461,6 +1517,7 @@ abstract class ProductVersion implements ActiveRecordInterface $copyObj->setRef($this->getRef()); $copyObj->setVisible($this->getVisible()); $copyObj->setPosition($this->getPosition()); + $copyObj->setTemplateId($this->getTemplateId()); $copyObj->setCreatedAt($this->getCreatedAt()); $copyObj->setUpdatedAt($this->getUpdatedAt()); $copyObj->setVersion($this->getVersion()); @@ -1554,6 +1611,7 @@ abstract class ProductVersion implements ActiveRecordInterface $this->ref = null; $this->visible = null; $this->position = null; + $this->template_id = null; $this->created_at = null; $this->updated_at = null; $this->version = null; diff --git a/core/lib/Thelia/Model/Base/ProductVersionQuery.php b/core/lib/Thelia/Model/Base/ProductVersionQuery.php index 1b43f7e66..b659becb9 100644 --- a/core/lib/Thelia/Model/Base/ProductVersionQuery.php +++ b/core/lib/Thelia/Model/Base/ProductVersionQuery.php @@ -26,6 +26,7 @@ use Thelia\Model\Map\ProductVersionTableMap; * @method ChildProductVersionQuery orderByRef($order = Criteria::ASC) Order by the ref column * @method ChildProductVersionQuery orderByVisible($order = Criteria::ASC) Order by the visible column * @method ChildProductVersionQuery orderByPosition($order = Criteria::ASC) Order by the position column + * @method ChildProductVersionQuery orderByTemplateId($order = Criteria::ASC) Order by the template_id column * @method ChildProductVersionQuery orderByCreatedAt($order = Criteria::ASC) Order by the created_at column * @method ChildProductVersionQuery orderByUpdatedAt($order = Criteria::ASC) Order by the updated_at column * @method ChildProductVersionQuery orderByVersion($order = Criteria::ASC) Order by the version column @@ -37,6 +38,7 @@ use Thelia\Model\Map\ProductVersionTableMap; * @method ChildProductVersionQuery groupByRef() Group by the ref column * @method ChildProductVersionQuery groupByVisible() Group by the visible column * @method ChildProductVersionQuery groupByPosition() Group by the position column + * @method ChildProductVersionQuery groupByTemplateId() Group by the template_id column * @method ChildProductVersionQuery groupByCreatedAt() Group by the created_at column * @method ChildProductVersionQuery groupByUpdatedAt() Group by the updated_at column * @method ChildProductVersionQuery groupByVersion() Group by the version column @@ -59,6 +61,7 @@ use Thelia\Model\Map\ProductVersionTableMap; * @method ChildProductVersion findOneByRef(string $ref) Return the first ChildProductVersion filtered by the ref column * @method ChildProductVersion findOneByVisible(int $visible) Return the first ChildProductVersion filtered by the visible column * @method ChildProductVersion findOneByPosition(int $position) Return the first ChildProductVersion filtered by the position column + * @method ChildProductVersion findOneByTemplateId(int $template_id) Return the first ChildProductVersion filtered by the template_id column * @method ChildProductVersion findOneByCreatedAt(string $created_at) Return the first ChildProductVersion filtered by the created_at column * @method ChildProductVersion findOneByUpdatedAt(string $updated_at) Return the first ChildProductVersion filtered by the updated_at column * @method ChildProductVersion findOneByVersion(int $version) Return the first ChildProductVersion filtered by the version column @@ -70,6 +73,7 @@ use Thelia\Model\Map\ProductVersionTableMap; * @method array findByRef(string $ref) Return ChildProductVersion objects filtered by the ref column * @method array findByVisible(int $visible) Return ChildProductVersion objects filtered by the visible column * @method array findByPosition(int $position) Return ChildProductVersion objects filtered by the position column + * @method array findByTemplateId(int $template_id) Return ChildProductVersion objects filtered by the template_id column * @method array findByCreatedAt(string $created_at) Return ChildProductVersion objects filtered by the created_at column * @method array findByUpdatedAt(string $updated_at) Return ChildProductVersion objects filtered by the updated_at column * @method array findByVersion(int $version) Return ChildProductVersion objects filtered by the version column @@ -163,7 +167,7 @@ abstract class ProductVersionQuery extends ModelCriteria */ protected function findPkSimple($key, $con) { - $sql = 'SELECT ID, TAX_RULE_ID, REF, VISIBLE, POSITION, CREATED_AT, UPDATED_AT, VERSION, VERSION_CREATED_AT, VERSION_CREATED_BY FROM product_version WHERE ID = :p0 AND VERSION = :p1'; + $sql = 'SELECT ID, TAX_RULE_ID, REF, VISIBLE, POSITION, TEMPLATE_ID, CREATED_AT, UPDATED_AT, VERSION, VERSION_CREATED_AT, VERSION_CREATED_BY FROM product_version WHERE ID = :p0 AND VERSION = :p1'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key[0], PDO::PARAM_INT); @@ -459,6 +463,47 @@ abstract class ProductVersionQuery extends ModelCriteria return $this->addUsingAlias(ProductVersionTableMap::POSITION, $position, $comparison); } + /** + * Filter the query on the template_id column + * + * Example usage: + * + * $query->filterByTemplateId(1234); // WHERE template_id = 1234 + * $query->filterByTemplateId(array(12, 34)); // WHERE template_id IN (12, 34) + * $query->filterByTemplateId(array('min' => 12)); // WHERE template_id > 12 + * + * + * @param mixed $templateId The value to use as filter. + * 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 ChildProductVersionQuery The current query, for fluid interface + */ + public function filterByTemplateId($templateId = null, $comparison = null) + { + if (is_array($templateId)) { + $useMinMax = false; + if (isset($templateId['min'])) { + $this->addUsingAlias(ProductVersionTableMap::TEMPLATE_ID, $templateId['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($templateId['max'])) { + $this->addUsingAlias(ProductVersionTableMap::TEMPLATE_ID, $templateId['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(ProductVersionTableMap::TEMPLATE_ID, $templateId, $comparison); + } + /** * Filter the query on the created_at column * diff --git a/core/lib/Thelia/Model/Base/TaxRule.php b/core/lib/Thelia/Model/Base/TaxRule.php index 61f21d4e1..9edb7b2fc 100644 --- a/core/lib/Thelia/Model/Base/TaxRule.php +++ b/core/lib/Thelia/Model/Base/TaxRule.php @@ -1434,6 +1434,31 @@ abstract class TaxRule implements ActiveRecordInterface return $this; } + + /** + * If this collection has already been initialized with + * an identical criteria, it returns the collection. + * Otherwise if this TaxRule is new, it will return + * an empty collection; or if this TaxRule has previously + * been saved, it will retrieve related Products from storage. + * + * This method is protected by default in order to keep the public + * api reasonable. You can provide public methods for those you + * actually need in TaxRule. + * + * @param Criteria $criteria optional Criteria object to narrow the query + * @param ConnectionInterface $con optional connection object + * @param string $joinBehavior optional join type to use (defaults to Criteria::LEFT_JOIN) + * @return Collection|ChildProduct[] List of ChildProduct objects + */ + public function getProductsJoinTemplate($criteria = null, $con = null, $joinBehavior = Criteria::LEFT_JOIN) + { + $query = ChildProductQuery::create(null, $criteria); + $query->joinWith('Template', $joinBehavior); + + return $this->getProducts($query, $con); + } + /** * Clears out the collTaxRuleCountries collection * diff --git a/core/lib/Thelia/Model/Base/Template.php b/core/lib/Thelia/Model/Base/Template.php new file mode 100644 index 000000000..77efa7ba0 --- /dev/null +++ b/core/lib/Thelia/Model/Base/Template.php @@ -0,0 +1,3019 @@ +modifiedColumns); + } + + /** + * Has specified column been modified? + * + * @param string $col column fully qualified name (TableMap::TYPE_COLNAME), e.g. Book::AUTHOR_ID + * @return boolean True if $col has been modified. + */ + public function isColumnModified($col) + { + return in_array($col, $this->modifiedColumns); + } + + /** + * Get the columns that have been modified in this object. + * @return array A unique list of the modified column names for this object. + */ + public function getModifiedColumns() + { + return array_unique($this->modifiedColumns); + } + + /** + * Returns whether the object has ever been saved. This will + * be false, if the object was retrieved from storage or was created + * and then saved. + * + * @return true, if the object has never been persisted. + */ + public function isNew() + { + return $this->new; + } + + /** + * Setter for the isNew attribute. This method will be called + * by Propel-generated children and objects. + * + * @param boolean $b the state of the object. + */ + public function setNew($b) + { + $this->new = (Boolean) $b; + } + + /** + * Whether this object has been deleted. + * @return boolean The deleted state of this object. + */ + public function isDeleted() + { + return $this->deleted; + } + + /** + * Specify whether this object has been deleted. + * @param boolean $b The deleted state of this object. + * @return void + */ + public function setDeleted($b) + { + $this->deleted = (Boolean) $b; + } + + /** + * Sets the modified state for the object to be false. + * @param string $col If supplied, only the specified column is reset. + * @return void + */ + public function resetModified($col = null) + { + if (null !== $col) { + while (false !== ($offset = array_search($col, $this->modifiedColumns))) { + array_splice($this->modifiedColumns, $offset, 1); + } + } else { + $this->modifiedColumns = array(); + } + } + + /** + * Compares this with another Template instance. If + * obj is an instance of Template, delegates to + * equals(Template). Otherwise, returns false. + * + * @param obj The object to compare to. + * @return Whether equal to the object specified. + */ + public function equals($obj) + { + $thisclazz = get_class($this); + if (!is_object($obj) || !($obj instanceof $thisclazz)) { + return false; + } + + if ($this === $obj) { + return true; + } + + if (null === $this->getPrimaryKey() + || null === $obj->getPrimaryKey()) { + return false; + } + + return $this->getPrimaryKey() === $obj->getPrimaryKey(); + } + + /** + * If the primary key is not null, return the hashcode of the + * primary key. Otherwise, return the hash code of the object. + * + * @return int Hashcode + */ + public function hashCode() + { + if (null !== $this->getPrimaryKey()) { + return crc32(serialize($this->getPrimaryKey())); + } + + return crc32(serialize(clone $this)); + } + + /** + * Get the associative array of the virtual columns in this object + * + * @param string $name The virtual column name + * + * @return array + */ + public function getVirtualColumns() + { + return $this->virtualColumns; + } + + /** + * Checks the existence of a virtual column in this object + * + * @return boolean + */ + public function hasVirtualColumn($name) + { + return array_key_exists($name, $this->virtualColumns); + } + + /** + * Get the value of a virtual column in this object + * + * @return mixed + */ + public function getVirtualColumn($name) + { + if (!$this->hasVirtualColumn($name)) { + throw new PropelException(sprintf('Cannot get value of inexistent virtual column %s.', $name)); + } + + return $this->virtualColumns[$name]; + } + + /** + * Set the value of a virtual column in this object + * + * @param string $name The virtual column name + * @param mixed $value The value to give to the virtual column + * + * @return Template The current object, for fluid interface + */ + public function setVirtualColumn($name, $value) + { + $this->virtualColumns[$name] = $value; + + return $this; + } + + /** + * Logs a message using Propel::log(). + * + * @param string $msg + * @param int $priority One of the Propel::LOG_* logging levels + * @return boolean + */ + protected function log($msg, $priority = Propel::LOG_INFO) + { + return Propel::log(get_class($this) . ': ' . $msg, $priority); + } + + /** + * Populate the current object from a string, using a given parser format + * + * $book = new Book(); + * $book->importFrom('JSON', '{"Id":9012,"Title":"Don Juan","ISBN":"0140422161","Price":12.99,"PublisherId":1234,"AuthorId":5678}'); + * + * + * @param mixed $parser A AbstractParser instance, + * or a format name ('XML', 'YAML', 'JSON', 'CSV') + * @param string $data The source data to import from + * + * @return Template The current object, for fluid interface + */ + public function importFrom($parser, $data) + { + if (!$parser instanceof AbstractParser) { + $parser = AbstractParser::getParser($parser); + } + + return $this->fromArray($parser->toArray($data), TableMap::TYPE_PHPNAME); + } + + /** + * Export the current object properties to a string, using a given parser format + * + * $book = BookQuery::create()->findPk(9012); + * echo $book->exportTo('JSON'); + * => {"Id":9012,"Title":"Don Juan","ISBN":"0140422161","Price":12.99,"PublisherId":1234,"AuthorId":5678}'); + * + * + * @param mixed $parser A AbstractParser instance, or a format name ('XML', 'YAML', 'JSON', 'CSV') + * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy load(ed) columns. Defaults to TRUE. + * @return string The exported data + */ + public function exportTo($parser, $includeLazyLoadColumns = true) + { + if (!$parser instanceof AbstractParser) { + $parser = AbstractParser::getParser($parser); + } + + return $parser->fromArray($this->toArray(TableMap::TYPE_PHPNAME, $includeLazyLoadColumns, array(), true)); + } + + /** + * Clean up internal collections prior to serializing + * Avoids recursive loops that turn into segmentation faults when serializing + */ + public function __sleep() + { + $this->clearAllReferences(); + + return array_keys(get_object_vars($this)); + } + + /** + * Get the [id] column value. + * + * @return int + */ + public function getId() + { + + return $this->id; + } + + /** + * 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 !== null ? $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 !== null ? $this->updated_at->format($format) : null; + } + } + + /** + * Set the value of [id] column. + * + * @param int $v new value + * @return \Thelia\Model\Template The current object (for fluent API support) + */ + public function setId($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->id !== $v) { + $this->id = $v; + $this->modifiedColumns[] = TemplateTableMap::ID; + } + + + return $this; + } // setId() + + /** + * 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\Template 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[] = TemplateTableMap::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\Template 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[] = TemplateTableMap::UPDATED_AT; + } + } // if either are not null + + + return $this; + } // setUpdatedAt() + + /** + * Indicates whether the columns in this object are only set to default values. + * + * This method can be used in conjunction with isModified() to indicate whether an object is both + * modified _and_ has some values set which are non-default. + * + * @return boolean Whether the columns in this object are only been set with default values. + */ + public function hasOnlyDefaultValues() + { + // otherwise, everything was equal, so return TRUE + return true; + } // hasOnlyDefaultValues() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (0-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param array $row The row returned by DataFetcher->fetch(). + * @param int $startcol 0-based offset column which indicates which restultset column to start with. + * @param boolean $rehydrate Whether this object is being re-hydrated from the database. + * @param string $indexType The index type of $row. Mostly DataFetcher->getIndexType(). + One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate($row, $startcol = 0, $rehydrate = false, $indexType = TableMap::TYPE_NUM) + { + try { + + + $col = $row[TableMap::TYPE_NUM == $indexType ? 0 + $startcol : TemplateTableMap::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)]; + $this->id = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 1 + $startcol : TemplateTableMap::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 ? 2 + $startcol : TemplateTableMap::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); + + if ($rehydrate) { + $this->ensureConsistency(); + } + + return $startcol + 3; // 3 = TemplateTableMap::NUM_HYDRATE_COLUMNS. + + } catch (Exception $e) { + throw new PropelException("Error populating \Thelia\Model\Template object", 0, $e); + } + } + + /** + * Checks and repairs the internal consistency of the object. + * + * This method is executed after an already-instantiated object is re-hydrated + * from the database. It exists to check any foreign keys to make sure that + * the objects related to the current object are correct based on foreign key. + * + * You can override this method in the stub class, but you should always invoke + * the base method from the overridden method (i.e. parent::ensureConsistency()), + * in case your model changes. + * + * @throws PropelException + */ + public function ensureConsistency() + { + } // ensureConsistency + + /** + * Reloads this object from datastore based on primary key and (optionally) resets all associated objects. + * + * This will only work if the object has been saved and has a valid primary key set. + * + * @param boolean $deep (optional) Whether to also de-associated any related objects. + * @param ConnectionInterface $con (optional) The ConnectionInterface connection to use. + * @return void + * @throws PropelException - if this object is deleted, unsaved or doesn't have pk match in db + */ + public function reload($deep = false, ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("Cannot reload a deleted object."); + } + + if ($this->isNew()) { + throw new PropelException("Cannot reload an unsaved object."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getReadConnection(TemplateTableMap::DATABASE_NAME); + } + + // We don't need to alter the object instance pool; we're just modifying this instance + // already in the pool. + + $dataFetcher = ChildTemplateQuery::create(null, $this->buildPkeyCriteria())->setFormatter(ModelCriteria::FORMAT_STATEMENT)->find($con); + $row = $dataFetcher->fetch(); + $dataFetcher->close(); + if (!$row) { + throw new PropelException('Cannot find matching row in the database to reload object values.'); + } + $this->hydrate($row, 0, true, $dataFetcher->getIndexType()); // rehydrate + + if ($deep) { // also de-associate any related objects? + + $this->collProducts = null; + + $this->collFeatureTemplates = null; + + $this->collAttributeTemplates = null; + + $this->collTemplateI18ns = null; + + $this->collFeatures = null; + $this->collAttributes = null; + } // if (deep) + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param ConnectionInterface $con + * @return void + * @throws PropelException + * @see Template::setDeleted() + * @see Template::isDeleted() + */ + public function delete(ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getWriteConnection(TemplateTableMap::DATABASE_NAME); + } + + $con->beginTransaction(); + try { + $deleteQuery = ChildTemplateQuery::create() + ->filterByPrimaryKey($this->getPrimaryKey()); + $ret = $this->preDelete($con); + if ($ret) { + $deleteQuery->delete($con); + $this->postDelete($con); + $con->commit(); + $this->setDeleted(true); + } else { + $con->commit(); + } + } catch (Exception $e) { + $con->rollBack(); + throw $e; + } + } + + /** + * Persists this object to the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All modified related objects will also be persisted in the doSave() + * method. This method wraps all precipitate database operations in a + * single transaction. + * + * @param ConnectionInterface $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save(ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getWriteConnection(TemplateTableMap::DATABASE_NAME); + } + + $con->beginTransaction(); + $isInsert = $this->isNew(); + try { + $ret = $this->preSave($con); + if ($isInsert) { + $ret = $ret && $this->preInsert($con); + // timestampable behavior + if (!$this->isColumnModified(TemplateTableMap::CREATED_AT)) { + $this->setCreatedAt(time()); + } + if (!$this->isColumnModified(TemplateTableMap::UPDATED_AT)) { + $this->setUpdatedAt(time()); + } + } else { + $ret = $ret && $this->preUpdate($con); + // timestampable behavior + if ($this->isModified() && !$this->isColumnModified(TemplateTableMap::UPDATED_AT)) { + $this->setUpdatedAt(time()); + } + } + if ($ret) { + $affectedRows = $this->doSave($con); + if ($isInsert) { + $this->postInsert($con); + } else { + $this->postUpdate($con); + } + $this->postSave($con); + TemplateTableMap::addInstanceToPool($this); + } else { + $affectedRows = 0; + } + $con->commit(); + + return $affectedRows; + } catch (Exception $e) { + $con->rollBack(); + throw $e; + } + } + + /** + * Performs the work of inserting or updating the row in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param ConnectionInterface $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave(ConnectionInterface $con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + if ($this->isNew() || $this->isModified()) { + // persist changes + if ($this->isNew()) { + $this->doInsert($con); + } else { + $this->doUpdate($con); + } + $affectedRows += 1; + $this->resetModified(); + } + + if ($this->featuresScheduledForDeletion !== null) { + if (!$this->featuresScheduledForDeletion->isEmpty()) { + $pks = array(); + $pk = $this->getPrimaryKey(); + foreach ($this->featuresScheduledForDeletion->getPrimaryKeys(false) as $remotePk) { + $pks[] = array($remotePk, $pk); + } + + FeatureTemplateQuery::create() + ->filterByPrimaryKeys($pks) + ->delete($con); + $this->featuresScheduledForDeletion = null; + } + + foreach ($this->getFeatures() as $feature) { + if ($feature->isModified()) { + $feature->save($con); + } + } + } elseif ($this->collFeatures) { + foreach ($this->collFeatures as $feature) { + if ($feature->isModified()) { + $feature->save($con); + } + } + } + + if ($this->attributesScheduledForDeletion !== null) { + if (!$this->attributesScheduledForDeletion->isEmpty()) { + $pks = array(); + $pk = $this->getPrimaryKey(); + foreach ($this->attributesScheduledForDeletion->getPrimaryKeys(false) as $remotePk) { + $pks[] = array($remotePk, $pk); + } + + AttributeTemplateQuery::create() + ->filterByPrimaryKeys($pks) + ->delete($con); + $this->attributesScheduledForDeletion = null; + } + + foreach ($this->getAttributes() as $attribute) { + if ($attribute->isModified()) { + $attribute->save($con); + } + } + } elseif ($this->collAttributes) { + foreach ($this->collAttributes as $attribute) { + if ($attribute->isModified()) { + $attribute->save($con); + } + } + } + + if ($this->productsScheduledForDeletion !== null) { + if (!$this->productsScheduledForDeletion->isEmpty()) { + \Thelia\Model\ProductQuery::create() + ->filterByPrimaryKeys($this->productsScheduledForDeletion->getPrimaryKeys(false)) + ->delete($con); + $this->productsScheduledForDeletion = null; + } + } + + if ($this->collProducts !== null) { + foreach ($this->collProducts as $referrerFK) { + if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) { + $affectedRows += $referrerFK->save($con); + } + } + } + + if ($this->featureTemplatesScheduledForDeletion !== null) { + if (!$this->featureTemplatesScheduledForDeletion->isEmpty()) { + \Thelia\Model\FeatureTemplateQuery::create() + ->filterByPrimaryKeys($this->featureTemplatesScheduledForDeletion->getPrimaryKeys(false)) + ->delete($con); + $this->featureTemplatesScheduledForDeletion = null; + } + } + + if ($this->collFeatureTemplates !== null) { + foreach ($this->collFeatureTemplates as $referrerFK) { + if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) { + $affectedRows += $referrerFK->save($con); + } + } + } + + if ($this->attributeTemplatesScheduledForDeletion !== null) { + if (!$this->attributeTemplatesScheduledForDeletion->isEmpty()) { + \Thelia\Model\AttributeTemplateQuery::create() + ->filterByPrimaryKeys($this->attributeTemplatesScheduledForDeletion->getPrimaryKeys(false)) + ->delete($con); + $this->attributeTemplatesScheduledForDeletion = null; + } + } + + if ($this->collAttributeTemplates !== null) { + foreach ($this->collAttributeTemplates as $referrerFK) { + if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) { + $affectedRows += $referrerFK->save($con); + } + } + } + + if ($this->templateI18nsScheduledForDeletion !== null) { + if (!$this->templateI18nsScheduledForDeletion->isEmpty()) { + \Thelia\Model\TemplateI18nQuery::create() + ->filterByPrimaryKeys($this->templateI18nsScheduledForDeletion->getPrimaryKeys(false)) + ->delete($con); + $this->templateI18nsScheduledForDeletion = null; + } + } + + if ($this->collTemplateI18ns !== null) { + foreach ($this->collTemplateI18ns as $referrerFK) { + if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) { + $affectedRows += $referrerFK->save($con); + } + } + } + + $this->alreadyInSave = false; + + } + + return $affectedRows; + } // doSave() + + /** + * Insert the row in the database. + * + * @param ConnectionInterface $con + * + * @throws PropelException + * @see doSave() + */ + protected function doInsert(ConnectionInterface $con) + { + $modifiedColumns = array(); + $index = 0; + + $this->modifiedColumns[] = TemplateTableMap::ID; + if (null !== $this->id) { + throw new PropelException('Cannot insert a value for auto-increment primary key (' . TemplateTableMap::ID . ')'); + } + + // check the columns in natural order for more readable SQL queries + if ($this->isColumnModified(TemplateTableMap::ID)) { + $modifiedColumns[':p' . $index++] = 'ID'; + } + if ($this->isColumnModified(TemplateTableMap::CREATED_AT)) { + $modifiedColumns[':p' . $index++] = 'CREATED_AT'; + } + if ($this->isColumnModified(TemplateTableMap::UPDATED_AT)) { + $modifiedColumns[':p' . $index++] = 'UPDATED_AT'; + } + + $sql = sprintf( + 'INSERT INTO template (%s) VALUES (%s)', + implode(', ', $modifiedColumns), + implode(', ', array_keys($modifiedColumns)) + ); + + try { + $stmt = $con->prepare($sql); + foreach ($modifiedColumns as $identifier => $columnName) { + switch ($columnName) { + case 'ID': + $stmt->bindValue($identifier, $this->id, PDO::PARAM_INT); + 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(); + } catch (Exception $e) { + Propel::log($e->getMessage(), Propel::LOG_ERR); + throw new PropelException(sprintf('Unable to execute INSERT statement [%s]', $sql), 0, $e); + } + + try { + $pk = $con->lastInsertId(); + } catch (Exception $e) { + throw new PropelException('Unable to get autoincrement id.', 0, $e); + } + $this->setId($pk); + + $this->setNew(false); + } + + /** + * Update the row in the database. + * + * @param ConnectionInterface $con + * + * @return Integer Number of updated rows + * @see doSave() + */ + protected function doUpdate(ConnectionInterface $con) + { + $selectCriteria = $this->buildPkeyCriteria(); + $valuesCriteria = $this->buildCriteria(); + + return $selectCriteria->doUpdate($valuesCriteria, $con); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @return mixed Value of field. + */ + public function getByName($name, $type = TableMap::TYPE_PHPNAME) + { + $pos = TemplateTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); + $field = $this->getByPosition($pos); + + return $field; + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch ($pos) { + case 0: + return $this->getId(); + break; + case 1: + return $this->getCreatedAt(); + break; + case 2: + return $this->getUpdatedAt(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType (optional) One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME, + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to TRUE. + * @param array $alreadyDumpedObjects List of objects to skip to avoid recursion + * @param boolean $includeForeignObjects (optional) Whether to include hydrated related objects. Default to FALSE. + * + * @return array an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = TableMap::TYPE_PHPNAME, $includeLazyLoadColumns = true, $alreadyDumpedObjects = array(), $includeForeignObjects = false) + { + if (isset($alreadyDumpedObjects['Template'][$this->getPrimaryKey()])) { + return '*RECURSION*'; + } + $alreadyDumpedObjects['Template'][$this->getPrimaryKey()] = true; + $keys = TemplateTableMap::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getId(), + $keys[1] => $this->getCreatedAt(), + $keys[2] => $this->getUpdatedAt(), + ); + $virtualColumns = $this->virtualColumns; + foreach($virtualColumns as $key => $virtualColumn) + { + $result[$key] = $virtualColumn; + } + + if ($includeForeignObjects) { + if (null !== $this->collProducts) { + $result['Products'] = $this->collProducts->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); + } + if (null !== $this->collFeatureTemplates) { + $result['FeatureTemplates'] = $this->collFeatureTemplates->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); + } + if (null !== $this->collAttributeTemplates) { + $result['AttributeTemplates'] = $this->collAttributeTemplates->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); + } + if (null !== $this->collTemplateI18ns) { + $result['TemplateI18ns'] = $this->collTemplateI18ns->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); + } + } + + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @return void + */ + public function setByName($name, $value, $type = TableMap::TYPE_PHPNAME) + { + $pos = TemplateTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); + + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch ($pos) { + case 0: + $this->setId($value); + break; + case 1: + $this->setCreatedAt($value); + break; + case 2: + $this->setUpdatedAt($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME, + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * The default key type is the column's TableMap::TYPE_PHPNAME. + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = TableMap::TYPE_PHPNAME) + { + $keys = TemplateTableMap::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setCreatedAt($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setUpdatedAt($arr[$keys[2]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(TemplateTableMap::DATABASE_NAME); + + if ($this->isColumnModified(TemplateTableMap::ID)) $criteria->add(TemplateTableMap::ID, $this->id); + if ($this->isColumnModified(TemplateTableMap::CREATED_AT)) $criteria->add(TemplateTableMap::CREATED_AT, $this->created_at); + if ($this->isColumnModified(TemplateTableMap::UPDATED_AT)) $criteria->add(TemplateTableMap::UPDATED_AT, $this->updated_at); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(TemplateTableMap::DATABASE_NAME); + $criteria->add(TemplateTableMap::ID, $this->id); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return int + */ + public function getPrimaryKey() + { + return $this->getId(); + } + + /** + * Generic method to set the primary key (id column). + * + * @param int $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setId($key); + } + + /** + * Returns true if the primary key for this object is null. + * @return boolean + */ + public function isPrimaryKeyNull() + { + + return null === $this->getId(); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of \Thelia\Model\Template (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @param boolean $makeNew Whether to reset autoincrement PKs and make the object new. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false, $makeNew = true) + { + $copyObj->setCreatedAt($this->getCreatedAt()); + $copyObj->setUpdatedAt($this->getUpdatedAt()); + + if ($deepCopy) { + // important: temporarily setNew(false) because this affects the behavior of + // the getter/setter methods for fkey referrer objects. + $copyObj->setNew(false); + + foreach ($this->getProducts() as $relObj) { + if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves + $copyObj->addProduct($relObj->copy($deepCopy)); + } + } + + foreach ($this->getFeatureTemplates() as $relObj) { + if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves + $copyObj->addFeatureTemplate($relObj->copy($deepCopy)); + } + } + + foreach ($this->getAttributeTemplates() as $relObj) { + if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves + $copyObj->addAttributeTemplate($relObj->copy($deepCopy)); + } + } + + foreach ($this->getTemplateI18ns() as $relObj) { + if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves + $copyObj->addTemplateI18n($relObj->copy($deepCopy)); + } + } + + } // if ($deepCopy) + + if ($makeNew) { + $copyObj->setNew(true); + $copyObj->setId(NULL); // this is a auto-increment column, so set to default value + } + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return \Thelia\Model\Template Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + + return $copyObj; + } + + + /** + * Initializes a collection based on the name of a relation. + * Avoids crafting an 'init[$relationName]s' method name + * that wouldn't work when StandardEnglishPluralizer is used. + * + * @param string $relationName The name of the relation to initialize + * @return void + */ + public function initRelation($relationName) + { + if ('Product' == $relationName) { + return $this->initProducts(); + } + if ('FeatureTemplate' == $relationName) { + return $this->initFeatureTemplates(); + } + if ('AttributeTemplate' == $relationName) { + return $this->initAttributeTemplates(); + } + if ('TemplateI18n' == $relationName) { + return $this->initTemplateI18ns(); + } + } + + /** + * Clears out the collProducts collection + * + * This does not modify the database; however, it will remove any associated objects, causing + * them to be refetched by subsequent calls to accessor method. + * + * @return void + * @see addProducts() + */ + public function clearProducts() + { + $this->collProducts = null; // important to set this to NULL since that means it is uninitialized + } + + /** + * Reset is the collProducts collection loaded partially. + */ + public function resetPartialProducts($v = true) + { + $this->collProductsPartial = $v; + } + + /** + * Initializes the collProducts collection. + * + * By default this just sets the collProducts collection to an empty array (like clearcollProducts()); + * however, you may wish to override this method in your stub class to provide setting appropriate + * to your application -- for example, setting the initial array to the values stored in database. + * + * @param boolean $overrideExisting If set to true, the method call initializes + * the collection even if it is not empty + * + * @return void + */ + public function initProducts($overrideExisting = true) + { + if (null !== $this->collProducts && !$overrideExisting) { + return; + } + $this->collProducts = new ObjectCollection(); + $this->collProducts->setModel('\Thelia\Model\Product'); + } + + /** + * Gets an array of ChildProduct objects which contain a foreign key that references this object. + * + * If the $criteria is not null, it is used to always fetch the results from the database. + * Otherwise the results are fetched from the database the first time, then cached. + * Next time the same method is called without $criteria, the cached collection is returned. + * If this ChildTemplate is new, it will return + * an empty collection or the current collection; the criteria is ignored on a new object. + * + * @param Criteria $criteria optional Criteria object to narrow the query + * @param ConnectionInterface $con optional connection object + * @return Collection|ChildProduct[] List of ChildProduct objects + * @throws PropelException + */ + public function getProducts($criteria = null, ConnectionInterface $con = null) + { + $partial = $this->collProductsPartial && !$this->isNew(); + if (null === $this->collProducts || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collProducts) { + // return empty collection + $this->initProducts(); + } else { + $collProducts = ChildProductQuery::create(null, $criteria) + ->filterByTemplate($this) + ->find($con); + + if (null !== $criteria) { + if (false !== $this->collProductsPartial && count($collProducts)) { + $this->initProducts(false); + + foreach ($collProducts as $obj) { + if (false == $this->collProducts->contains($obj)) { + $this->collProducts->append($obj); + } + } + + $this->collProductsPartial = true; + } + + $collProducts->getInternalIterator()->rewind(); + + return $collProducts; + } + + if ($partial && $this->collProducts) { + foreach ($this->collProducts as $obj) { + if ($obj->isNew()) { + $collProducts[] = $obj; + } + } + } + + $this->collProducts = $collProducts; + $this->collProductsPartial = false; + } + } + + return $this->collProducts; + } + + /** + * Sets a collection of Product objects related by a one-to-many relationship + * to the current object. + * It will also schedule objects for deletion based on a diff between old objects (aka persisted) + * and new objects from the given Propel collection. + * + * @param Collection $products A Propel collection. + * @param ConnectionInterface $con Optional connection object + * @return ChildTemplate The current object (for fluent API support) + */ + public function setProducts(Collection $products, ConnectionInterface $con = null) + { + $productsToDelete = $this->getProducts(new Criteria(), $con)->diff($products); + + + $this->productsScheduledForDeletion = $productsToDelete; + + foreach ($productsToDelete as $productRemoved) { + $productRemoved->setTemplate(null); + } + + $this->collProducts = null; + foreach ($products as $product) { + $this->addProduct($product); + } + + $this->collProducts = $products; + $this->collProductsPartial = false; + + return $this; + } + + /** + * Returns the number of related Product objects. + * + * @param Criteria $criteria + * @param boolean $distinct + * @param ConnectionInterface $con + * @return int Count of related Product objects. + * @throws PropelException + */ + public function countProducts(Criteria $criteria = null, $distinct = false, ConnectionInterface $con = null) + { + $partial = $this->collProductsPartial && !$this->isNew(); + if (null === $this->collProducts || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collProducts) { + return 0; + } + + if ($partial && !$criteria) { + return count($this->getProducts()); + } + + $query = ChildProductQuery::create(null, $criteria); + if ($distinct) { + $query->distinct(); + } + + return $query + ->filterByTemplate($this) + ->count($con); + } + + return count($this->collProducts); + } + + /** + * Method called to associate a ChildProduct object to this object + * through the ChildProduct foreign key attribute. + * + * @param ChildProduct $l ChildProduct + * @return \Thelia\Model\Template The current object (for fluent API support) + */ + public function addProduct(ChildProduct $l) + { + if ($this->collProducts === null) { + $this->initProducts(); + $this->collProductsPartial = true; + } + + if (!in_array($l, $this->collProducts->getArrayCopy(), true)) { // only add it if the **same** object is not already associated + $this->doAddProduct($l); + } + + return $this; + } + + /** + * @param Product $product The product object to add. + */ + protected function doAddProduct($product) + { + $this->collProducts[]= $product; + $product->setTemplate($this); + } + + /** + * @param Product $product The product object to remove. + * @return ChildTemplate The current object (for fluent API support) + */ + public function removeProduct($product) + { + if ($this->getProducts()->contains($product)) { + $this->collProducts->remove($this->collProducts->search($product)); + if (null === $this->productsScheduledForDeletion) { + $this->productsScheduledForDeletion = clone $this->collProducts; + $this->productsScheduledForDeletion->clear(); + } + $this->productsScheduledForDeletion[]= clone $product; + $product->setTemplate(null); + } + + return $this; + } + + + /** + * If this collection has already been initialized with + * an identical criteria, it returns the collection. + * Otherwise if this Template is new, it will return + * an empty collection; or if this Template has previously + * been saved, it will retrieve related Products from storage. + * + * This method is protected by default in order to keep the public + * api reasonable. You can provide public methods for those you + * actually need in Template. + * + * @param Criteria $criteria optional Criteria object to narrow the query + * @param ConnectionInterface $con optional connection object + * @param string $joinBehavior optional join type to use (defaults to Criteria::LEFT_JOIN) + * @return Collection|ChildProduct[] List of ChildProduct objects + */ + public function getProductsJoinTaxRule($criteria = null, $con = null, $joinBehavior = Criteria::LEFT_JOIN) + { + $query = ChildProductQuery::create(null, $criteria); + $query->joinWith('TaxRule', $joinBehavior); + + return $this->getProducts($query, $con); + } + + /** + * Clears out the collFeatureTemplates collection + * + * This does not modify the database; however, it will remove any associated objects, causing + * them to be refetched by subsequent calls to accessor method. + * + * @return void + * @see addFeatureTemplates() + */ + public function clearFeatureTemplates() + { + $this->collFeatureTemplates = null; // important to set this to NULL since that means it is uninitialized + } + + /** + * Reset is the collFeatureTemplates collection loaded partially. + */ + public function resetPartialFeatureTemplates($v = true) + { + $this->collFeatureTemplatesPartial = $v; + } + + /** + * Initializes the collFeatureTemplates collection. + * + * By default this just sets the collFeatureTemplates collection to an empty array (like clearcollFeatureTemplates()); + * however, you may wish to override this method in your stub class to provide setting appropriate + * to your application -- for example, setting the initial array to the values stored in database. + * + * @param boolean $overrideExisting If set to true, the method call initializes + * the collection even if it is not empty + * + * @return void + */ + public function initFeatureTemplates($overrideExisting = true) + { + if (null !== $this->collFeatureTemplates && !$overrideExisting) { + return; + } + $this->collFeatureTemplates = new ObjectCollection(); + $this->collFeatureTemplates->setModel('\Thelia\Model\FeatureTemplate'); + } + + /** + * Gets an array of ChildFeatureTemplate objects which contain a foreign key that references this object. + * + * If the $criteria is not null, it is used to always fetch the results from the database. + * Otherwise the results are fetched from the database the first time, then cached. + * Next time the same method is called without $criteria, the cached collection is returned. + * If this ChildTemplate is new, it will return + * an empty collection or the current collection; the criteria is ignored on a new object. + * + * @param Criteria $criteria optional Criteria object to narrow the query + * @param ConnectionInterface $con optional connection object + * @return Collection|ChildFeatureTemplate[] List of ChildFeatureTemplate objects + * @throws PropelException + */ + public function getFeatureTemplates($criteria = null, ConnectionInterface $con = null) + { + $partial = $this->collFeatureTemplatesPartial && !$this->isNew(); + if (null === $this->collFeatureTemplates || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collFeatureTemplates) { + // return empty collection + $this->initFeatureTemplates(); + } else { + $collFeatureTemplates = ChildFeatureTemplateQuery::create(null, $criteria) + ->filterByTemplate($this) + ->find($con); + + if (null !== $criteria) { + if (false !== $this->collFeatureTemplatesPartial && count($collFeatureTemplates)) { + $this->initFeatureTemplates(false); + + foreach ($collFeatureTemplates as $obj) { + if (false == $this->collFeatureTemplates->contains($obj)) { + $this->collFeatureTemplates->append($obj); + } + } + + $this->collFeatureTemplatesPartial = true; + } + + $collFeatureTemplates->getInternalIterator()->rewind(); + + return $collFeatureTemplates; + } + + if ($partial && $this->collFeatureTemplates) { + foreach ($this->collFeatureTemplates as $obj) { + if ($obj->isNew()) { + $collFeatureTemplates[] = $obj; + } + } + } + + $this->collFeatureTemplates = $collFeatureTemplates; + $this->collFeatureTemplatesPartial = false; + } + } + + return $this->collFeatureTemplates; + } + + /** + * Sets a collection of FeatureTemplate objects related by a one-to-many relationship + * to the current object. + * It will also schedule objects for deletion based on a diff between old objects (aka persisted) + * and new objects from the given Propel collection. + * + * @param Collection $featureTemplates A Propel collection. + * @param ConnectionInterface $con Optional connection object + * @return ChildTemplate The current object (for fluent API support) + */ + public function setFeatureTemplates(Collection $featureTemplates, ConnectionInterface $con = null) + { + $featureTemplatesToDelete = $this->getFeatureTemplates(new Criteria(), $con)->diff($featureTemplates); + + + $this->featureTemplatesScheduledForDeletion = $featureTemplatesToDelete; + + foreach ($featureTemplatesToDelete as $featureTemplateRemoved) { + $featureTemplateRemoved->setTemplate(null); + } + + $this->collFeatureTemplates = null; + foreach ($featureTemplates as $featureTemplate) { + $this->addFeatureTemplate($featureTemplate); + } + + $this->collFeatureTemplates = $featureTemplates; + $this->collFeatureTemplatesPartial = false; + + return $this; + } + + /** + * Returns the number of related FeatureTemplate objects. + * + * @param Criteria $criteria + * @param boolean $distinct + * @param ConnectionInterface $con + * @return int Count of related FeatureTemplate objects. + * @throws PropelException + */ + public function countFeatureTemplates(Criteria $criteria = null, $distinct = false, ConnectionInterface $con = null) + { + $partial = $this->collFeatureTemplatesPartial && !$this->isNew(); + if (null === $this->collFeatureTemplates || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collFeatureTemplates) { + return 0; + } + + if ($partial && !$criteria) { + return count($this->getFeatureTemplates()); + } + + $query = ChildFeatureTemplateQuery::create(null, $criteria); + if ($distinct) { + $query->distinct(); + } + + return $query + ->filterByTemplate($this) + ->count($con); + } + + return count($this->collFeatureTemplates); + } + + /** + * Method called to associate a ChildFeatureTemplate object to this object + * through the ChildFeatureTemplate foreign key attribute. + * + * @param ChildFeatureTemplate $l ChildFeatureTemplate + * @return \Thelia\Model\Template The current object (for fluent API support) + */ + public function addFeatureTemplate(ChildFeatureTemplate $l) + { + if ($this->collFeatureTemplates === null) { + $this->initFeatureTemplates(); + $this->collFeatureTemplatesPartial = true; + } + + if (!in_array($l, $this->collFeatureTemplates->getArrayCopy(), true)) { // only add it if the **same** object is not already associated + $this->doAddFeatureTemplate($l); + } + + return $this; + } + + /** + * @param FeatureTemplate $featureTemplate The featureTemplate object to add. + */ + protected function doAddFeatureTemplate($featureTemplate) + { + $this->collFeatureTemplates[]= $featureTemplate; + $featureTemplate->setTemplate($this); + } + + /** + * @param FeatureTemplate $featureTemplate The featureTemplate object to remove. + * @return ChildTemplate The current object (for fluent API support) + */ + public function removeFeatureTemplate($featureTemplate) + { + if ($this->getFeatureTemplates()->contains($featureTemplate)) { + $this->collFeatureTemplates->remove($this->collFeatureTemplates->search($featureTemplate)); + if (null === $this->featureTemplatesScheduledForDeletion) { + $this->featureTemplatesScheduledForDeletion = clone $this->collFeatureTemplates; + $this->featureTemplatesScheduledForDeletion->clear(); + } + $this->featureTemplatesScheduledForDeletion[]= clone $featureTemplate; + $featureTemplate->setTemplate(null); + } + + return $this; + } + + + /** + * If this collection has already been initialized with + * an identical criteria, it returns the collection. + * Otherwise if this Template is new, it will return + * an empty collection; or if this Template has previously + * been saved, it will retrieve related FeatureTemplates from storage. + * + * This method is protected by default in order to keep the public + * api reasonable. You can provide public methods for those you + * actually need in Template. + * + * @param Criteria $criteria optional Criteria object to narrow the query + * @param ConnectionInterface $con optional connection object + * @param string $joinBehavior optional join type to use (defaults to Criteria::LEFT_JOIN) + * @return Collection|ChildFeatureTemplate[] List of ChildFeatureTemplate objects + */ + public function getFeatureTemplatesJoinFeature($criteria = null, $con = null, $joinBehavior = Criteria::LEFT_JOIN) + { + $query = ChildFeatureTemplateQuery::create(null, $criteria); + $query->joinWith('Feature', $joinBehavior); + + return $this->getFeatureTemplates($query, $con); + } + + /** + * Clears out the collAttributeTemplates collection + * + * This does not modify the database; however, it will remove any associated objects, causing + * them to be refetched by subsequent calls to accessor method. + * + * @return void + * @see addAttributeTemplates() + */ + public function clearAttributeTemplates() + { + $this->collAttributeTemplates = null; // important to set this to NULL since that means it is uninitialized + } + + /** + * Reset is the collAttributeTemplates collection loaded partially. + */ + public function resetPartialAttributeTemplates($v = true) + { + $this->collAttributeTemplatesPartial = $v; + } + + /** + * Initializes the collAttributeTemplates collection. + * + * By default this just sets the collAttributeTemplates collection to an empty array (like clearcollAttributeTemplates()); + * however, you may wish to override this method in your stub class to provide setting appropriate + * to your application -- for example, setting the initial array to the values stored in database. + * + * @param boolean $overrideExisting If set to true, the method call initializes + * the collection even if it is not empty + * + * @return void + */ + public function initAttributeTemplates($overrideExisting = true) + { + if (null !== $this->collAttributeTemplates && !$overrideExisting) { + return; + } + $this->collAttributeTemplates = new ObjectCollection(); + $this->collAttributeTemplates->setModel('\Thelia\Model\AttributeTemplate'); + } + + /** + * Gets an array of ChildAttributeTemplate objects which contain a foreign key that references this object. + * + * If the $criteria is not null, it is used to always fetch the results from the database. + * Otherwise the results are fetched from the database the first time, then cached. + * Next time the same method is called without $criteria, the cached collection is returned. + * If this ChildTemplate is new, it will return + * an empty collection or the current collection; the criteria is ignored on a new object. + * + * @param Criteria $criteria optional Criteria object to narrow the query + * @param ConnectionInterface $con optional connection object + * @return Collection|ChildAttributeTemplate[] List of ChildAttributeTemplate objects + * @throws PropelException + */ + public function getAttributeTemplates($criteria = null, ConnectionInterface $con = null) + { + $partial = $this->collAttributeTemplatesPartial && !$this->isNew(); + if (null === $this->collAttributeTemplates || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collAttributeTemplates) { + // return empty collection + $this->initAttributeTemplates(); + } else { + $collAttributeTemplates = ChildAttributeTemplateQuery::create(null, $criteria) + ->filterByTemplate($this) + ->find($con); + + if (null !== $criteria) { + if (false !== $this->collAttributeTemplatesPartial && count($collAttributeTemplates)) { + $this->initAttributeTemplates(false); + + foreach ($collAttributeTemplates as $obj) { + if (false == $this->collAttributeTemplates->contains($obj)) { + $this->collAttributeTemplates->append($obj); + } + } + + $this->collAttributeTemplatesPartial = true; + } + + $collAttributeTemplates->getInternalIterator()->rewind(); + + return $collAttributeTemplates; + } + + if ($partial && $this->collAttributeTemplates) { + foreach ($this->collAttributeTemplates as $obj) { + if ($obj->isNew()) { + $collAttributeTemplates[] = $obj; + } + } + } + + $this->collAttributeTemplates = $collAttributeTemplates; + $this->collAttributeTemplatesPartial = false; + } + } + + return $this->collAttributeTemplates; + } + + /** + * Sets a collection of AttributeTemplate objects related by a one-to-many relationship + * to the current object. + * It will also schedule objects for deletion based on a diff between old objects (aka persisted) + * and new objects from the given Propel collection. + * + * @param Collection $attributeTemplates A Propel collection. + * @param ConnectionInterface $con Optional connection object + * @return ChildTemplate The current object (for fluent API support) + */ + public function setAttributeTemplates(Collection $attributeTemplates, ConnectionInterface $con = null) + { + $attributeTemplatesToDelete = $this->getAttributeTemplates(new Criteria(), $con)->diff($attributeTemplates); + + + $this->attributeTemplatesScheduledForDeletion = $attributeTemplatesToDelete; + + foreach ($attributeTemplatesToDelete as $attributeTemplateRemoved) { + $attributeTemplateRemoved->setTemplate(null); + } + + $this->collAttributeTemplates = null; + foreach ($attributeTemplates as $attributeTemplate) { + $this->addAttributeTemplate($attributeTemplate); + } + + $this->collAttributeTemplates = $attributeTemplates; + $this->collAttributeTemplatesPartial = false; + + return $this; + } + + /** + * Returns the number of related AttributeTemplate objects. + * + * @param Criteria $criteria + * @param boolean $distinct + * @param ConnectionInterface $con + * @return int Count of related AttributeTemplate objects. + * @throws PropelException + */ + public function countAttributeTemplates(Criteria $criteria = null, $distinct = false, ConnectionInterface $con = null) + { + $partial = $this->collAttributeTemplatesPartial && !$this->isNew(); + if (null === $this->collAttributeTemplates || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collAttributeTemplates) { + return 0; + } + + if ($partial && !$criteria) { + return count($this->getAttributeTemplates()); + } + + $query = ChildAttributeTemplateQuery::create(null, $criteria); + if ($distinct) { + $query->distinct(); + } + + return $query + ->filterByTemplate($this) + ->count($con); + } + + return count($this->collAttributeTemplates); + } + + /** + * Method called to associate a ChildAttributeTemplate object to this object + * through the ChildAttributeTemplate foreign key attribute. + * + * @param ChildAttributeTemplate $l ChildAttributeTemplate + * @return \Thelia\Model\Template The current object (for fluent API support) + */ + public function addAttributeTemplate(ChildAttributeTemplate $l) + { + if ($this->collAttributeTemplates === null) { + $this->initAttributeTemplates(); + $this->collAttributeTemplatesPartial = true; + } + + if (!in_array($l, $this->collAttributeTemplates->getArrayCopy(), true)) { // only add it if the **same** object is not already associated + $this->doAddAttributeTemplate($l); + } + + return $this; + } + + /** + * @param AttributeTemplate $attributeTemplate The attributeTemplate object to add. + */ + protected function doAddAttributeTemplate($attributeTemplate) + { + $this->collAttributeTemplates[]= $attributeTemplate; + $attributeTemplate->setTemplate($this); + } + + /** + * @param AttributeTemplate $attributeTemplate The attributeTemplate object to remove. + * @return ChildTemplate The current object (for fluent API support) + */ + public function removeAttributeTemplate($attributeTemplate) + { + if ($this->getAttributeTemplates()->contains($attributeTemplate)) { + $this->collAttributeTemplates->remove($this->collAttributeTemplates->search($attributeTemplate)); + if (null === $this->attributeTemplatesScheduledForDeletion) { + $this->attributeTemplatesScheduledForDeletion = clone $this->collAttributeTemplates; + $this->attributeTemplatesScheduledForDeletion->clear(); + } + $this->attributeTemplatesScheduledForDeletion[]= clone $attributeTemplate; + $attributeTemplate->setTemplate(null); + } + + return $this; + } + + + /** + * If this collection has already been initialized with + * an identical criteria, it returns the collection. + * Otherwise if this Template is new, it will return + * an empty collection; or if this Template has previously + * been saved, it will retrieve related AttributeTemplates from storage. + * + * This method is protected by default in order to keep the public + * api reasonable. You can provide public methods for those you + * actually need in Template. + * + * @param Criteria $criteria optional Criteria object to narrow the query + * @param ConnectionInterface $con optional connection object + * @param string $joinBehavior optional join type to use (defaults to Criteria::LEFT_JOIN) + * @return Collection|ChildAttributeTemplate[] List of ChildAttributeTemplate objects + */ + public function getAttributeTemplatesJoinAttribute($criteria = null, $con = null, $joinBehavior = Criteria::LEFT_JOIN) + { + $query = ChildAttributeTemplateQuery::create(null, $criteria); + $query->joinWith('Attribute', $joinBehavior); + + return $this->getAttributeTemplates($query, $con); + } + + /** + * Clears out the collTemplateI18ns collection + * + * This does not modify the database; however, it will remove any associated objects, causing + * them to be refetched by subsequent calls to accessor method. + * + * @return void + * @see addTemplateI18ns() + */ + public function clearTemplateI18ns() + { + $this->collTemplateI18ns = null; // important to set this to NULL since that means it is uninitialized + } + + /** + * Reset is the collTemplateI18ns collection loaded partially. + */ + public function resetPartialTemplateI18ns($v = true) + { + $this->collTemplateI18nsPartial = $v; + } + + /** + * Initializes the collTemplateI18ns collection. + * + * By default this just sets the collTemplateI18ns collection to an empty array (like clearcollTemplateI18ns()); + * however, you may wish to override this method in your stub class to provide setting appropriate + * to your application -- for example, setting the initial array to the values stored in database. + * + * @param boolean $overrideExisting If set to true, the method call initializes + * the collection even if it is not empty + * + * @return void + */ + public function initTemplateI18ns($overrideExisting = true) + { + if (null !== $this->collTemplateI18ns && !$overrideExisting) { + return; + } + $this->collTemplateI18ns = new ObjectCollection(); + $this->collTemplateI18ns->setModel('\Thelia\Model\TemplateI18n'); + } + + /** + * Gets an array of ChildTemplateI18n objects which contain a foreign key that references this object. + * + * If the $criteria is not null, it is used to always fetch the results from the database. + * Otherwise the results are fetched from the database the first time, then cached. + * Next time the same method is called without $criteria, the cached collection is returned. + * If this ChildTemplate is new, it will return + * an empty collection or the current collection; the criteria is ignored on a new object. + * + * @param Criteria $criteria optional Criteria object to narrow the query + * @param ConnectionInterface $con optional connection object + * @return Collection|ChildTemplateI18n[] List of ChildTemplateI18n objects + * @throws PropelException + */ + public function getTemplateI18ns($criteria = null, ConnectionInterface $con = null) + { + $partial = $this->collTemplateI18nsPartial && !$this->isNew(); + if (null === $this->collTemplateI18ns || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collTemplateI18ns) { + // return empty collection + $this->initTemplateI18ns(); + } else { + $collTemplateI18ns = ChildTemplateI18nQuery::create(null, $criteria) + ->filterByTemplate($this) + ->find($con); + + if (null !== $criteria) { + if (false !== $this->collTemplateI18nsPartial && count($collTemplateI18ns)) { + $this->initTemplateI18ns(false); + + foreach ($collTemplateI18ns as $obj) { + if (false == $this->collTemplateI18ns->contains($obj)) { + $this->collTemplateI18ns->append($obj); + } + } + + $this->collTemplateI18nsPartial = true; + } + + $collTemplateI18ns->getInternalIterator()->rewind(); + + return $collTemplateI18ns; + } + + if ($partial && $this->collTemplateI18ns) { + foreach ($this->collTemplateI18ns as $obj) { + if ($obj->isNew()) { + $collTemplateI18ns[] = $obj; + } + } + } + + $this->collTemplateI18ns = $collTemplateI18ns; + $this->collTemplateI18nsPartial = false; + } + } + + return $this->collTemplateI18ns; + } + + /** + * Sets a collection of TemplateI18n objects related by a one-to-many relationship + * to the current object. + * It will also schedule objects for deletion based on a diff between old objects (aka persisted) + * and new objects from the given Propel collection. + * + * @param Collection $templateI18ns A Propel collection. + * @param ConnectionInterface $con Optional connection object + * @return ChildTemplate The current object (for fluent API support) + */ + public function setTemplateI18ns(Collection $templateI18ns, ConnectionInterface $con = null) + { + $templateI18nsToDelete = $this->getTemplateI18ns(new Criteria(), $con)->diff($templateI18ns); + + + //since at least one column in the foreign key is at the same time a PK + //we can not just set a PK to NULL in the lines below. We have to store + //a backup of all values, so we are able to manipulate these items based on the onDelete value later. + $this->templateI18nsScheduledForDeletion = clone $templateI18nsToDelete; + + foreach ($templateI18nsToDelete as $templateI18nRemoved) { + $templateI18nRemoved->setTemplate(null); + } + + $this->collTemplateI18ns = null; + foreach ($templateI18ns as $templateI18n) { + $this->addTemplateI18n($templateI18n); + } + + $this->collTemplateI18ns = $templateI18ns; + $this->collTemplateI18nsPartial = false; + + return $this; + } + + /** + * Returns the number of related TemplateI18n objects. + * + * @param Criteria $criteria + * @param boolean $distinct + * @param ConnectionInterface $con + * @return int Count of related TemplateI18n objects. + * @throws PropelException + */ + public function countTemplateI18ns(Criteria $criteria = null, $distinct = false, ConnectionInterface $con = null) + { + $partial = $this->collTemplateI18nsPartial && !$this->isNew(); + if (null === $this->collTemplateI18ns || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collTemplateI18ns) { + return 0; + } + + if ($partial && !$criteria) { + return count($this->getTemplateI18ns()); + } + + $query = ChildTemplateI18nQuery::create(null, $criteria); + if ($distinct) { + $query->distinct(); + } + + return $query + ->filterByTemplate($this) + ->count($con); + } + + return count($this->collTemplateI18ns); + } + + /** + * Method called to associate a ChildTemplateI18n object to this object + * through the ChildTemplateI18n foreign key attribute. + * + * @param ChildTemplateI18n $l ChildTemplateI18n + * @return \Thelia\Model\Template The current object (for fluent API support) + */ + public function addTemplateI18n(ChildTemplateI18n $l) + { + if ($l && $locale = $l->getLocale()) { + $this->setLocale($locale); + $this->currentTranslations[$locale] = $l; + } + if ($this->collTemplateI18ns === null) { + $this->initTemplateI18ns(); + $this->collTemplateI18nsPartial = true; + } + + if (!in_array($l, $this->collTemplateI18ns->getArrayCopy(), true)) { // only add it if the **same** object is not already associated + $this->doAddTemplateI18n($l); + } + + return $this; + } + + /** + * @param TemplateI18n $templateI18n The templateI18n object to add. + */ + protected function doAddTemplateI18n($templateI18n) + { + $this->collTemplateI18ns[]= $templateI18n; + $templateI18n->setTemplate($this); + } + + /** + * @param TemplateI18n $templateI18n The templateI18n object to remove. + * @return ChildTemplate The current object (for fluent API support) + */ + public function removeTemplateI18n($templateI18n) + { + if ($this->getTemplateI18ns()->contains($templateI18n)) { + $this->collTemplateI18ns->remove($this->collTemplateI18ns->search($templateI18n)); + if (null === $this->templateI18nsScheduledForDeletion) { + $this->templateI18nsScheduledForDeletion = clone $this->collTemplateI18ns; + $this->templateI18nsScheduledForDeletion->clear(); + } + $this->templateI18nsScheduledForDeletion[]= clone $templateI18n; + $templateI18n->setTemplate(null); + } + + return $this; + } + + /** + * Clears out the collFeatures collection + * + * This does not modify the database; however, it will remove any associated objects, causing + * them to be refetched by subsequent calls to accessor method. + * + * @return void + * @see addFeatures() + */ + public function clearFeatures() + { + $this->collFeatures = null; // important to set this to NULL since that means it is uninitialized + $this->collFeaturesPartial = null; + } + + /** + * Initializes the collFeatures collection. + * + * By default this just sets the collFeatures collection to an empty collection (like clearFeatures()); + * however, you may wish to override this method in your stub class to provide setting appropriate + * to your application -- for example, setting the initial array to the values stored in database. + * + * @return void + */ + public function initFeatures() + { + $this->collFeatures = new ObjectCollection(); + $this->collFeatures->setModel('\Thelia\Model\Feature'); + } + + /** + * Gets a collection of ChildFeature objects related by a many-to-many relationship + * to the current object by way of the feature_template cross-reference table. + * + * If the $criteria is not null, it is used to always fetch the results from the database. + * Otherwise the results are fetched from the database the first time, then cached. + * Next time the same method is called without $criteria, the cached collection is returned. + * If this ChildTemplate is new, it will return + * an empty collection or the current collection; the criteria is ignored on a new object. + * + * @param Criteria $criteria Optional query object to filter the query + * @param ConnectionInterface $con Optional connection object + * + * @return ObjectCollection|ChildFeature[] List of ChildFeature objects + */ + public function getFeatures($criteria = null, ConnectionInterface $con = null) + { + if (null === $this->collFeatures || null !== $criteria) { + if ($this->isNew() && null === $this->collFeatures) { + // return empty collection + $this->initFeatures(); + } else { + $collFeatures = ChildFeatureQuery::create(null, $criteria) + ->filterByTemplate($this) + ->find($con); + if (null !== $criteria) { + return $collFeatures; + } + $this->collFeatures = $collFeatures; + } + } + + return $this->collFeatures; + } + + /** + * Sets a collection of Feature objects related by a many-to-many relationship + * to the current object by way of the feature_template cross-reference table. + * It will also schedule objects for deletion based on a diff between old objects (aka persisted) + * and new objects from the given Propel collection. + * + * @param Collection $features A Propel collection. + * @param ConnectionInterface $con Optional connection object + * @return ChildTemplate The current object (for fluent API support) + */ + public function setFeatures(Collection $features, ConnectionInterface $con = null) + { + $this->clearFeatures(); + $currentFeatures = $this->getFeatures(); + + $this->featuresScheduledForDeletion = $currentFeatures->diff($features); + + foreach ($features as $feature) { + if (!$currentFeatures->contains($feature)) { + $this->doAddFeature($feature); + } + } + + $this->collFeatures = $features; + + return $this; + } + + /** + * Gets the number of ChildFeature objects related by a many-to-many relationship + * to the current object by way of the feature_template cross-reference table. + * + * @param Criteria $criteria Optional query object to filter the query + * @param boolean $distinct Set to true to force count distinct + * @param ConnectionInterface $con Optional connection object + * + * @return int the number of related ChildFeature objects + */ + public function countFeatures($criteria = null, $distinct = false, ConnectionInterface $con = null) + { + if (null === $this->collFeatures || null !== $criteria) { + if ($this->isNew() && null === $this->collFeatures) { + return 0; + } else { + $query = ChildFeatureQuery::create(null, $criteria); + if ($distinct) { + $query->distinct(); + } + + return $query + ->filterByTemplate($this) + ->count($con); + } + } else { + return count($this->collFeatures); + } + } + + /** + * Associate a ChildFeature object to this object + * through the feature_template cross reference table. + * + * @param ChildFeature $feature The ChildFeatureTemplate object to relate + * @return ChildTemplate The current object (for fluent API support) + */ + public function addFeature(ChildFeature $feature) + { + if ($this->collFeatures === null) { + $this->initFeatures(); + } + + if (!$this->collFeatures->contains($feature)) { // only add it if the **same** object is not already associated + $this->doAddFeature($feature); + $this->collFeatures[] = $feature; + } + + return $this; + } + + /** + * @param Feature $feature The feature object to add. + */ + protected function doAddFeature($feature) + { + $featureTemplate = new ChildFeatureTemplate(); + $featureTemplate->setFeature($feature); + $this->addFeatureTemplate($featureTemplate); + // set the back reference to this object directly as using provided method either results + // in endless loop or in multiple relations + if (!$feature->getTemplates()->contains($this)) { + $foreignCollection = $feature->getTemplates(); + $foreignCollection[] = $this; + } + } + + /** + * Remove a ChildFeature object to this object + * through the feature_template cross reference table. + * + * @param ChildFeature $feature The ChildFeatureTemplate object to relate + * @return ChildTemplate The current object (for fluent API support) + */ + public function removeFeature(ChildFeature $feature) + { + if ($this->getFeatures()->contains($feature)) { + $this->collFeatures->remove($this->collFeatures->search($feature)); + + if (null === $this->featuresScheduledForDeletion) { + $this->featuresScheduledForDeletion = clone $this->collFeatures; + $this->featuresScheduledForDeletion->clear(); + } + + $this->featuresScheduledForDeletion[] = $feature; + } + + return $this; + } + + /** + * Clears out the collAttributes collection + * + * This does not modify the database; however, it will remove any associated objects, causing + * them to be refetched by subsequent calls to accessor method. + * + * @return void + * @see addAttributes() + */ + public function clearAttributes() + { + $this->collAttributes = null; // important to set this to NULL since that means it is uninitialized + $this->collAttributesPartial = null; + } + + /** + * Initializes the collAttributes collection. + * + * By default this just sets the collAttributes collection to an empty collection (like clearAttributes()); + * however, you may wish to override this method in your stub class to provide setting appropriate + * to your application -- for example, setting the initial array to the values stored in database. + * + * @return void + */ + public function initAttributes() + { + $this->collAttributes = new ObjectCollection(); + $this->collAttributes->setModel('\Thelia\Model\Attribute'); + } + + /** + * Gets a collection of ChildAttribute objects related by a many-to-many relationship + * to the current object by way of the attribute_template cross-reference table. + * + * If the $criteria is not null, it is used to always fetch the results from the database. + * Otherwise the results are fetched from the database the first time, then cached. + * Next time the same method is called without $criteria, the cached collection is returned. + * If this ChildTemplate is new, it will return + * an empty collection or the current collection; the criteria is ignored on a new object. + * + * @param Criteria $criteria Optional query object to filter the query + * @param ConnectionInterface $con Optional connection object + * + * @return ObjectCollection|ChildAttribute[] List of ChildAttribute objects + */ + public function getAttributes($criteria = null, ConnectionInterface $con = null) + { + if (null === $this->collAttributes || null !== $criteria) { + if ($this->isNew() && null === $this->collAttributes) { + // return empty collection + $this->initAttributes(); + } else { + $collAttributes = ChildAttributeQuery::create(null, $criteria) + ->filterByTemplate($this) + ->find($con); + if (null !== $criteria) { + return $collAttributes; + } + $this->collAttributes = $collAttributes; + } + } + + return $this->collAttributes; + } + + /** + * Sets a collection of Attribute objects related by a many-to-many relationship + * to the current object by way of the attribute_template cross-reference table. + * It will also schedule objects for deletion based on a diff between old objects (aka persisted) + * and new objects from the given Propel collection. + * + * @param Collection $attributes A Propel collection. + * @param ConnectionInterface $con Optional connection object + * @return ChildTemplate The current object (for fluent API support) + */ + public function setAttributes(Collection $attributes, ConnectionInterface $con = null) + { + $this->clearAttributes(); + $currentAttributes = $this->getAttributes(); + + $this->attributesScheduledForDeletion = $currentAttributes->diff($attributes); + + foreach ($attributes as $attribute) { + if (!$currentAttributes->contains($attribute)) { + $this->doAddAttribute($attribute); + } + } + + $this->collAttributes = $attributes; + + return $this; + } + + /** + * Gets the number of ChildAttribute objects related by a many-to-many relationship + * to the current object by way of the attribute_template cross-reference table. + * + * @param Criteria $criteria Optional query object to filter the query + * @param boolean $distinct Set to true to force count distinct + * @param ConnectionInterface $con Optional connection object + * + * @return int the number of related ChildAttribute objects + */ + public function countAttributes($criteria = null, $distinct = false, ConnectionInterface $con = null) + { + if (null === $this->collAttributes || null !== $criteria) { + if ($this->isNew() && null === $this->collAttributes) { + return 0; + } else { + $query = ChildAttributeQuery::create(null, $criteria); + if ($distinct) { + $query->distinct(); + } + + return $query + ->filterByTemplate($this) + ->count($con); + } + } else { + return count($this->collAttributes); + } + } + + /** + * Associate a ChildAttribute object to this object + * through the attribute_template cross reference table. + * + * @param ChildAttribute $attribute The ChildAttributeTemplate object to relate + * @return ChildTemplate The current object (for fluent API support) + */ + public function addAttribute(ChildAttribute $attribute) + { + if ($this->collAttributes === null) { + $this->initAttributes(); + } + + if (!$this->collAttributes->contains($attribute)) { // only add it if the **same** object is not already associated + $this->doAddAttribute($attribute); + $this->collAttributes[] = $attribute; + } + + return $this; + } + + /** + * @param Attribute $attribute The attribute object to add. + */ + protected function doAddAttribute($attribute) + { + $attributeTemplate = new ChildAttributeTemplate(); + $attributeTemplate->setAttribute($attribute); + $this->addAttributeTemplate($attributeTemplate); + // set the back reference to this object directly as using provided method either results + // in endless loop or in multiple relations + if (!$attribute->getTemplates()->contains($this)) { + $foreignCollection = $attribute->getTemplates(); + $foreignCollection[] = $this; + } + } + + /** + * Remove a ChildAttribute object to this object + * through the attribute_template cross reference table. + * + * @param ChildAttribute $attribute The ChildAttributeTemplate object to relate + * @return ChildTemplate The current object (for fluent API support) + */ + public function removeAttribute(ChildAttribute $attribute) + { + if ($this->getAttributes()->contains($attribute)) { + $this->collAttributes->remove($this->collAttributes->search($attribute)); + + if (null === $this->attributesScheduledForDeletion) { + $this->attributesScheduledForDeletion = clone $this->collAttributes; + $this->attributesScheduledForDeletion->clear(); + } + + $this->attributesScheduledForDeletion[] = $attribute; + } + + return $this; + } + + /** + * Clears the current object and sets all attributes to their default values + */ + public function clear() + { + $this->id = null; + $this->created_at = null; + $this->updated_at = null; + $this->alreadyInSave = false; + $this->clearAllReferences(); + $this->resetModified(); + $this->setNew(true); + $this->setDeleted(false); + } + + /** + * Resets all references to other model objects or collections of model objects. + * + * This method is a user-space workaround for PHP's inability to garbage collect + * objects with circular references (even in PHP 5.3). This is currently necessary + * when using Propel in certain daemon or large-volume/high-memory operations. + * + * @param boolean $deep Whether to also clear the references on all referrer objects. + */ + public function clearAllReferences($deep = false) + { + if ($deep) { + if ($this->collProducts) { + foreach ($this->collProducts as $o) { + $o->clearAllReferences($deep); + } + } + if ($this->collFeatureTemplates) { + foreach ($this->collFeatureTemplates as $o) { + $o->clearAllReferences($deep); + } + } + if ($this->collAttributeTemplates) { + foreach ($this->collAttributeTemplates as $o) { + $o->clearAllReferences($deep); + } + } + if ($this->collTemplateI18ns) { + foreach ($this->collTemplateI18ns as $o) { + $o->clearAllReferences($deep); + } + } + if ($this->collFeatures) { + foreach ($this->collFeatures as $o) { + $o->clearAllReferences($deep); + } + } + if ($this->collAttributes) { + foreach ($this->collAttributes as $o) { + $o->clearAllReferences($deep); + } + } + } // if ($deep) + + // i18n behavior + $this->currentLocale = 'en_US'; + $this->currentTranslations = null; + + if ($this->collProducts instanceof Collection) { + $this->collProducts->clearIterator(); + } + $this->collProducts = null; + if ($this->collFeatureTemplates instanceof Collection) { + $this->collFeatureTemplates->clearIterator(); + } + $this->collFeatureTemplates = null; + if ($this->collAttributeTemplates instanceof Collection) { + $this->collAttributeTemplates->clearIterator(); + } + $this->collAttributeTemplates = null; + if ($this->collTemplateI18ns instanceof Collection) { + $this->collTemplateI18ns->clearIterator(); + } + $this->collTemplateI18ns = null; + if ($this->collFeatures instanceof Collection) { + $this->collFeatures->clearIterator(); + } + $this->collFeatures = null; + if ($this->collAttributes instanceof Collection) { + $this->collAttributes->clearIterator(); + } + $this->collAttributes = null; + } + + /** + * Return the string representation of this object + * + * @return string + */ + public function __toString() + { + return (string) $this->exportTo(TemplateTableMap::DEFAULT_STRING_FORMAT); + } + + // i18n behavior + + /** + * Sets the locale for translations + * + * @param string $locale Locale to use for the translation, e.g. 'fr_FR' + * + * @return ChildTemplate The current object (for fluent API support) + */ + public function setLocale($locale = 'en_US') + { + $this->currentLocale = $locale; + + return $this; + } + + /** + * Gets the locale for translations + * + * @return string $locale Locale to use for the translation, e.g. 'fr_FR' + */ + public function getLocale() + { + return $this->currentLocale; + } + + /** + * Returns the current translation for a given locale + * + * @param string $locale Locale to use for the translation, e.g. 'fr_FR' + * @param ConnectionInterface $con an optional connection object + * + * @return ChildTemplateI18n */ + public function getTranslation($locale = 'en_US', ConnectionInterface $con = null) + { + if (!isset($this->currentTranslations[$locale])) { + if (null !== $this->collTemplateI18ns) { + foreach ($this->collTemplateI18ns as $translation) { + if ($translation->getLocale() == $locale) { + $this->currentTranslations[$locale] = $translation; + + return $translation; + } + } + } + if ($this->isNew()) { + $translation = new ChildTemplateI18n(); + $translation->setLocale($locale); + } else { + $translation = ChildTemplateI18nQuery::create() + ->filterByPrimaryKey(array($this->getPrimaryKey(), $locale)) + ->findOneOrCreate($con); + $this->currentTranslations[$locale] = $translation; + } + $this->addTemplateI18n($translation); + } + + return $this->currentTranslations[$locale]; + } + + /** + * Remove the translation for a given locale + * + * @param string $locale Locale to use for the translation, e.g. 'fr_FR' + * @param ConnectionInterface $con an optional connection object + * + * @return ChildTemplate The current object (for fluent API support) + */ + public function removeTranslation($locale = 'en_US', ConnectionInterface $con = null) + { + if (!$this->isNew()) { + ChildTemplateI18nQuery::create() + ->filterByPrimaryKey(array($this->getPrimaryKey(), $locale)) + ->delete($con); + } + if (isset($this->currentTranslations[$locale])) { + unset($this->currentTranslations[$locale]); + } + foreach ($this->collTemplateI18ns as $key => $translation) { + if ($translation->getLocale() == $locale) { + unset($this->collTemplateI18ns[$key]); + break; + } + } + + return $this; + } + + /** + * Returns the current translation + * + * @param ConnectionInterface $con an optional connection object + * + * @return ChildTemplateI18n */ + public function getCurrentTranslation(ConnectionInterface $con = null) + { + return $this->getTranslation($this->getLocale(), $con); + } + + + /** + * Get the [name] column value. + * + * @return string + */ + public function getName() + { + return $this->getCurrentTranslation()->getName(); + } + + + /** + * Set the value of [name] column. + * + * @param string $v new value + * @return \Thelia\Model\TemplateI18n The current object (for fluent API support) + */ + public function setName($v) + { $this->getCurrentTranslation()->setName($v); + + return $this; + } + + // timestampable behavior + + /** + * Mark the current object so that the update date doesn't get updated during next save + * + * @return ChildTemplate The current object (for fluent API support) + */ + public function keepUpdateDateUnchanged() + { + $this->modifiedColumns[] = TemplateTableMap::UPDATED_AT; + + return $this; + } + + /** + * Code to be run before persisting the object + * @param ConnectionInterface $con + * @return boolean + */ + public function preSave(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after persisting the object + * @param ConnectionInterface $con + */ + public function postSave(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before inserting to database + * @param ConnectionInterface $con + * @return boolean + */ + public function preInsert(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after inserting to database + * @param ConnectionInterface $con + */ + public function postInsert(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before updating the object in database + * @param ConnectionInterface $con + * @return boolean + */ + public function preUpdate(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after updating the object in database + * @param ConnectionInterface $con + */ + public function postUpdate(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before deleting the object in database + * @param ConnectionInterface $con + * @return boolean + */ + public function preDelete(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after deleting the object in database + * @param ConnectionInterface $con + */ + public function postDelete(ConnectionInterface $con = null) + { + + } + + + /** + * Derived method to catches calls to undefined methods. + * + * Provides magic import/export method support (fromXML()/toXML(), fromYAML()/toYAML(), etc.). + * Allows to define default __call() behavior if you overwrite __call() + * + * @param string $name + * @param mixed $params + * + * @return array|string + */ + public function __call($name, $params) + { + if (0 === strpos($name, 'get')) { + $virtualColumn = substr($name, 3); + if ($this->hasVirtualColumn($virtualColumn)) { + return $this->getVirtualColumn($virtualColumn); + } + + $virtualColumn = lcfirst($virtualColumn); + if ($this->hasVirtualColumn($virtualColumn)) { + return $this->getVirtualColumn($virtualColumn); + } + } + + if (0 === strpos($name, 'from')) { + $format = substr($name, 4); + + return $this->importFrom($format, reset($params)); + } + + if (0 === strpos($name, 'to')) { + $format = substr($name, 2); + $includeLazyLoadColumns = isset($params[0]) ? $params[0] : true; + + return $this->exportTo($format, $includeLazyLoadColumns); + } + + throw new BadMethodCallException(sprintf('Call to undefined method: %s.', $name)); + } + +} diff --git a/core/lib/Thelia/Model/Base/TemplateI18n.php b/core/lib/Thelia/Model/Base/TemplateI18n.php new file mode 100644 index 000000000..7c61c6983 --- /dev/null +++ b/core/lib/Thelia/Model/Base/TemplateI18n.php @@ -0,0 +1,1265 @@ +locale = 'en_US'; + } + + /** + * Initializes internal state of Thelia\Model\Base\TemplateI18n object. + * @see applyDefaults() + */ + public function __construct() + { + $this->applyDefaultValues(); + } + + /** + * Returns whether the object has been modified. + * + * @return boolean True if the object has been modified. + */ + public function isModified() + { + return !empty($this->modifiedColumns); + } + + /** + * Has specified column been modified? + * + * @param string $col column fully qualified name (TableMap::TYPE_COLNAME), e.g. Book::AUTHOR_ID + * @return boolean True if $col has been modified. + */ + public function isColumnModified($col) + { + return in_array($col, $this->modifiedColumns); + } + + /** + * Get the columns that have been modified in this object. + * @return array A unique list of the modified column names for this object. + */ + public function getModifiedColumns() + { + return array_unique($this->modifiedColumns); + } + + /** + * Returns whether the object has ever been saved. This will + * be false, if the object was retrieved from storage or was created + * and then saved. + * + * @return true, if the object has never been persisted. + */ + public function isNew() + { + return $this->new; + } + + /** + * Setter for the isNew attribute. This method will be called + * by Propel-generated children and objects. + * + * @param boolean $b the state of the object. + */ + public function setNew($b) + { + $this->new = (Boolean) $b; + } + + /** + * Whether this object has been deleted. + * @return boolean The deleted state of this object. + */ + public function isDeleted() + { + return $this->deleted; + } + + /** + * Specify whether this object has been deleted. + * @param boolean $b The deleted state of this object. + * @return void + */ + public function setDeleted($b) + { + $this->deleted = (Boolean) $b; + } + + /** + * Sets the modified state for the object to be false. + * @param string $col If supplied, only the specified column is reset. + * @return void + */ + public function resetModified($col = null) + { + if (null !== $col) { + while (false !== ($offset = array_search($col, $this->modifiedColumns))) { + array_splice($this->modifiedColumns, $offset, 1); + } + } else { + $this->modifiedColumns = array(); + } + } + + /** + * Compares this with another TemplateI18n instance. If + * obj is an instance of TemplateI18n, delegates to + * equals(TemplateI18n). Otherwise, returns false. + * + * @param obj The object to compare to. + * @return Whether equal to the object specified. + */ + public function equals($obj) + { + $thisclazz = get_class($this); + if (!is_object($obj) || !($obj instanceof $thisclazz)) { + return false; + } + + if ($this === $obj) { + return true; + } + + if (null === $this->getPrimaryKey() + || null === $obj->getPrimaryKey()) { + return false; + } + + return $this->getPrimaryKey() === $obj->getPrimaryKey(); + } + + /** + * If the primary key is not null, return the hashcode of the + * primary key. Otherwise, return the hash code of the object. + * + * @return int Hashcode + */ + public function hashCode() + { + if (null !== $this->getPrimaryKey()) { + return crc32(serialize($this->getPrimaryKey())); + } + + return crc32(serialize(clone $this)); + } + + /** + * Get the associative array of the virtual columns in this object + * + * @param string $name The virtual column name + * + * @return array + */ + public function getVirtualColumns() + { + return $this->virtualColumns; + } + + /** + * Checks the existence of a virtual column in this object + * + * @return boolean + */ + public function hasVirtualColumn($name) + { + return array_key_exists($name, $this->virtualColumns); + } + + /** + * Get the value of a virtual column in this object + * + * @return mixed + */ + public function getVirtualColumn($name) + { + if (!$this->hasVirtualColumn($name)) { + throw new PropelException(sprintf('Cannot get value of inexistent virtual column %s.', $name)); + } + + return $this->virtualColumns[$name]; + } + + /** + * Set the value of a virtual column in this object + * + * @param string $name The virtual column name + * @param mixed $value The value to give to the virtual column + * + * @return TemplateI18n The current object, for fluid interface + */ + public function setVirtualColumn($name, $value) + { + $this->virtualColumns[$name] = $value; + + return $this; + } + + /** + * Logs a message using Propel::log(). + * + * @param string $msg + * @param int $priority One of the Propel::LOG_* logging levels + * @return boolean + */ + protected function log($msg, $priority = Propel::LOG_INFO) + { + return Propel::log(get_class($this) . ': ' . $msg, $priority); + } + + /** + * Populate the current object from a string, using a given parser format + * + * $book = new Book(); + * $book->importFrom('JSON', '{"Id":9012,"Title":"Don Juan","ISBN":"0140422161","Price":12.99,"PublisherId":1234,"AuthorId":5678}'); + * + * + * @param mixed $parser A AbstractParser instance, + * or a format name ('XML', 'YAML', 'JSON', 'CSV') + * @param string $data The source data to import from + * + * @return TemplateI18n The current object, for fluid interface + */ + public function importFrom($parser, $data) + { + if (!$parser instanceof AbstractParser) { + $parser = AbstractParser::getParser($parser); + } + + return $this->fromArray($parser->toArray($data), TableMap::TYPE_PHPNAME); + } + + /** + * Export the current object properties to a string, using a given parser format + * + * $book = BookQuery::create()->findPk(9012); + * echo $book->exportTo('JSON'); + * => {"Id":9012,"Title":"Don Juan","ISBN":"0140422161","Price":12.99,"PublisherId":1234,"AuthorId":5678}'); + * + * + * @param mixed $parser A AbstractParser instance, or a format name ('XML', 'YAML', 'JSON', 'CSV') + * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy load(ed) columns. Defaults to TRUE. + * @return string The exported data + */ + public function exportTo($parser, $includeLazyLoadColumns = true) + { + if (!$parser instanceof AbstractParser) { + $parser = AbstractParser::getParser($parser); + } + + return $parser->fromArray($this->toArray(TableMap::TYPE_PHPNAME, $includeLazyLoadColumns, array(), true)); + } + + /** + * Clean up internal collections prior to serializing + * Avoids recursive loops that turn into segmentation faults when serializing + */ + public function __sleep() + { + $this->clearAllReferences(); + + return array_keys(get_object_vars($this)); + } + + /** + * Get the [id] column value. + * + * @return int + */ + public function getId() + { + + return $this->id; + } + + /** + * Get the [locale] column value. + * + * @return string + */ + public function getLocale() + { + + return $this->locale; + } + + /** + * Get the [name] column value. + * + * @return string + */ + public function getName() + { + + return $this->name; + } + + /** + * Set the value of [id] column. + * + * @param int $v new value + * @return \Thelia\Model\TemplateI18n The current object (for fluent API support) + */ + public function setId($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->id !== $v) { + $this->id = $v; + $this->modifiedColumns[] = TemplateI18nTableMap::ID; + } + + if ($this->aTemplate !== null && $this->aTemplate->getId() !== $v) { + $this->aTemplate = null; + } + + + return $this; + } // setId() + + /** + * Set the value of [locale] column. + * + * @param string $v new value + * @return \Thelia\Model\TemplateI18n 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[] = TemplateI18nTableMap::LOCALE; + } + + + return $this; + } // setLocale() + + /** + * Set the value of [name] column. + * + * @param string $v new value + * @return \Thelia\Model\TemplateI18n The current object (for fluent API support) + */ + public function setName($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->name !== $v) { + $this->name = $v; + $this->modifiedColumns[] = TemplateI18nTableMap::NAME; + } + + + return $this; + } // setName() + + /** + * Indicates whether the columns in this object are only set to default values. + * + * This method can be used in conjunction with isModified() to indicate whether an object is both + * modified _and_ has some values set which are non-default. + * + * @return boolean Whether the columns in this object are only been set with default values. + */ + public function hasOnlyDefaultValues() + { + if ($this->locale !== 'en_US') { + return false; + } + + // otherwise, everything was equal, so return TRUE + return true; + } // hasOnlyDefaultValues() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (0-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param array $row The row returned by DataFetcher->fetch(). + * @param int $startcol 0-based offset column which indicates which restultset column to start with. + * @param boolean $rehydrate Whether this object is being re-hydrated from the database. + * @param string $indexType The index type of $row. Mostly DataFetcher->getIndexType(). + One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate($row, $startcol = 0, $rehydrate = false, $indexType = TableMap::TYPE_NUM) + { + try { + + + $col = $row[TableMap::TYPE_NUM == $indexType ? 0 + $startcol : TemplateI18nTableMap::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)]; + $this->id = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 1 + $startcol : TemplateI18nTableMap::translateFieldName('Locale', TableMap::TYPE_PHPNAME, $indexType)]; + $this->locale = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : TemplateI18nTableMap::translateFieldName('Name', TableMap::TYPE_PHPNAME, $indexType)]; + $this->name = (null !== $col) ? (string) $col : null; + $this->resetModified(); + + $this->setNew(false); + + if ($rehydrate) { + $this->ensureConsistency(); + } + + return $startcol + 3; // 3 = TemplateI18nTableMap::NUM_HYDRATE_COLUMNS. + + } catch (Exception $e) { + throw new PropelException("Error populating \Thelia\Model\TemplateI18n object", 0, $e); + } + } + + /** + * Checks and repairs the internal consistency of the object. + * + * This method is executed after an already-instantiated object is re-hydrated + * from the database. It exists to check any foreign keys to make sure that + * the objects related to the current object are correct based on foreign key. + * + * You can override this method in the stub class, but you should always invoke + * the base method from the overridden method (i.e. parent::ensureConsistency()), + * in case your model changes. + * + * @throws PropelException + */ + public function ensureConsistency() + { + if ($this->aTemplate !== null && $this->id !== $this->aTemplate->getId()) { + $this->aTemplate = null; + } + } // ensureConsistency + + /** + * Reloads this object from datastore based on primary key and (optionally) resets all associated objects. + * + * This will only work if the object has been saved and has a valid primary key set. + * + * @param boolean $deep (optional) Whether to also de-associated any related objects. + * @param ConnectionInterface $con (optional) The ConnectionInterface connection to use. + * @return void + * @throws PropelException - if this object is deleted, unsaved or doesn't have pk match in db + */ + public function reload($deep = false, ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("Cannot reload a deleted object."); + } + + if ($this->isNew()) { + throw new PropelException("Cannot reload an unsaved object."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getReadConnection(TemplateI18nTableMap::DATABASE_NAME); + } + + // We don't need to alter the object instance pool; we're just modifying this instance + // already in the pool. + + $dataFetcher = ChildTemplateI18nQuery::create(null, $this->buildPkeyCriteria())->setFormatter(ModelCriteria::FORMAT_STATEMENT)->find($con); + $row = $dataFetcher->fetch(); + $dataFetcher->close(); + if (!$row) { + throw new PropelException('Cannot find matching row in the database to reload object values.'); + } + $this->hydrate($row, 0, true, $dataFetcher->getIndexType()); // rehydrate + + if ($deep) { // also de-associate any related objects? + + $this->aTemplate = null; + } // if (deep) + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param ConnectionInterface $con + * @return void + * @throws PropelException + * @see TemplateI18n::setDeleted() + * @see TemplateI18n::isDeleted() + */ + public function delete(ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getWriteConnection(TemplateI18nTableMap::DATABASE_NAME); + } + + $con->beginTransaction(); + try { + $deleteQuery = ChildTemplateI18nQuery::create() + ->filterByPrimaryKey($this->getPrimaryKey()); + $ret = $this->preDelete($con); + if ($ret) { + $deleteQuery->delete($con); + $this->postDelete($con); + $con->commit(); + $this->setDeleted(true); + } else { + $con->commit(); + } + } catch (Exception $e) { + $con->rollBack(); + throw $e; + } + } + + /** + * Persists this object to the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All modified related objects will also be persisted in the doSave() + * method. This method wraps all precipitate database operations in a + * single transaction. + * + * @param ConnectionInterface $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save(ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getWriteConnection(TemplateI18nTableMap::DATABASE_NAME); + } + + $con->beginTransaction(); + $isInsert = $this->isNew(); + try { + $ret = $this->preSave($con); + if ($isInsert) { + $ret = $ret && $this->preInsert($con); + } else { + $ret = $ret && $this->preUpdate($con); + } + if ($ret) { + $affectedRows = $this->doSave($con); + if ($isInsert) { + $this->postInsert($con); + } else { + $this->postUpdate($con); + } + $this->postSave($con); + TemplateI18nTableMap::addInstanceToPool($this); + } else { + $affectedRows = 0; + } + $con->commit(); + + return $affectedRows; + } catch (Exception $e) { + $con->rollBack(); + throw $e; + } + } + + /** + * Performs the work of inserting or updating the row in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param ConnectionInterface $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave(ConnectionInterface $con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + // We call the save method on the following object(s) if they + // were passed to this object by their corresponding set + // method. This object relates to these object(s) by a + // foreign key reference. + + if ($this->aTemplate !== null) { + if ($this->aTemplate->isModified() || $this->aTemplate->isNew()) { + $affectedRows += $this->aTemplate->save($con); + } + $this->setTemplate($this->aTemplate); + } + + if ($this->isNew() || $this->isModified()) { + // persist changes + if ($this->isNew()) { + $this->doInsert($con); + } else { + $this->doUpdate($con); + } + $affectedRows += 1; + $this->resetModified(); + } + + $this->alreadyInSave = false; + + } + + return $affectedRows; + } // doSave() + + /** + * Insert the row in the database. + * + * @param ConnectionInterface $con + * + * @throws PropelException + * @see doSave() + */ + protected function doInsert(ConnectionInterface $con) + { + $modifiedColumns = array(); + $index = 0; + + + // check the columns in natural order for more readable SQL queries + if ($this->isColumnModified(TemplateI18nTableMap::ID)) { + $modifiedColumns[':p' . $index++] = 'ID'; + } + if ($this->isColumnModified(TemplateI18nTableMap::LOCALE)) { + $modifiedColumns[':p' . $index++] = 'LOCALE'; + } + if ($this->isColumnModified(TemplateI18nTableMap::NAME)) { + $modifiedColumns[':p' . $index++] = 'NAME'; + } + + $sql = sprintf( + 'INSERT INTO template_i18n (%s) VALUES (%s)', + implode(', ', $modifiedColumns), + implode(', ', array_keys($modifiedColumns)) + ); + + try { + $stmt = $con->prepare($sql); + foreach ($modifiedColumns as $identifier => $columnName) { + switch ($columnName) { + case 'ID': + $stmt->bindValue($identifier, $this->id, PDO::PARAM_INT); + break; + case 'LOCALE': + $stmt->bindValue($identifier, $this->locale, PDO::PARAM_STR); + break; + case 'NAME': + $stmt->bindValue($identifier, $this->name, PDO::PARAM_STR); + break; + } + } + $stmt->execute(); + } catch (Exception $e) { + Propel::log($e->getMessage(), Propel::LOG_ERR); + throw new PropelException(sprintf('Unable to execute INSERT statement [%s]', $sql), 0, $e); + } + + $this->setNew(false); + } + + /** + * Update the row in the database. + * + * @param ConnectionInterface $con + * + * @return Integer Number of updated rows + * @see doSave() + */ + protected function doUpdate(ConnectionInterface $con) + { + $selectCriteria = $this->buildPkeyCriteria(); + $valuesCriteria = $this->buildCriteria(); + + return $selectCriteria->doUpdate($valuesCriteria, $con); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @return mixed Value of field. + */ + public function getByName($name, $type = TableMap::TYPE_PHPNAME) + { + $pos = TemplateI18nTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); + $field = $this->getByPosition($pos); + + return $field; + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch ($pos) { + case 0: + return $this->getId(); + break; + case 1: + return $this->getLocale(); + break; + case 2: + return $this->getName(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType (optional) One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME, + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to TRUE. + * @param array $alreadyDumpedObjects List of objects to skip to avoid recursion + * @param boolean $includeForeignObjects (optional) Whether to include hydrated related objects. Default to FALSE. + * + * @return array an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = TableMap::TYPE_PHPNAME, $includeLazyLoadColumns = true, $alreadyDumpedObjects = array(), $includeForeignObjects = false) + { + if (isset($alreadyDumpedObjects['TemplateI18n'][serialize($this->getPrimaryKey())])) { + return '*RECURSION*'; + } + $alreadyDumpedObjects['TemplateI18n'][serialize($this->getPrimaryKey())] = true; + $keys = TemplateI18nTableMap::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getId(), + $keys[1] => $this->getLocale(), + $keys[2] => $this->getName(), + ); + $virtualColumns = $this->virtualColumns; + foreach($virtualColumns as $key => $virtualColumn) + { + $result[$key] = $virtualColumn; + } + + if ($includeForeignObjects) { + if (null !== $this->aTemplate) { + $result['Template'] = $this->aTemplate->toArray($keyType, $includeLazyLoadColumns, $alreadyDumpedObjects, true); + } + } + + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @return void + */ + public function setByName($name, $value, $type = TableMap::TYPE_PHPNAME) + { + $pos = TemplateI18nTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); + + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch ($pos) { + case 0: + $this->setId($value); + break; + case 1: + $this->setLocale($value); + break; + case 2: + $this->setName($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME, + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * The default key type is the column's TableMap::TYPE_PHPNAME. + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = TableMap::TYPE_PHPNAME) + { + $keys = TemplateI18nTableMap::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setLocale($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setName($arr[$keys[2]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(TemplateI18nTableMap::DATABASE_NAME); + + if ($this->isColumnModified(TemplateI18nTableMap::ID)) $criteria->add(TemplateI18nTableMap::ID, $this->id); + if ($this->isColumnModified(TemplateI18nTableMap::LOCALE)) $criteria->add(TemplateI18nTableMap::LOCALE, $this->locale); + if ($this->isColumnModified(TemplateI18nTableMap::NAME)) $criteria->add(TemplateI18nTableMap::NAME, $this->name); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(TemplateI18nTableMap::DATABASE_NAME); + $criteria->add(TemplateI18nTableMap::ID, $this->id); + $criteria->add(TemplateI18nTableMap::LOCALE, $this->locale); + + return $criteria; + } + + /** + * Returns the composite primary key for this object. + * The array elements will be in same order as specified in XML. + * @return array + */ + public function getPrimaryKey() + { + $pks = array(); + $pks[0] = $this->getId(); + $pks[1] = $this->getLocale(); + + return $pks; + } + + /** + * Set the [composite] primary key. + * + * @param array $keys The elements of the composite key (order must match the order in XML file). + * @return void + */ + public function setPrimaryKey($keys) + { + $this->setId($keys[0]); + $this->setLocale($keys[1]); + } + + /** + * Returns true if the primary key for this object is null. + * @return boolean + */ + public function isPrimaryKeyNull() + { + + return (null === $this->getId()) && (null === $this->getLocale()); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of \Thelia\Model\TemplateI18n (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @param boolean $makeNew Whether to reset autoincrement PKs and make the object new. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false, $makeNew = true) + { + $copyObj->setId($this->getId()); + $copyObj->setLocale($this->getLocale()); + $copyObj->setName($this->getName()); + if ($makeNew) { + $copyObj->setNew(true); + } + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return \Thelia\Model\TemplateI18n Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + + return $copyObj; + } + + /** + * Declares an association between this object and a ChildTemplate object. + * + * @param ChildTemplate $v + * @return \Thelia\Model\TemplateI18n The current object (for fluent API support) + * @throws PropelException + */ + public function setTemplate(ChildTemplate $v = null) + { + if ($v === null) { + $this->setId(NULL); + } else { + $this->setId($v->getId()); + } + + $this->aTemplate = $v; + + // Add binding for other direction of this n:n relationship. + // If this object has already been added to the ChildTemplate object, it will not be re-added. + if ($v !== null) { + $v->addTemplateI18n($this); + } + + + return $this; + } + + + /** + * Get the associated ChildTemplate object + * + * @param ConnectionInterface $con Optional Connection object. + * @return ChildTemplate The associated ChildTemplate object. + * @throws PropelException + */ + public function getTemplate(ConnectionInterface $con = null) + { + if ($this->aTemplate === null && ($this->id !== null)) { + $this->aTemplate = ChildTemplateQuery::create()->findPk($this->id, $con); + /* The following can be used additionally to + guarantee the related object contains a reference + to this object. This level of coupling may, however, be + undesirable since it could result in an only partially populated collection + in the referenced object. + $this->aTemplate->addTemplateI18ns($this); + */ + } + + return $this->aTemplate; + } + + /** + * Clears the current object and sets all attributes to their default values + */ + public function clear() + { + $this->id = null; + $this->locale = null; + $this->name = null; + $this->alreadyInSave = false; + $this->clearAllReferences(); + $this->applyDefaultValues(); + $this->resetModified(); + $this->setNew(true); + $this->setDeleted(false); + } + + /** + * Resets all references to other model objects or collections of model objects. + * + * This method is a user-space workaround for PHP's inability to garbage collect + * objects with circular references (even in PHP 5.3). This is currently necessary + * when using Propel in certain daemon or large-volume/high-memory operations. + * + * @param boolean $deep Whether to also clear the references on all referrer objects. + */ + public function clearAllReferences($deep = false) + { + if ($deep) { + } // if ($deep) + + $this->aTemplate = null; + } + + /** + * Return the string representation of this object + * + * @return string + */ + public function __toString() + { + return (string) $this->exportTo(TemplateI18nTableMap::DEFAULT_STRING_FORMAT); + } + + /** + * Code to be run before persisting the object + * @param ConnectionInterface $con + * @return boolean + */ + public function preSave(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after persisting the object + * @param ConnectionInterface $con + */ + public function postSave(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before inserting to database + * @param ConnectionInterface $con + * @return boolean + */ + public function preInsert(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after inserting to database + * @param ConnectionInterface $con + */ + public function postInsert(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before updating the object in database + * @param ConnectionInterface $con + * @return boolean + */ + public function preUpdate(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after updating the object in database + * @param ConnectionInterface $con + */ + public function postUpdate(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before deleting the object in database + * @param ConnectionInterface $con + * @return boolean + */ + public function preDelete(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after deleting the object in database + * @param ConnectionInterface $con + */ + public function postDelete(ConnectionInterface $con = null) + { + + } + + + /** + * Derived method to catches calls to undefined methods. + * + * Provides magic import/export method support (fromXML()/toXML(), fromYAML()/toYAML(), etc.). + * Allows to define default __call() behavior if you overwrite __call() + * + * @param string $name + * @param mixed $params + * + * @return array|string + */ + public function __call($name, $params) + { + if (0 === strpos($name, 'get')) { + $virtualColumn = substr($name, 3); + if ($this->hasVirtualColumn($virtualColumn)) { + return $this->getVirtualColumn($virtualColumn); + } + + $virtualColumn = lcfirst($virtualColumn); + if ($this->hasVirtualColumn($virtualColumn)) { + return $this->getVirtualColumn($virtualColumn); + } + } + + if (0 === strpos($name, 'from')) { + $format = substr($name, 4); + + return $this->importFrom($format, reset($params)); + } + + if (0 === strpos($name, 'to')) { + $format = substr($name, 2); + $includeLazyLoadColumns = isset($params[0]) ? $params[0] : true; + + return $this->exportTo($format, $includeLazyLoadColumns); + } + + throw new BadMethodCallException(sprintf('Call to undefined method: %s.', $name)); + } + +} diff --git a/core/lib/Thelia/Model/Base/TemplateI18nQuery.php b/core/lib/Thelia/Model/Base/TemplateI18nQuery.php new file mode 100644 index 000000000..12e7b7d1f --- /dev/null +++ b/core/lib/Thelia/Model/Base/TemplateI18nQuery.php @@ -0,0 +1,508 @@ +setModelAlias($modelAlias); + } + if ($criteria instanceof Criteria) { + $query->mergeWith($criteria); + } + + return $query; + } + + /** + * Find object by primary key. + * Propel uses the instance pool to skip the database if the object exists. + * Go fast if the query is untouched. + * + * + * $obj = $c->findPk(array(12, 34), $con); + * + * + * @param array[$id, $locale] $key Primary key to use for the query + * @param ConnectionInterface $con an optional connection object + * + * @return ChildTemplateI18n|array|mixed the result, formatted by the current formatter + */ + public function findPk($key, $con = null) + { + if ($key === null) { + return null; + } + if ((null !== ($obj = TemplateI18nTableMap::getInstanceFromPool(serialize(array((string) $key[0], (string) $key[1]))))) && !$this->formatter) { + // the object is already in the instance pool + return $obj; + } + if ($con === null) { + $con = Propel::getServiceContainer()->getReadConnection(TemplateI18nTableMap::DATABASE_NAME); + } + $this->basePreSelect($con); + if ($this->formatter || $this->modelAlias || $this->with || $this->select + || $this->selectColumns || $this->asColumns || $this->selectModifiers + || $this->map || $this->having || $this->joins) { + return $this->findPkComplex($key, $con); + } else { + return $this->findPkSimple($key, $con); + } + } + + /** + * Find object by primary key using raw SQL to go fast. + * Bypass doSelect() and the object formatter by using generated code. + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con A connection object + * + * @return ChildTemplateI18n A model object, or null if the key is not found + */ + protected function findPkSimple($key, $con) + { + $sql = 'SELECT ID, LOCALE, NAME FROM template_i18n WHERE ID = :p0 AND LOCALE = :p1'; + try { + $stmt = $con->prepare($sql); + $stmt->bindValue(':p0', $key[0], PDO::PARAM_INT); + $stmt->bindValue(':p1', $key[1], PDO::PARAM_STR); + $stmt->execute(); + } catch (Exception $e) { + Propel::log($e->getMessage(), Propel::LOG_ERR); + throw new PropelException(sprintf('Unable to execute SELECT statement [%s]', $sql), 0, $e); + } + $obj = null; + if ($row = $stmt->fetch(\PDO::FETCH_NUM)) { + $obj = new ChildTemplateI18n(); + $obj->hydrate($row); + TemplateI18nTableMap::addInstanceToPool($obj, serialize(array((string) $key[0], (string) $key[1]))); + } + $stmt->closeCursor(); + + return $obj; + } + + /** + * Find object by primary key. + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con A connection object + * + * @return ChildTemplateI18n|array|mixed the result, formatted by the current formatter + */ + protected function findPkComplex($key, $con) + { + // As the query uses a PK condition, no limit(1) is necessary. + $criteria = $this->isKeepQuery() ? clone $this : $this; + $dataFetcher = $criteria + ->filterByPrimaryKey($key) + ->doSelect($con); + + return $criteria->getFormatter()->init($criteria)->formatOne($dataFetcher); + } + + /** + * Find objects by primary key + * + * $objs = $c->findPks(array(array(12, 56), array(832, 123), array(123, 456)), $con); + * + * @param array $keys Primary keys to use for the query + * @param ConnectionInterface $con an optional connection object + * + * @return ObjectCollection|array|mixed the list of results, formatted by the current formatter + */ + public function findPks($keys, $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getReadConnection($this->getDbName()); + } + $this->basePreSelect($con); + $criteria = $this->isKeepQuery() ? clone $this : $this; + $dataFetcher = $criteria + ->filterByPrimaryKeys($keys) + ->doSelect($con); + + return $criteria->getFormatter()->init($criteria)->format($dataFetcher); + } + + /** + * Filter the query by primary key + * + * @param mixed $key Primary key to use for the query + * + * @return ChildTemplateI18nQuery The current query, for fluid interface + */ + public function filterByPrimaryKey($key) + { + $this->addUsingAlias(TemplateI18nTableMap::ID, $key[0], Criteria::EQUAL); + $this->addUsingAlias(TemplateI18nTableMap::LOCALE, $key[1], Criteria::EQUAL); + + return $this; + } + + /** + * Filter the query by a list of primary keys + * + * @param array $keys The list of primary key to use for the query + * + * @return ChildTemplateI18nQuery The current query, for fluid interface + */ + public function filterByPrimaryKeys($keys) + { + if (empty($keys)) { + return $this->add(null, '1<>1', Criteria::CUSTOM); + } + foreach ($keys as $key) { + $cton0 = $this->getNewCriterion(TemplateI18nTableMap::ID, $key[0], Criteria::EQUAL); + $cton1 = $this->getNewCriterion(TemplateI18nTableMap::LOCALE, $key[1], Criteria::EQUAL); + $cton0->addAnd($cton1); + $this->addOr($cton0); + } + + return $this; + } + + /** + * Filter the query on the id column + * + * Example usage: + * + * $query->filterById(1234); // WHERE id = 1234 + * $query->filterById(array(12, 34)); // WHERE id IN (12, 34) + * $query->filterById(array('min' => 12)); // WHERE id > 12 + * + * + * @see filterByTemplate() + * + * @param mixed $id The value to use as filter. + * 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 ChildTemplateI18nQuery The current query, for fluid interface + */ + public function filterById($id = null, $comparison = null) + { + if (is_array($id)) { + $useMinMax = false; + if (isset($id['min'])) { + $this->addUsingAlias(TemplateI18nTableMap::ID, $id['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($id['max'])) { + $this->addUsingAlias(TemplateI18nTableMap::ID, $id['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(TemplateI18nTableMap::ID, $id, $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 ChildTemplateI18nQuery 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(TemplateI18nTableMap::LOCALE, $locale, $comparison); + } + + /** + * Filter the query on the name column + * + * Example usage: + * + * $query->filterByName('fooValue'); // WHERE name = 'fooValue' + * $query->filterByName('%fooValue%'); // WHERE name LIKE '%fooValue%' + * + * + * @param string $name 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 ChildTemplateI18nQuery The current query, for fluid interface + */ + public function filterByName($name = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($name)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $name)) { + $name = str_replace('*', '%', $name); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(TemplateI18nTableMap::NAME, $name, $comparison); + } + + /** + * Filter the query by a related \Thelia\Model\Template object + * + * @param \Thelia\Model\Template|ObjectCollection $template The related object(s) to use as filter + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildTemplateI18nQuery The current query, for fluid interface + */ + public function filterByTemplate($template, $comparison = null) + { + if ($template instanceof \Thelia\Model\Template) { + return $this + ->addUsingAlias(TemplateI18nTableMap::ID, $template->getId(), $comparison); + } elseif ($template instanceof ObjectCollection) { + if (null === $comparison) { + $comparison = Criteria::IN; + } + + return $this + ->addUsingAlias(TemplateI18nTableMap::ID, $template->toKeyValue('PrimaryKey', 'Id'), $comparison); + } else { + throw new PropelException('filterByTemplate() only accepts arguments of type \Thelia\Model\Template or Collection'); + } + } + + /** + * Adds a JOIN clause to the query using the Template relation + * + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return ChildTemplateI18nQuery The current query, for fluid interface + */ + public function joinTemplate($relationAlias = null, $joinType = 'LEFT JOIN') + { + $tableMap = $this->getTableMap(); + $relationMap = $tableMap->getRelation('Template'); + + // create a ModelJoin object for this join + $join = new ModelJoin(); + $join->setJoinType($joinType); + $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); + if ($previousJoin = $this->getPreviousJoin()) { + $join->setPreviousJoin($previousJoin); + } + + // add the ModelJoin to the current object + if ($relationAlias) { + $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); + $this->addJoinObject($join, $relationAlias); + } else { + $this->addJoinObject($join, 'Template'); + } + + return $this; + } + + /** + * Use the Template relation Template object + * + * @see useQuery() + * + * @param string $relationAlias optional alias for the relation, + * to be used as main alias in the secondary query + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return \Thelia\Model\TemplateQuery A secondary query class using the current class as primary query + */ + public function useTemplateQuery($relationAlias = null, $joinType = 'LEFT JOIN') + { + return $this + ->joinTemplate($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'Template', '\Thelia\Model\TemplateQuery'); + } + + /** + * Exclude object from result + * + * @param ChildTemplateI18n $templateI18n Object to remove from the list of results + * + * @return ChildTemplateI18nQuery The current query, for fluid interface + */ + public function prune($templateI18n = null) + { + if ($templateI18n) { + $this->addCond('pruneCond0', $this->getAliasedColName(TemplateI18nTableMap::ID), $templateI18n->getId(), Criteria::NOT_EQUAL); + $this->addCond('pruneCond1', $this->getAliasedColName(TemplateI18nTableMap::LOCALE), $templateI18n->getLocale(), Criteria::NOT_EQUAL); + $this->combine(array('pruneCond0', 'pruneCond1'), Criteria::LOGICAL_OR); + } + + return $this; + } + + /** + * Deletes all rows from the template_i18n table. + * + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). + */ + public function doDeleteAll(ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(TemplateI18nTableMap::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->beginTransaction(); + $affectedRows += parent::doDeleteAll($con); + // Because this db requires some delete cascade/set null emulation, we have to + // clear the cached instance *after* the emulation has happened (since + // instances get re-added by the select statement contained therein). + TemplateI18nTableMap::clearInstancePool(); + TemplateI18nTableMap::clearRelatedInstancePool(); + + $con->commit(); + } catch (PropelException $e) { + $con->rollBack(); + throw $e; + } + + return $affectedRows; + } + + /** + * Performs a DELETE on the database, given a ChildTemplateI18n or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or ChildTemplateI18n object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public function delete(ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(TemplateI18nTableMap::DATABASE_NAME); + } + + $criteria = $this; + + // Set the correct dbName + $criteria->setDbName(TemplateI18nTableMap::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->beginTransaction(); + + + TemplateI18nTableMap::removeInstanceFromPool($criteria); + + $affectedRows += ModelCriteria::delete($con); + TemplateI18nTableMap::clearRelatedInstancePool(); + $con->commit(); + + return $affectedRows; + } catch (PropelException $e) { + $con->rollBack(); + throw $e; + } + } + +} // TemplateI18nQuery diff --git a/core/lib/Thelia/Model/Base/TemplateQuery.php b/core/lib/Thelia/Model/Base/TemplateQuery.php new file mode 100644 index 000000000..506d7d943 --- /dev/null +++ b/core/lib/Thelia/Model/Base/TemplateQuery.php @@ -0,0 +1,907 @@ +setModelAlias($modelAlias); + } + if ($criteria instanceof Criteria) { + $query->mergeWith($criteria); + } + + return $query; + } + + /** + * Find object by primary key. + * Propel uses the instance pool to skip the database if the object exists. + * Go fast if the query is untouched. + * + * + * $obj = $c->findPk(12, $con); + * + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con an optional connection object + * + * @return ChildTemplate|array|mixed the result, formatted by the current formatter + */ + public function findPk($key, $con = null) + { + if ($key === null) { + return null; + } + if ((null !== ($obj = TemplateTableMap::getInstanceFromPool((string) $key))) && !$this->formatter) { + // the object is already in the instance pool + return $obj; + } + if ($con === null) { + $con = Propel::getServiceContainer()->getReadConnection(TemplateTableMap::DATABASE_NAME); + } + $this->basePreSelect($con); + if ($this->formatter || $this->modelAlias || $this->with || $this->select + || $this->selectColumns || $this->asColumns || $this->selectModifiers + || $this->map || $this->having || $this->joins) { + return $this->findPkComplex($key, $con); + } else { + return $this->findPkSimple($key, $con); + } + } + + /** + * Find object by primary key using raw SQL to go fast. + * Bypass doSelect() and the object formatter by using generated code. + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con A connection object + * + * @return ChildTemplate A model object, or null if the key is not found + */ + protected function findPkSimple($key, $con) + { + $sql = 'SELECT ID, CREATED_AT, UPDATED_AT FROM template WHERE ID = :p0'; + try { + $stmt = $con->prepare($sql); + $stmt->bindValue(':p0', $key, PDO::PARAM_INT); + $stmt->execute(); + } catch (Exception $e) { + Propel::log($e->getMessage(), Propel::LOG_ERR); + throw new PropelException(sprintf('Unable to execute SELECT statement [%s]', $sql), 0, $e); + } + $obj = null; + if ($row = $stmt->fetch(\PDO::FETCH_NUM)) { + $obj = new ChildTemplate(); + $obj->hydrate($row); + TemplateTableMap::addInstanceToPool($obj, (string) $key); + } + $stmt->closeCursor(); + + return $obj; + } + + /** + * Find object by primary key. + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con A connection object + * + * @return ChildTemplate|array|mixed the result, formatted by the current formatter + */ + protected function findPkComplex($key, $con) + { + // As the query uses a PK condition, no limit(1) is necessary. + $criteria = $this->isKeepQuery() ? clone $this : $this; + $dataFetcher = $criteria + ->filterByPrimaryKey($key) + ->doSelect($con); + + return $criteria->getFormatter()->init($criteria)->formatOne($dataFetcher); + } + + /** + * Find objects by primary key + * + * $objs = $c->findPks(array(12, 56, 832), $con); + * + * @param array $keys Primary keys to use for the query + * @param ConnectionInterface $con an optional connection object + * + * @return ObjectCollection|array|mixed the list of results, formatted by the current formatter + */ + public function findPks($keys, $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getReadConnection($this->getDbName()); + } + $this->basePreSelect($con); + $criteria = $this->isKeepQuery() ? clone $this : $this; + $dataFetcher = $criteria + ->filterByPrimaryKeys($keys) + ->doSelect($con); + + return $criteria->getFormatter()->init($criteria)->format($dataFetcher); + } + + /** + * Filter the query by primary key + * + * @param mixed $key Primary key to use for the query + * + * @return ChildTemplateQuery The current query, for fluid interface + */ + public function filterByPrimaryKey($key) + { + + return $this->addUsingAlias(TemplateTableMap::ID, $key, Criteria::EQUAL); + } + + /** + * Filter the query by a list of primary keys + * + * @param array $keys The list of primary key to use for the query + * + * @return ChildTemplateQuery The current query, for fluid interface + */ + public function filterByPrimaryKeys($keys) + { + + return $this->addUsingAlias(TemplateTableMap::ID, $keys, Criteria::IN); + } + + /** + * Filter the query on the id column + * + * Example usage: + * + * $query->filterById(1234); // WHERE id = 1234 + * $query->filterById(array(12, 34)); // WHERE id IN (12, 34) + * $query->filterById(array('min' => 12)); // WHERE id > 12 + * + * + * @param mixed $id The value to use as filter. + * 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 ChildTemplateQuery The current query, for fluid interface + */ + public function filterById($id = null, $comparison = null) + { + if (is_array($id)) { + $useMinMax = false; + if (isset($id['min'])) { + $this->addUsingAlias(TemplateTableMap::ID, $id['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($id['max'])) { + $this->addUsingAlias(TemplateTableMap::ID, $id['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(TemplateTableMap::ID, $id, $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 ChildTemplateQuery 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(TemplateTableMap::CREATED_AT, $createdAt['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($createdAt['max'])) { + $this->addUsingAlias(TemplateTableMap::CREATED_AT, $createdAt['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(TemplateTableMap::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 ChildTemplateQuery 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(TemplateTableMap::UPDATED_AT, $updatedAt['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($updatedAt['max'])) { + $this->addUsingAlias(TemplateTableMap::UPDATED_AT, $updatedAt['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(TemplateTableMap::UPDATED_AT, $updatedAt, $comparison); + } + + /** + * Filter the query by a related \Thelia\Model\Product object + * + * @param \Thelia\Model\Product|ObjectCollection $product the related object to use as filter + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildTemplateQuery The current query, for fluid interface + */ + public function filterByProduct($product, $comparison = null) + { + if ($product instanceof \Thelia\Model\Product) { + return $this + ->addUsingAlias(TemplateTableMap::ID, $product->getTemplateId(), $comparison); + } elseif ($product instanceof ObjectCollection) { + return $this + ->useProductQuery() + ->filterByPrimaryKeys($product->getPrimaryKeys()) + ->endUse(); + } else { + throw new PropelException('filterByProduct() only accepts arguments of type \Thelia\Model\Product or Collection'); + } + } + + /** + * Adds a JOIN clause to the query using the Product relation + * + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return ChildTemplateQuery The current query, for fluid interface + */ + public function joinProduct($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + $tableMap = $this->getTableMap(); + $relationMap = $tableMap->getRelation('Product'); + + // create a ModelJoin object for this join + $join = new ModelJoin(); + $join->setJoinType($joinType); + $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); + if ($previousJoin = $this->getPreviousJoin()) { + $join->setPreviousJoin($previousJoin); + } + + // add the ModelJoin to the current object + if ($relationAlias) { + $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); + $this->addJoinObject($join, $relationAlias); + } else { + $this->addJoinObject($join, 'Product'); + } + + return $this; + } + + /** + * Use the Product relation Product object + * + * @see useQuery() + * + * @param string $relationAlias optional alias for the relation, + * to be used as main alias in the secondary query + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return \Thelia\Model\ProductQuery A secondary query class using the current class as primary query + */ + public function useProductQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + return $this + ->joinProduct($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'Product', '\Thelia\Model\ProductQuery'); + } + + /** + * Filter the query by a related \Thelia\Model\FeatureTemplate object + * + * @param \Thelia\Model\FeatureTemplate|ObjectCollection $featureTemplate the related object to use as filter + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildTemplateQuery The current query, for fluid interface + */ + public function filterByFeatureTemplate($featureTemplate, $comparison = null) + { + if ($featureTemplate instanceof \Thelia\Model\FeatureTemplate) { + return $this + ->addUsingAlias(TemplateTableMap::ID, $featureTemplate->getTemplateId(), $comparison); + } elseif ($featureTemplate instanceof ObjectCollection) { + return $this + ->useFeatureTemplateQuery() + ->filterByPrimaryKeys($featureTemplate->getPrimaryKeys()) + ->endUse(); + } else { + throw new PropelException('filterByFeatureTemplate() only accepts arguments of type \Thelia\Model\FeatureTemplate or Collection'); + } + } + + /** + * Adds a JOIN clause to the query using the FeatureTemplate relation + * + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return ChildTemplateQuery The current query, for fluid interface + */ + public function joinFeatureTemplate($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + $tableMap = $this->getTableMap(); + $relationMap = $tableMap->getRelation('FeatureTemplate'); + + // create a ModelJoin object for this join + $join = new ModelJoin(); + $join->setJoinType($joinType); + $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); + if ($previousJoin = $this->getPreviousJoin()) { + $join->setPreviousJoin($previousJoin); + } + + // add the ModelJoin to the current object + if ($relationAlias) { + $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); + $this->addJoinObject($join, $relationAlias); + } else { + $this->addJoinObject($join, 'FeatureTemplate'); + } + + return $this; + } + + /** + * Use the FeatureTemplate relation FeatureTemplate object + * + * @see useQuery() + * + * @param string $relationAlias optional alias for the relation, + * to be used as main alias in the secondary query + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return \Thelia\Model\FeatureTemplateQuery A secondary query class using the current class as primary query + */ + public function useFeatureTemplateQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + return $this + ->joinFeatureTemplate($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'FeatureTemplate', '\Thelia\Model\FeatureTemplateQuery'); + } + + /** + * Filter the query by a related \Thelia\Model\AttributeTemplate object + * + * @param \Thelia\Model\AttributeTemplate|ObjectCollection $attributeTemplate the related object to use as filter + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildTemplateQuery The current query, for fluid interface + */ + public function filterByAttributeTemplate($attributeTemplate, $comparison = null) + { + if ($attributeTemplate instanceof \Thelia\Model\AttributeTemplate) { + return $this + ->addUsingAlias(TemplateTableMap::ID, $attributeTemplate->getTemplateId(), $comparison); + } elseif ($attributeTemplate instanceof ObjectCollection) { + return $this + ->useAttributeTemplateQuery() + ->filterByPrimaryKeys($attributeTemplate->getPrimaryKeys()) + ->endUse(); + } else { + throw new PropelException('filterByAttributeTemplate() only accepts arguments of type \Thelia\Model\AttributeTemplate or Collection'); + } + } + + /** + * Adds a JOIN clause to the query using the AttributeTemplate relation + * + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return ChildTemplateQuery The current query, for fluid interface + */ + public function joinAttributeTemplate($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + $tableMap = $this->getTableMap(); + $relationMap = $tableMap->getRelation('AttributeTemplate'); + + // create a ModelJoin object for this join + $join = new ModelJoin(); + $join->setJoinType($joinType); + $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); + if ($previousJoin = $this->getPreviousJoin()) { + $join->setPreviousJoin($previousJoin); + } + + // add the ModelJoin to the current object + if ($relationAlias) { + $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); + $this->addJoinObject($join, $relationAlias); + } else { + $this->addJoinObject($join, 'AttributeTemplate'); + } + + return $this; + } + + /** + * Use the AttributeTemplate relation AttributeTemplate object + * + * @see useQuery() + * + * @param string $relationAlias optional alias for the relation, + * to be used as main alias in the secondary query + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return \Thelia\Model\AttributeTemplateQuery A secondary query class using the current class as primary query + */ + public function useAttributeTemplateQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + return $this + ->joinAttributeTemplate($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'AttributeTemplate', '\Thelia\Model\AttributeTemplateQuery'); + } + + /** + * Filter the query by a related \Thelia\Model\TemplateI18n object + * + * @param \Thelia\Model\TemplateI18n|ObjectCollection $templateI18n the related object to use as filter + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildTemplateQuery The current query, for fluid interface + */ + public function filterByTemplateI18n($templateI18n, $comparison = null) + { + if ($templateI18n instanceof \Thelia\Model\TemplateI18n) { + return $this + ->addUsingAlias(TemplateTableMap::ID, $templateI18n->getId(), $comparison); + } elseif ($templateI18n instanceof ObjectCollection) { + return $this + ->useTemplateI18nQuery() + ->filterByPrimaryKeys($templateI18n->getPrimaryKeys()) + ->endUse(); + } else { + throw new PropelException('filterByTemplateI18n() only accepts arguments of type \Thelia\Model\TemplateI18n or Collection'); + } + } + + /** + * Adds a JOIN clause to the query using the TemplateI18n relation + * + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return ChildTemplateQuery The current query, for fluid interface + */ + public function joinTemplateI18n($relationAlias = null, $joinType = 'LEFT JOIN') + { + $tableMap = $this->getTableMap(); + $relationMap = $tableMap->getRelation('TemplateI18n'); + + // create a ModelJoin object for this join + $join = new ModelJoin(); + $join->setJoinType($joinType); + $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); + if ($previousJoin = $this->getPreviousJoin()) { + $join->setPreviousJoin($previousJoin); + } + + // add the ModelJoin to the current object + if ($relationAlias) { + $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); + $this->addJoinObject($join, $relationAlias); + } else { + $this->addJoinObject($join, 'TemplateI18n'); + } + + return $this; + } + + /** + * Use the TemplateI18n relation TemplateI18n object + * + * @see useQuery() + * + * @param string $relationAlias optional alias for the relation, + * to be used as main alias in the secondary query + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return \Thelia\Model\TemplateI18nQuery A secondary query class using the current class as primary query + */ + public function useTemplateI18nQuery($relationAlias = null, $joinType = 'LEFT JOIN') + { + return $this + ->joinTemplateI18n($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'TemplateI18n', '\Thelia\Model\TemplateI18nQuery'); + } + + /** + * Filter the query by a related Feature object + * using the feature_template table as cross reference + * + * @param Feature $feature the related object to use as filter + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildTemplateQuery The current query, for fluid interface + */ + public function filterByFeature($feature, $comparison = Criteria::EQUAL) + { + return $this + ->useFeatureTemplateQuery() + ->filterByFeature($feature, $comparison) + ->endUse(); + } + + /** + * Filter the query by a related Attribute object + * using the attribute_template table as cross reference + * + * @param Attribute $attribute the related object to use as filter + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildTemplateQuery The current query, for fluid interface + */ + public function filterByAttribute($attribute, $comparison = Criteria::EQUAL) + { + return $this + ->useAttributeTemplateQuery() + ->filterByAttribute($attribute, $comparison) + ->endUse(); + } + + /** + * Exclude object from result + * + * @param ChildTemplate $template Object to remove from the list of results + * + * @return ChildTemplateQuery The current query, for fluid interface + */ + public function prune($template = null) + { + if ($template) { + $this->addUsingAlias(TemplateTableMap::ID, $template->getId(), Criteria::NOT_EQUAL); + } + + return $this; + } + + /** + * Deletes all rows from the template table. + * + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). + */ + public function doDeleteAll(ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(TemplateTableMap::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->beginTransaction(); + $affectedRows += parent::doDeleteAll($con); + // Because this db requires some delete cascade/set null emulation, we have to + // clear the cached instance *after* the emulation has happened (since + // instances get re-added by the select statement contained therein). + TemplateTableMap::clearInstancePool(); + TemplateTableMap::clearRelatedInstancePool(); + + $con->commit(); + } catch (PropelException $e) { + $con->rollBack(); + throw $e; + } + + return $affectedRows; + } + + /** + * Performs a DELETE on the database, given a ChildTemplate or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or ChildTemplate object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public function delete(ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(TemplateTableMap::DATABASE_NAME); + } + + $criteria = $this; + + // Set the correct dbName + $criteria->setDbName(TemplateTableMap::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->beginTransaction(); + + + TemplateTableMap::removeInstanceFromPool($criteria); + + $affectedRows += ModelCriteria::delete($con); + TemplateTableMap::clearRelatedInstancePool(); + $con->commit(); + + return $affectedRows; + } catch (PropelException $e) { + $con->rollBack(); + throw $e; + } + } + + // i18n behavior + + /** + * Adds a JOIN clause to the query using the i18n relation + * + * @param string $locale Locale to use for the join condition, e.g. 'fr_FR' + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join'. Defaults to left join. + * + * @return ChildTemplateQuery The current query, for fluid interface + */ + public function joinI18n($locale = 'en_US', $relationAlias = null, $joinType = Criteria::LEFT_JOIN) + { + $relationName = $relationAlias ? $relationAlias : 'TemplateI18n'; + + return $this + ->joinTemplateI18n($relationAlias, $joinType) + ->addJoinCondition($relationName, $relationName . '.Locale = ?', $locale); + } + + /** + * Adds a JOIN clause to the query and hydrates the related I18n object. + * Shortcut for $c->joinI18n($locale)->with() + * + * @param string $locale Locale to use for the join condition, e.g. 'fr_FR' + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join'. Defaults to left join. + * + * @return ChildTemplateQuery The current query, for fluid interface + */ + public function joinWithI18n($locale = 'en_US', $joinType = Criteria::LEFT_JOIN) + { + $this + ->joinI18n($locale, null, $joinType) + ->with('TemplateI18n'); + $this->with['TemplateI18n']->setIsWithOneToMany(false); + + return $this; + } + + /** + * Use the I18n relation query object + * + * @see useQuery() + * + * @param string $locale Locale to use for the join condition, e.g. 'fr_FR' + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join'. Defaults to left join. + * + * @return ChildTemplateI18nQuery A secondary query class using the current class as primary query + */ + public function useI18nQuery($locale = 'en_US', $relationAlias = null, $joinType = Criteria::LEFT_JOIN) + { + return $this + ->joinI18n($locale, $relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'TemplateI18n', '\Thelia\Model\TemplateI18nQuery'); + } + + // timestampable behavior + + /** + * Filter by the latest updated + * + * @param int $nbDays Maximum age of the latest update in days + * + * @return ChildTemplateQuery The current query, for fluid interface + */ + public function recentlyUpdated($nbDays = 7) + { + return $this->addUsingAlias(TemplateTableMap::UPDATED_AT, time() - $nbDays * 24 * 60 * 60, Criteria::GREATER_EQUAL); + } + + /** + * Filter by the latest created + * + * @param int $nbDays Maximum age of in days + * + * @return ChildTemplateQuery The current query, for fluid interface + */ + public function recentlyCreated($nbDays = 7) + { + return $this->addUsingAlias(TemplateTableMap::CREATED_AT, time() - $nbDays * 24 * 60 * 60, Criteria::GREATER_EQUAL); + } + + /** + * Order by update date desc + * + * @return ChildTemplateQuery The current query, for fluid interface + */ + public function lastUpdatedFirst() + { + return $this->addDescendingOrderByColumn(TemplateTableMap::UPDATED_AT); + } + + /** + * Order by update date asc + * + * @return ChildTemplateQuery The current query, for fluid interface + */ + public function firstUpdatedFirst() + { + return $this->addAscendingOrderByColumn(TemplateTableMap::UPDATED_AT); + } + + /** + * Order by create date desc + * + * @return ChildTemplateQuery The current query, for fluid interface + */ + public function lastCreatedFirst() + { + return $this->addDescendingOrderByColumn(TemplateTableMap::CREATED_AT); + } + + /** + * Order by create date asc + * + * @return ChildTemplateQuery The current query, for fluid interface + */ + public function firstCreatedFirst() + { + return $this->addAscendingOrderByColumn(TemplateTableMap::CREATED_AT); + } + +} // TemplateQuery diff --git a/core/lib/Thelia/Model/Customer.php b/core/lib/Thelia/Model/Customer.php index f839d5f5b..820928224 100755 --- a/core/lib/Thelia/Model/Customer.php +++ b/core/lib/Thelia/Model/Customer.php @@ -205,11 +205,42 @@ class Customer extends BaseCustomer implements UserInterface return array(new Role('CUSTOMER')); } + /** + * {@inheritDoc} + */ + public function getToken() { + return $this->getRememberMeToken(); + } + + /** + * {@inheritDoc} + */ + public function setToken($token) { + $this->setRememberMeToken($token)->save(); + } + + /** + * {@inheritDoc} + */ + public function getSerial() { + return $this->getRememberMeSerial(); + } + + /** + * {@inheritDoc} + */ + public function setSerial($serial) { + $this->setRememberMeSerial($serial)->save(); + } + /** * {@inheritDoc} */ public function preInsert(ConnectionInterface $con = null) { + // Set the serial number (for auto-login) + $this->setRememberMeSerial(uniqid()); + $this->setRef($this->generateRef()); $this->dispatchEvent(TheliaEvents::BEFORE_CREATECUSTOMER, new CustomerEvent($this)); diff --git a/core/lib/Thelia/Model/FeatureTemplate.php b/core/lib/Thelia/Model/FeatureTemplate.php new file mode 100644 index 000000000..47a33027a --- /dev/null +++ b/core/lib/Thelia/Model/FeatureTemplate.php @@ -0,0 +1,10 @@ + array('Id', 'Firstname', 'Lastname', 'Login', 'Password', 'Algo', 'Salt', 'CreatedAt', 'UpdatedAt', ), - self::TYPE_STUDLYPHPNAME => array('id', 'firstname', 'lastname', 'login', 'password', 'algo', 'salt', 'createdAt', 'updatedAt', ), - self::TYPE_COLNAME => array(AdminTableMap::ID, AdminTableMap::FIRSTNAME, AdminTableMap::LASTNAME, AdminTableMap::LOGIN, AdminTableMap::PASSWORD, AdminTableMap::ALGO, AdminTableMap::SALT, AdminTableMap::CREATED_AT, AdminTableMap::UPDATED_AT, ), - self::TYPE_RAW_COLNAME => array('ID', 'FIRSTNAME', 'LASTNAME', 'LOGIN', 'PASSWORD', 'ALGO', 'SALT', 'CREATED_AT', 'UPDATED_AT', ), - self::TYPE_FIELDNAME => array('id', 'firstname', 'lastname', 'login', 'password', 'algo', 'salt', 'created_at', 'updated_at', ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, ) + self::TYPE_PHPNAME => array('Id', 'Firstname', 'Lastname', 'Login', 'Password', 'Algo', 'Salt', 'RememberMeToken', 'RememberMeSerial', 'CreatedAt', 'UpdatedAt', ), + self::TYPE_STUDLYPHPNAME => array('id', 'firstname', 'lastname', 'login', 'password', 'algo', 'salt', 'rememberMeToken', 'rememberMeSerial', 'createdAt', 'updatedAt', ), + self::TYPE_COLNAME => array(AdminTableMap::ID, AdminTableMap::FIRSTNAME, AdminTableMap::LASTNAME, AdminTableMap::LOGIN, AdminTableMap::PASSWORD, AdminTableMap::ALGO, AdminTableMap::SALT, AdminTableMap::REMEMBER_ME_TOKEN, AdminTableMap::REMEMBER_ME_SERIAL, AdminTableMap::CREATED_AT, AdminTableMap::UPDATED_AT, ), + self::TYPE_RAW_COLNAME => array('ID', 'FIRSTNAME', 'LASTNAME', 'LOGIN', 'PASSWORD', 'ALGO', 'SALT', 'REMEMBER_ME_TOKEN', 'REMEMBER_ME_SERIAL', 'CREATED_AT', 'UPDATED_AT', ), + self::TYPE_FIELDNAME => array('id', 'firstname', 'lastname', 'login', 'password', 'algo', 'salt', 'remember_me_token', 'remember_me_serial', 'created_at', 'updated_at', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ) ); /** @@ -141,12 +151,12 @@ class AdminTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'Firstname' => 1, 'Lastname' => 2, 'Login' => 3, 'Password' => 4, 'Algo' => 5, 'Salt' => 6, 'CreatedAt' => 7, 'UpdatedAt' => 8, ), - self::TYPE_STUDLYPHPNAME => array('id' => 0, 'firstname' => 1, 'lastname' => 2, 'login' => 3, 'password' => 4, 'algo' => 5, 'salt' => 6, 'createdAt' => 7, 'updatedAt' => 8, ), - self::TYPE_COLNAME => array(AdminTableMap::ID => 0, AdminTableMap::FIRSTNAME => 1, AdminTableMap::LASTNAME => 2, AdminTableMap::LOGIN => 3, AdminTableMap::PASSWORD => 4, AdminTableMap::ALGO => 5, AdminTableMap::SALT => 6, AdminTableMap::CREATED_AT => 7, AdminTableMap::UPDATED_AT => 8, ), - self::TYPE_RAW_COLNAME => array('ID' => 0, 'FIRSTNAME' => 1, 'LASTNAME' => 2, 'LOGIN' => 3, 'PASSWORD' => 4, 'ALGO' => 5, 'SALT' => 6, 'CREATED_AT' => 7, 'UPDATED_AT' => 8, ), - self::TYPE_FIELDNAME => array('id' => 0, 'firstname' => 1, 'lastname' => 2, 'login' => 3, 'password' => 4, 'algo' => 5, 'salt' => 6, 'created_at' => 7, 'updated_at' => 8, ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, ) + self::TYPE_PHPNAME => array('Id' => 0, 'Firstname' => 1, 'Lastname' => 2, 'Login' => 3, 'Password' => 4, 'Algo' => 5, 'Salt' => 6, 'RememberMeToken' => 7, 'RememberMeSerial' => 8, 'CreatedAt' => 9, 'UpdatedAt' => 10, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'firstname' => 1, 'lastname' => 2, 'login' => 3, 'password' => 4, 'algo' => 5, 'salt' => 6, 'rememberMeToken' => 7, 'rememberMeSerial' => 8, 'createdAt' => 9, 'updatedAt' => 10, ), + self::TYPE_COLNAME => array(AdminTableMap::ID => 0, AdminTableMap::FIRSTNAME => 1, AdminTableMap::LASTNAME => 2, AdminTableMap::LOGIN => 3, AdminTableMap::PASSWORD => 4, AdminTableMap::ALGO => 5, AdminTableMap::SALT => 6, AdminTableMap::REMEMBER_ME_TOKEN => 7, AdminTableMap::REMEMBER_ME_SERIAL => 8, AdminTableMap::CREATED_AT => 9, AdminTableMap::UPDATED_AT => 10, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'FIRSTNAME' => 1, 'LASTNAME' => 2, 'LOGIN' => 3, 'PASSWORD' => 4, 'ALGO' => 5, 'SALT' => 6, 'REMEMBER_ME_TOKEN' => 7, 'REMEMBER_ME_SERIAL' => 8, 'CREATED_AT' => 9, 'UPDATED_AT' => 10, ), + self::TYPE_FIELDNAME => array('id' => 0, 'firstname' => 1, 'lastname' => 2, 'login' => 3, 'password' => 4, 'algo' => 5, 'salt' => 6, 'remember_me_token' => 7, 'remember_me_serial' => 8, 'created_at' => 9, 'updated_at' => 10, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ) ); /** @@ -172,6 +182,8 @@ class AdminTableMap extends TableMap $this->addColumn('PASSWORD', 'Password', 'VARCHAR', true, 128, null); $this->addColumn('ALGO', 'Algo', 'VARCHAR', false, 128, null); $this->addColumn('SALT', 'Salt', 'VARCHAR', false, 128, null); + $this->addColumn('REMEMBER_ME_TOKEN', 'RememberMeToken', 'VARCHAR', false, 255, null); + $this->addColumn('REMEMBER_ME_SERIAL', 'RememberMeSerial', 'VARCHAR', false, 255, null); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); } // initialize() @@ -352,6 +364,8 @@ class AdminTableMap extends TableMap $criteria->addSelectColumn(AdminTableMap::PASSWORD); $criteria->addSelectColumn(AdminTableMap::ALGO); $criteria->addSelectColumn(AdminTableMap::SALT); + $criteria->addSelectColumn(AdminTableMap::REMEMBER_ME_TOKEN); + $criteria->addSelectColumn(AdminTableMap::REMEMBER_ME_SERIAL); $criteria->addSelectColumn(AdminTableMap::CREATED_AT); $criteria->addSelectColumn(AdminTableMap::UPDATED_AT); } else { @@ -362,6 +376,8 @@ class AdminTableMap extends TableMap $criteria->addSelectColumn($alias . '.PASSWORD'); $criteria->addSelectColumn($alias . '.ALGO'); $criteria->addSelectColumn($alias . '.SALT'); + $criteria->addSelectColumn($alias . '.REMEMBER_ME_TOKEN'); + $criteria->addSelectColumn($alias . '.REMEMBER_ME_SERIAL'); $criteria->addSelectColumn($alias . '.CREATED_AT'); $criteria->addSelectColumn($alias . '.UPDATED_AT'); } diff --git a/core/lib/Thelia/Model/Map/AttributeTableMap.php b/core/lib/Thelia/Model/Map/AttributeTableMap.php index 773e13cab..245dc08d3 100644 --- a/core/lib/Thelia/Model/Map/AttributeTableMap.php +++ b/core/lib/Thelia/Model/Map/AttributeTableMap.php @@ -162,9 +162,9 @@ class AttributeTableMap extends TableMap { $this->addRelation('AttributeAv', '\\Thelia\\Model\\AttributeAv', RelationMap::ONE_TO_MANY, array('id' => 'attribute_id', ), 'CASCADE', 'RESTRICT', 'AttributeAvs'); $this->addRelation('AttributeCombination', '\\Thelia\\Model\\AttributeCombination', RelationMap::ONE_TO_MANY, array('id' => 'attribute_id', ), 'CASCADE', 'RESTRICT', 'AttributeCombinations'); - $this->addRelation('AttributeCategory', '\\Thelia\\Model\\AttributeCategory', RelationMap::ONE_TO_MANY, array('id' => 'attribute_id', ), 'CASCADE', 'RESTRICT', 'AttributeCategories'); + $this->addRelation('AttributeTemplate', '\\Thelia\\Model\\AttributeTemplate', RelationMap::ONE_TO_MANY, array('id' => 'attribute_id', ), 'CASCADE', 'RESTRICT', 'AttributeTemplates'); $this->addRelation('AttributeI18n', '\\Thelia\\Model\\AttributeI18n', RelationMap::ONE_TO_MANY, array('id' => 'id', ), 'CASCADE', null, 'AttributeI18ns'); - $this->addRelation('Category', '\\Thelia\\Model\\Category', RelationMap::MANY_TO_MANY, array(), 'CASCADE', 'RESTRICT', 'Categories'); + $this->addRelation('Template', '\\Thelia\\Model\\Template', RelationMap::MANY_TO_MANY, array(), null, null, 'Templates'); } // buildRelations() /** @@ -189,7 +189,7 @@ class AttributeTableMap extends TableMap // since one or more of them may be deleted by ON DELETE CASCADE/SETNULL rule. AttributeAvTableMap::clearInstancePool(); AttributeCombinationTableMap::clearInstancePool(); - AttributeCategoryTableMap::clearInstancePool(); + AttributeTemplateTableMap::clearInstancePool(); AttributeI18nTableMap::clearInstancePool(); } diff --git a/core/lib/Thelia/Model/Map/AttributeTemplateTableMap.php b/core/lib/Thelia/Model/Map/AttributeTemplateTableMap.php new file mode 100644 index 000000000..04d3a9a4a --- /dev/null +++ b/core/lib/Thelia/Model/Map/AttributeTemplateTableMap.php @@ -0,0 +1,449 @@ + array('Id', 'AttributeId', 'TemplateId', 'CreatedAt', 'UpdatedAt', ), + self::TYPE_STUDLYPHPNAME => array('id', 'attributeId', 'templateId', 'createdAt', 'updatedAt', ), + self::TYPE_COLNAME => array(AttributeTemplateTableMap::ID, AttributeTemplateTableMap::ATTRIBUTE_ID, AttributeTemplateTableMap::TEMPLATE_ID, AttributeTemplateTableMap::CREATED_AT, AttributeTemplateTableMap::UPDATED_AT, ), + self::TYPE_RAW_COLNAME => array('ID', 'ATTRIBUTE_ID', 'TEMPLATE_ID', 'CREATED_AT', 'UPDATED_AT', ), + self::TYPE_FIELDNAME => array('id', 'attribute_id', 'template_id', 'created_at', 'updated_at', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 + */ + protected static $fieldKeys = array ( + self::TYPE_PHPNAME => array('Id' => 0, 'AttributeId' => 1, 'TemplateId' => 2, 'CreatedAt' => 3, 'UpdatedAt' => 4, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'attributeId' => 1, 'templateId' => 2, 'createdAt' => 3, 'updatedAt' => 4, ), + self::TYPE_COLNAME => array(AttributeTemplateTableMap::ID => 0, AttributeTemplateTableMap::ATTRIBUTE_ID => 1, AttributeTemplateTableMap::TEMPLATE_ID => 2, AttributeTemplateTableMap::CREATED_AT => 3, AttributeTemplateTableMap::UPDATED_AT => 4, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'ATTRIBUTE_ID' => 1, 'TEMPLATE_ID' => 2, 'CREATED_AT' => 3, 'UPDATED_AT' => 4, ), + self::TYPE_FIELDNAME => array('id' => 0, 'attribute_id' => 1, 'template_id' => 2, 'created_at' => 3, 'updated_at' => 4, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, ) + ); + + /** + * Initialize the table attributes and columns + * Relations are not initialized by this method since they are lazy loaded + * + * @return void + * @throws PropelException + */ + public function initialize() + { + // attributes + $this->setName('attribute_template'); + $this->setPhpName('AttributeTemplate'); + $this->setClassName('\\Thelia\\Model\\AttributeTemplate'); + $this->setPackage('Thelia.Model'); + $this->setUseIdGenerator(true); + $this->setIsCrossRef(true); + // columns + $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); + $this->addForeignKey('ATTRIBUTE_ID', 'AttributeId', 'INTEGER', 'attribute', 'ID', true, null, null); + $this->addForeignKey('TEMPLATE_ID', 'TemplateId', 'INTEGER', 'template', 'ID', true, null, null); + $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); + $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); + } // initialize() + + /** + * Build the RelationMap objects for this table relationships + */ + public function buildRelations() + { + $this->addRelation('Attribute', '\\Thelia\\Model\\Attribute', RelationMap::MANY_TO_ONE, array('attribute_id' => 'id', ), 'CASCADE', 'RESTRICT'); + $this->addRelation('Template', '\\Thelia\\Model\\Template', RelationMap::MANY_TO_ONE, array('template_id' => 'id', ), null, null); + } // 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. + * + * For tables with a single-column primary key, that simple pkey value will be returned. For tables with + * a multi-column primary key, a serialize()d version of the primary key will be returned. + * + * @param array $row resultset row. + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM + */ + public static function getPrimaryKeyHashFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + // If the PK cannot be derived from the row, return NULL. + if ($row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)] === null) { + return null; + } + + return (string) $row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)]; + } + + /** + * Retrieves the primary key from the DB resultset row + * For tables with a single-column primary key, that simple pkey value will be returned. For tables with + * a multi-column primary key, an array of the primary key columns will be returned. + * + * @param array $row resultset row. + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM + * + * @return mixed The primary key of the row + */ + public static function getPrimaryKeyFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + + return (int) $row[ + $indexType == TableMap::TYPE_NUM + ? 0 + $offset + : self::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType) + ]; + } + + /** + * The class that the tableMap will make instances of. + * + * If $withPrefix is true, the returned path + * uses a dot-path notation which is translated into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @param boolean $withPrefix Whether or not to return the path with the class name + * @return string path.to.ClassName + */ + public static function getOMClass($withPrefix = true) + { + return $withPrefix ? AttributeTemplateTableMap::CLASS_DEFAULT : AttributeTemplateTableMap::OM_CLASS; + } + + /** + * Populates an object of the default type or an object that inherit from the default. + * + * @param array $row row returned by DataFetcher->fetch(). + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType The index type of $row. Mostly DataFetcher->getIndexType(). + One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return array (AttributeTemplate object, last column rank) + */ + public static function populateObject($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + $key = AttributeTemplateTableMap::getPrimaryKeyHashFromRow($row, $offset, $indexType); + if (null !== ($obj = AttributeTemplateTableMap::getInstanceFromPool($key))) { + // We no longer rehydrate the object, since this can cause data loss. + // See http://www.propelorm.org/ticket/509 + // $obj->hydrate($row, $offset, true); // rehydrate + $col = $offset + AttributeTemplateTableMap::NUM_HYDRATE_COLUMNS; + } else { + $cls = AttributeTemplateTableMap::OM_CLASS; + $obj = new $cls(); + $col = $obj->hydrate($row, $offset, false, $indexType); + AttributeTemplateTableMap::addInstanceToPool($obj, $key); + } + + return array($obj, $col); + } + + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @param DataFetcherInterface $dataFetcher + * @return array + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(DataFetcherInterface $dataFetcher) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = static::getOMClass(false); + // populate the object(s) + while ($row = $dataFetcher->fetch()) { + $key = AttributeTemplateTableMap::getPrimaryKeyHashFromRow($row, 0, $dataFetcher->getIndexType()); + if (null !== ($obj = AttributeTemplateTableMap::getInstanceFromPool($key))) { + // We no longer rehydrate the object, since this can cause data loss. + // See http://www.propelorm.org/ticket/509 + // $obj->hydrate($row, 0, true); // rehydrate + $results[] = $obj; + } else { + $obj = new $cls(); + $obj->hydrate($row); + $results[] = $obj; + AttributeTemplateTableMap::addInstanceToPool($obj, $key); + } // if key exists + } + + return $results; + } + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param Criteria $criteria object containing the columns to add. + * @param string $alias optional table alias + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria, $alias = null) + { + if (null === $alias) { + $criteria->addSelectColumn(AttributeTemplateTableMap::ID); + $criteria->addSelectColumn(AttributeTemplateTableMap::ATTRIBUTE_ID); + $criteria->addSelectColumn(AttributeTemplateTableMap::TEMPLATE_ID); + $criteria->addSelectColumn(AttributeTemplateTableMap::CREATED_AT); + $criteria->addSelectColumn(AttributeTemplateTableMap::UPDATED_AT); + } else { + $criteria->addSelectColumn($alias . '.ID'); + $criteria->addSelectColumn($alias . '.ATTRIBUTE_ID'); + $criteria->addSelectColumn($alias . '.TEMPLATE_ID'); + $criteria->addSelectColumn($alias . '.CREATED_AT'); + $criteria->addSelectColumn($alias . '.UPDATED_AT'); + } + } + + /** + * Returns the TableMap related to this object. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getServiceContainer()->getDatabaseMap(AttributeTemplateTableMap::DATABASE_NAME)->getTable(AttributeTemplateTableMap::TABLE_NAME); + } + + /** + * Add a TableMap instance to the database for this tableMap class. + */ + public static function buildTableMap() + { + $dbMap = Propel::getServiceContainer()->getDatabaseMap(AttributeTemplateTableMap::DATABASE_NAME); + if (!$dbMap->hasTable(AttributeTemplateTableMap::TABLE_NAME)) { + $dbMap->addTableObject(new AttributeTemplateTableMap()); + } + } + + /** + * Performs a DELETE on the database, given a AttributeTemplate or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or AttributeTemplate object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(AttributeTemplateTableMap::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + // rename for clarity + $criteria = $values; + } elseif ($values instanceof \Thelia\Model\AttributeTemplate) { // it's a model object + // create criteria based on pk values + $criteria = $values->buildPkeyCriteria(); + } else { // it's a primary key, or an array of pks + $criteria = new Criteria(AttributeTemplateTableMap::DATABASE_NAME); + $criteria->add(AttributeTemplateTableMap::ID, (array) $values, Criteria::IN); + } + + $query = AttributeTemplateQuery::create()->mergeWith($criteria); + + if ($values instanceof Criteria) { AttributeTemplateTableMap::clearInstancePool(); + } elseif (!is_object($values)) { // it's a primary key, or an array of pks + foreach ((array) $values as $singleval) { AttributeTemplateTableMap::removeInstanceFromPool($singleval); + } + } + + return $query->delete($con); + } + + /** + * Deletes all rows from the attribute_template table. + * + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll(ConnectionInterface $con = null) + { + return AttributeTemplateQuery::create()->doDeleteAll($con); + } + + /** + * Performs an INSERT on the database, given a AttributeTemplate or Criteria object. + * + * @param mixed $criteria Criteria or AttributeTemplate object containing data that is used to create the INSERT statement. + * @param ConnectionInterface $con the ConnectionInterface connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($criteria, ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(AttributeTemplateTableMap::DATABASE_NAME); + } + + if ($criteria instanceof Criteria) { + $criteria = clone $criteria; // rename for clarity + } else { + $criteria = $criteria->buildCriteria(); // build Criteria from AttributeTemplate object + } + + if ($criteria->containsKey(AttributeTemplateTableMap::ID) && $criteria->keyContainsValue(AttributeTemplateTableMap::ID) ) { + throw new PropelException('Cannot insert a value for auto-increment primary key ('.AttributeTemplateTableMap::ID.')'); + } + + + // Set the correct dbName + $query = AttributeTemplateQuery::create()->mergeWith($criteria); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->beginTransaction(); + $pk = $query->doInsert($con); + $con->commit(); + } catch (PropelException $e) { + $con->rollBack(); + throw $e; + } + + return $pk; + } + +} // AttributeTemplateTableMap +// This is the static code needed to register the TableMap for this table with the main Propel class. +// +AttributeTemplateTableMap::buildTableMap(); diff --git a/core/lib/Thelia/Model/Map/CategoryTableMap.php b/core/lib/Thelia/Model/Map/CategoryTableMap.php index 6a2d052a1..cd0ca3799 100644 --- a/core/lib/Thelia/Model/Map/CategoryTableMap.php +++ b/core/lib/Thelia/Model/Map/CategoryTableMap.php @@ -191,16 +191,12 @@ class CategoryTableMap extends TableMap public function buildRelations() { $this->addRelation('ProductCategory', '\\Thelia\\Model\\ProductCategory', RelationMap::ONE_TO_MANY, array('id' => 'category_id', ), 'CASCADE', 'RESTRICT', 'ProductCategories'); - $this->addRelation('FeatureCategory', '\\Thelia\\Model\\FeatureCategory', RelationMap::ONE_TO_MANY, array('id' => 'category_id', ), 'CASCADE', 'RESTRICT', 'FeatureCategories'); - $this->addRelation('AttributeCategory', '\\Thelia\\Model\\AttributeCategory', RelationMap::ONE_TO_MANY, array('id' => 'category_id', ), 'CASCADE', 'RESTRICT', 'AttributeCategories'); $this->addRelation('CategoryImage', '\\Thelia\\Model\\CategoryImage', RelationMap::ONE_TO_MANY, array('id' => 'category_id', ), 'CASCADE', 'RESTRICT', 'CategoryImages'); $this->addRelation('CategoryDocument', '\\Thelia\\Model\\CategoryDocument', RelationMap::ONE_TO_MANY, array('id' => 'category_id', ), 'CASCADE', 'RESTRICT', 'CategoryDocuments'); $this->addRelation('CategoryAssociatedContent', '\\Thelia\\Model\\CategoryAssociatedContent', RelationMap::ONE_TO_MANY, array('id' => 'category_id', ), 'CASCADE', 'RESTRICT', 'CategoryAssociatedContents'); $this->addRelation('CategoryI18n', '\\Thelia\\Model\\CategoryI18n', RelationMap::ONE_TO_MANY, array('id' => 'id', ), 'CASCADE', null, 'CategoryI18ns'); $this->addRelation('CategoryVersion', '\\Thelia\\Model\\CategoryVersion', RelationMap::ONE_TO_MANY, array('id' => 'id', ), 'CASCADE', null, 'CategoryVersions'); $this->addRelation('Product', '\\Thelia\\Model\\Product', RelationMap::MANY_TO_MANY, array(), 'CASCADE', 'RESTRICT', 'Products'); - $this->addRelation('Feature', '\\Thelia\\Model\\Feature', RelationMap::MANY_TO_MANY, array(), 'CASCADE', 'RESTRICT', 'Features'); - $this->addRelation('Attribute', '\\Thelia\\Model\\Attribute', RelationMap::MANY_TO_MANY, array(), 'CASCADE', 'RESTRICT', 'Attributes'); } // buildRelations() /** @@ -225,8 +221,6 @@ class CategoryTableMap extends TableMap // Invalidate objects in ".$this->getClassNameFromBuilder($joinedTableTableMapBuilder)." instance pool, // since one or more of them may be deleted by ON DELETE CASCADE/SETNULL rule. ProductCategoryTableMap::clearInstancePool(); - FeatureCategoryTableMap::clearInstancePool(); - AttributeCategoryTableMap::clearInstancePool(); CategoryImageTableMap::clearInstancePool(); CategoryDocumentTableMap::clearInstancePool(); CategoryAssociatedContentTableMap::clearInstancePool(); diff --git a/core/lib/Thelia/Model/Map/CustomerTableMap.php b/core/lib/Thelia/Model/Map/CustomerTableMap.php index b23f4d6b0..32ccf07ee 100644 --- a/core/lib/Thelia/Model/Map/CustomerTableMap.php +++ b/core/lib/Thelia/Model/Map/CustomerTableMap.php @@ -57,7 +57,7 @@ class CustomerTableMap extends TableMap /** * The total number of columns */ - const NUM_COLUMNS = 14; + const NUM_COLUMNS = 16; /** * The number of lazy-loaded columns @@ -67,7 +67,7 @@ class CustomerTableMap extends TableMap /** * The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */ - const NUM_HYDRATE_COLUMNS = 14; + const NUM_HYDRATE_COLUMNS = 16; /** * the column name for the ID field @@ -129,6 +129,16 @@ class CustomerTableMap extends TableMap */ const DISCOUNT = 'customer.DISCOUNT'; + /** + * the column name for the REMEMBER_ME_TOKEN field + */ + const REMEMBER_ME_TOKEN = 'customer.REMEMBER_ME_TOKEN'; + + /** + * the column name for the REMEMBER_ME_SERIAL field + */ + const REMEMBER_ME_SERIAL = 'customer.REMEMBER_ME_SERIAL'; + /** * the column name for the CREATED_AT field */ @@ -151,12 +161,12 @@ class CustomerTableMap extends TableMap * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ protected static $fieldNames = array ( - self::TYPE_PHPNAME => array('Id', 'Ref', 'TitleId', 'Firstname', 'Lastname', 'Email', 'Password', 'Algo', 'Reseller', 'Lang', 'Sponsor', 'Discount', 'CreatedAt', 'UpdatedAt', ), - self::TYPE_STUDLYPHPNAME => array('id', 'ref', 'titleId', 'firstname', 'lastname', 'email', 'password', 'algo', 'reseller', 'lang', 'sponsor', 'discount', 'createdAt', 'updatedAt', ), - self::TYPE_COLNAME => array(CustomerTableMap::ID, CustomerTableMap::REF, CustomerTableMap::TITLE_ID, CustomerTableMap::FIRSTNAME, CustomerTableMap::LASTNAME, CustomerTableMap::EMAIL, CustomerTableMap::PASSWORD, CustomerTableMap::ALGO, CustomerTableMap::RESELLER, CustomerTableMap::LANG, CustomerTableMap::SPONSOR, CustomerTableMap::DISCOUNT, CustomerTableMap::CREATED_AT, CustomerTableMap::UPDATED_AT, ), - self::TYPE_RAW_COLNAME => array('ID', 'REF', 'TITLE_ID', 'FIRSTNAME', 'LASTNAME', 'EMAIL', 'PASSWORD', 'ALGO', 'RESELLER', 'LANG', 'SPONSOR', 'DISCOUNT', 'CREATED_AT', 'UPDATED_AT', ), - self::TYPE_FIELDNAME => array('id', 'ref', 'title_id', 'firstname', 'lastname', 'email', 'password', 'algo', 'reseller', 'lang', 'sponsor', 'discount', 'created_at', 'updated_at', ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, ) + self::TYPE_PHPNAME => array('Id', 'Ref', 'TitleId', 'Firstname', 'Lastname', 'Email', 'Password', 'Algo', 'Reseller', 'Lang', 'Sponsor', 'Discount', 'RememberMeToken', 'RememberMeSerial', 'CreatedAt', 'UpdatedAt', ), + self::TYPE_STUDLYPHPNAME => array('id', 'ref', 'titleId', 'firstname', 'lastname', 'email', 'password', 'algo', 'reseller', 'lang', 'sponsor', 'discount', 'rememberMeToken', 'rememberMeSerial', 'createdAt', 'updatedAt', ), + self::TYPE_COLNAME => array(CustomerTableMap::ID, CustomerTableMap::REF, CustomerTableMap::TITLE_ID, CustomerTableMap::FIRSTNAME, CustomerTableMap::LASTNAME, CustomerTableMap::EMAIL, CustomerTableMap::PASSWORD, CustomerTableMap::ALGO, CustomerTableMap::RESELLER, CustomerTableMap::LANG, CustomerTableMap::SPONSOR, CustomerTableMap::DISCOUNT, CustomerTableMap::REMEMBER_ME_TOKEN, CustomerTableMap::REMEMBER_ME_SERIAL, CustomerTableMap::CREATED_AT, CustomerTableMap::UPDATED_AT, ), + self::TYPE_RAW_COLNAME => array('ID', 'REF', 'TITLE_ID', 'FIRSTNAME', 'LASTNAME', 'EMAIL', 'PASSWORD', 'ALGO', 'RESELLER', 'LANG', 'SPONSOR', 'DISCOUNT', 'REMEMBER_ME_TOKEN', 'REMEMBER_ME_SERIAL', 'CREATED_AT', 'UPDATED_AT', ), + self::TYPE_FIELDNAME => array('id', 'ref', 'title_id', 'firstname', 'lastname', 'email', 'password', 'algo', 'reseller', 'lang', 'sponsor', 'discount', 'remember_me_token', 'remember_me_serial', 'created_at', 'updated_at', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ) ); /** @@ -166,12 +176,12 @@ class CustomerTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'Ref' => 1, 'TitleId' => 2, 'Firstname' => 3, 'Lastname' => 4, 'Email' => 5, 'Password' => 6, 'Algo' => 7, 'Reseller' => 8, 'Lang' => 9, 'Sponsor' => 10, 'Discount' => 11, 'CreatedAt' => 12, 'UpdatedAt' => 13, ), - self::TYPE_STUDLYPHPNAME => array('id' => 0, 'ref' => 1, 'titleId' => 2, 'firstname' => 3, 'lastname' => 4, 'email' => 5, 'password' => 6, 'algo' => 7, 'reseller' => 8, 'lang' => 9, 'sponsor' => 10, 'discount' => 11, 'createdAt' => 12, 'updatedAt' => 13, ), - self::TYPE_COLNAME => array(CustomerTableMap::ID => 0, CustomerTableMap::REF => 1, CustomerTableMap::TITLE_ID => 2, CustomerTableMap::FIRSTNAME => 3, CustomerTableMap::LASTNAME => 4, CustomerTableMap::EMAIL => 5, CustomerTableMap::PASSWORD => 6, CustomerTableMap::ALGO => 7, CustomerTableMap::RESELLER => 8, CustomerTableMap::LANG => 9, CustomerTableMap::SPONSOR => 10, CustomerTableMap::DISCOUNT => 11, CustomerTableMap::CREATED_AT => 12, CustomerTableMap::UPDATED_AT => 13, ), - self::TYPE_RAW_COLNAME => array('ID' => 0, 'REF' => 1, 'TITLE_ID' => 2, 'FIRSTNAME' => 3, 'LASTNAME' => 4, 'EMAIL' => 5, 'PASSWORD' => 6, 'ALGO' => 7, 'RESELLER' => 8, 'LANG' => 9, 'SPONSOR' => 10, 'DISCOUNT' => 11, 'CREATED_AT' => 12, 'UPDATED_AT' => 13, ), - self::TYPE_FIELDNAME => array('id' => 0, 'ref' => 1, 'title_id' => 2, 'firstname' => 3, 'lastname' => 4, 'email' => 5, 'password' => 6, 'algo' => 7, 'reseller' => 8, 'lang' => 9, 'sponsor' => 10, 'discount' => 11, 'created_at' => 12, 'updated_at' => 13, ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, ) + self::TYPE_PHPNAME => array('Id' => 0, 'Ref' => 1, 'TitleId' => 2, 'Firstname' => 3, 'Lastname' => 4, 'Email' => 5, 'Password' => 6, 'Algo' => 7, 'Reseller' => 8, 'Lang' => 9, 'Sponsor' => 10, 'Discount' => 11, 'RememberMeToken' => 12, 'RememberMeSerial' => 13, 'CreatedAt' => 14, 'UpdatedAt' => 15, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'ref' => 1, 'titleId' => 2, 'firstname' => 3, 'lastname' => 4, 'email' => 5, 'password' => 6, 'algo' => 7, 'reseller' => 8, 'lang' => 9, 'sponsor' => 10, 'discount' => 11, 'rememberMeToken' => 12, 'rememberMeSerial' => 13, 'createdAt' => 14, 'updatedAt' => 15, ), + self::TYPE_COLNAME => array(CustomerTableMap::ID => 0, CustomerTableMap::REF => 1, CustomerTableMap::TITLE_ID => 2, CustomerTableMap::FIRSTNAME => 3, CustomerTableMap::LASTNAME => 4, CustomerTableMap::EMAIL => 5, CustomerTableMap::PASSWORD => 6, CustomerTableMap::ALGO => 7, CustomerTableMap::RESELLER => 8, CustomerTableMap::LANG => 9, CustomerTableMap::SPONSOR => 10, CustomerTableMap::DISCOUNT => 11, CustomerTableMap::REMEMBER_ME_TOKEN => 12, CustomerTableMap::REMEMBER_ME_SERIAL => 13, CustomerTableMap::CREATED_AT => 14, CustomerTableMap::UPDATED_AT => 15, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'REF' => 1, 'TITLE_ID' => 2, 'FIRSTNAME' => 3, 'LASTNAME' => 4, 'EMAIL' => 5, 'PASSWORD' => 6, 'ALGO' => 7, 'RESELLER' => 8, 'LANG' => 9, 'SPONSOR' => 10, 'DISCOUNT' => 11, 'REMEMBER_ME_TOKEN' => 12, 'REMEMBER_ME_SERIAL' => 13, 'CREATED_AT' => 14, 'UPDATED_AT' => 15, ), + self::TYPE_FIELDNAME => array('id' => 0, 'ref' => 1, 'title_id' => 2, 'firstname' => 3, 'lastname' => 4, 'email' => 5, 'password' => 6, 'algo' => 7, 'reseller' => 8, 'lang' => 9, 'sponsor' => 10, 'discount' => 11, 'remember_me_token' => 12, 'remember_me_serial' => 13, 'created_at' => 14, 'updated_at' => 15, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ) ); /** @@ -202,6 +212,8 @@ class CustomerTableMap extends TableMap $this->addColumn('LANG', 'Lang', 'VARCHAR', false, 10, null); $this->addColumn('SPONSOR', 'Sponsor', 'VARCHAR', false, 50, null); $this->addColumn('DISCOUNT', 'Discount', 'FLOAT', false, null, null); + $this->addColumn('REMEMBER_ME_TOKEN', 'RememberMeToken', 'VARCHAR', false, 255, null); + $this->addColumn('REMEMBER_ME_SERIAL', 'RememberMeSerial', 'VARCHAR', false, 255, null); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); } // initialize() @@ -390,6 +402,8 @@ class CustomerTableMap extends TableMap $criteria->addSelectColumn(CustomerTableMap::LANG); $criteria->addSelectColumn(CustomerTableMap::SPONSOR); $criteria->addSelectColumn(CustomerTableMap::DISCOUNT); + $criteria->addSelectColumn(CustomerTableMap::REMEMBER_ME_TOKEN); + $criteria->addSelectColumn(CustomerTableMap::REMEMBER_ME_SERIAL); $criteria->addSelectColumn(CustomerTableMap::CREATED_AT); $criteria->addSelectColumn(CustomerTableMap::UPDATED_AT); } else { @@ -405,6 +419,8 @@ class CustomerTableMap extends TableMap $criteria->addSelectColumn($alias . '.LANG'); $criteria->addSelectColumn($alias . '.SPONSOR'); $criteria->addSelectColumn($alias . '.DISCOUNT'); + $criteria->addSelectColumn($alias . '.REMEMBER_ME_TOKEN'); + $criteria->addSelectColumn($alias . '.REMEMBER_ME_SERIAL'); $criteria->addSelectColumn($alias . '.CREATED_AT'); $criteria->addSelectColumn($alias . '.UPDATED_AT'); } diff --git a/core/lib/Thelia/Model/Map/FeatureTableMap.php b/core/lib/Thelia/Model/Map/FeatureTableMap.php index 76c2fe724..067a242a3 100644 --- a/core/lib/Thelia/Model/Map/FeatureTableMap.php +++ b/core/lib/Thelia/Model/Map/FeatureTableMap.php @@ -168,9 +168,9 @@ class FeatureTableMap extends TableMap { $this->addRelation('FeatureAv', '\\Thelia\\Model\\FeatureAv', RelationMap::ONE_TO_MANY, array('id' => 'feature_id', ), 'CASCADE', 'RESTRICT', 'FeatureAvs'); $this->addRelation('FeatureProduct', '\\Thelia\\Model\\FeatureProduct', RelationMap::ONE_TO_MANY, array('id' => 'feature_id', ), 'CASCADE', 'RESTRICT', 'FeatureProducts'); - $this->addRelation('FeatureCategory', '\\Thelia\\Model\\FeatureCategory', RelationMap::ONE_TO_MANY, array('id' => 'feature_id', ), 'CASCADE', 'RESTRICT', 'FeatureCategories'); + $this->addRelation('FeatureTemplate', '\\Thelia\\Model\\FeatureTemplate', RelationMap::ONE_TO_MANY, array('id' => 'feature_id', ), 'CASCADE', 'RESTRICT', 'FeatureTemplates'); $this->addRelation('FeatureI18n', '\\Thelia\\Model\\FeatureI18n', RelationMap::ONE_TO_MANY, array('id' => 'id', ), 'CASCADE', null, 'FeatureI18ns'); - $this->addRelation('Category', '\\Thelia\\Model\\Category', RelationMap::MANY_TO_MANY, array(), 'CASCADE', 'RESTRICT', 'Categories'); + $this->addRelation('Template', '\\Thelia\\Model\\Template', RelationMap::MANY_TO_MANY, array(), null, null, 'Templates'); } // buildRelations() /** @@ -195,7 +195,7 @@ class FeatureTableMap extends TableMap // since one or more of them may be deleted by ON DELETE CASCADE/SETNULL rule. FeatureAvTableMap::clearInstancePool(); FeatureProductTableMap::clearInstancePool(); - FeatureCategoryTableMap::clearInstancePool(); + FeatureTemplateTableMap::clearInstancePool(); FeatureI18nTableMap::clearInstancePool(); } diff --git a/core/lib/Thelia/Model/Map/FeatureTemplateTableMap.php b/core/lib/Thelia/Model/Map/FeatureTemplateTableMap.php new file mode 100644 index 000000000..abb1a98b7 --- /dev/null +++ b/core/lib/Thelia/Model/Map/FeatureTemplateTableMap.php @@ -0,0 +1,449 @@ + array('Id', 'FeatureId', 'TemplateId', 'CreatedAt', 'UpdatedAt', ), + self::TYPE_STUDLYPHPNAME => array('id', 'featureId', 'templateId', 'createdAt', 'updatedAt', ), + self::TYPE_COLNAME => array(FeatureTemplateTableMap::ID, FeatureTemplateTableMap::FEATURE_ID, FeatureTemplateTableMap::TEMPLATE_ID, FeatureTemplateTableMap::CREATED_AT, FeatureTemplateTableMap::UPDATED_AT, ), + self::TYPE_RAW_COLNAME => array('ID', 'FEATURE_ID', 'TEMPLATE_ID', 'CREATED_AT', 'UPDATED_AT', ), + self::TYPE_FIELDNAME => array('id', 'feature_id', 'template_id', 'created_at', 'updated_at', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 + */ + protected static $fieldKeys = array ( + self::TYPE_PHPNAME => array('Id' => 0, 'FeatureId' => 1, 'TemplateId' => 2, 'CreatedAt' => 3, 'UpdatedAt' => 4, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'featureId' => 1, 'templateId' => 2, 'createdAt' => 3, 'updatedAt' => 4, ), + self::TYPE_COLNAME => array(FeatureTemplateTableMap::ID => 0, FeatureTemplateTableMap::FEATURE_ID => 1, FeatureTemplateTableMap::TEMPLATE_ID => 2, FeatureTemplateTableMap::CREATED_AT => 3, FeatureTemplateTableMap::UPDATED_AT => 4, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'FEATURE_ID' => 1, 'TEMPLATE_ID' => 2, 'CREATED_AT' => 3, 'UPDATED_AT' => 4, ), + self::TYPE_FIELDNAME => array('id' => 0, 'feature_id' => 1, 'template_id' => 2, 'created_at' => 3, 'updated_at' => 4, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, ) + ); + + /** + * Initialize the table attributes and columns + * Relations are not initialized by this method since they are lazy loaded + * + * @return void + * @throws PropelException + */ + public function initialize() + { + // attributes + $this->setName('feature_template'); + $this->setPhpName('FeatureTemplate'); + $this->setClassName('\\Thelia\\Model\\FeatureTemplate'); + $this->setPackage('Thelia.Model'); + $this->setUseIdGenerator(true); + $this->setIsCrossRef(true); + // columns + $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); + $this->addForeignKey('FEATURE_ID', 'FeatureId', 'INTEGER', 'feature', 'ID', true, null, null); + $this->addForeignKey('TEMPLATE_ID', 'TemplateId', 'INTEGER', 'template', 'ID', true, null, null); + $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); + $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); + } // initialize() + + /** + * Build the RelationMap objects for this table relationships + */ + public function buildRelations() + { + $this->addRelation('Feature', '\\Thelia\\Model\\Feature', RelationMap::MANY_TO_ONE, array('feature_id' => 'id', ), 'CASCADE', 'RESTRICT'); + $this->addRelation('Template', '\\Thelia\\Model\\Template', RelationMap::MANY_TO_ONE, array('template_id' => 'id', ), null, null); + } // 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. + * + * For tables with a single-column primary key, that simple pkey value will be returned. For tables with + * a multi-column primary key, a serialize()d version of the primary key will be returned. + * + * @param array $row resultset row. + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM + */ + public static function getPrimaryKeyHashFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + // If the PK cannot be derived from the row, return NULL. + if ($row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)] === null) { + return null; + } + + return (string) $row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)]; + } + + /** + * Retrieves the primary key from the DB resultset row + * For tables with a single-column primary key, that simple pkey value will be returned. For tables with + * a multi-column primary key, an array of the primary key columns will be returned. + * + * @param array $row resultset row. + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM + * + * @return mixed The primary key of the row + */ + public static function getPrimaryKeyFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + + return (int) $row[ + $indexType == TableMap::TYPE_NUM + ? 0 + $offset + : self::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType) + ]; + } + + /** + * The class that the tableMap will make instances of. + * + * If $withPrefix is true, the returned path + * uses a dot-path notation which is translated into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @param boolean $withPrefix Whether or not to return the path with the class name + * @return string path.to.ClassName + */ + public static function getOMClass($withPrefix = true) + { + return $withPrefix ? FeatureTemplateTableMap::CLASS_DEFAULT : FeatureTemplateTableMap::OM_CLASS; + } + + /** + * Populates an object of the default type or an object that inherit from the default. + * + * @param array $row row returned by DataFetcher->fetch(). + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType The index type of $row. Mostly DataFetcher->getIndexType(). + One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return array (FeatureTemplate object, last column rank) + */ + public static function populateObject($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + $key = FeatureTemplateTableMap::getPrimaryKeyHashFromRow($row, $offset, $indexType); + if (null !== ($obj = FeatureTemplateTableMap::getInstanceFromPool($key))) { + // We no longer rehydrate the object, since this can cause data loss. + // See http://www.propelorm.org/ticket/509 + // $obj->hydrate($row, $offset, true); // rehydrate + $col = $offset + FeatureTemplateTableMap::NUM_HYDRATE_COLUMNS; + } else { + $cls = FeatureTemplateTableMap::OM_CLASS; + $obj = new $cls(); + $col = $obj->hydrate($row, $offset, false, $indexType); + FeatureTemplateTableMap::addInstanceToPool($obj, $key); + } + + return array($obj, $col); + } + + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @param DataFetcherInterface $dataFetcher + * @return array + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(DataFetcherInterface $dataFetcher) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = static::getOMClass(false); + // populate the object(s) + while ($row = $dataFetcher->fetch()) { + $key = FeatureTemplateTableMap::getPrimaryKeyHashFromRow($row, 0, $dataFetcher->getIndexType()); + if (null !== ($obj = FeatureTemplateTableMap::getInstanceFromPool($key))) { + // We no longer rehydrate the object, since this can cause data loss. + // See http://www.propelorm.org/ticket/509 + // $obj->hydrate($row, 0, true); // rehydrate + $results[] = $obj; + } else { + $obj = new $cls(); + $obj->hydrate($row); + $results[] = $obj; + FeatureTemplateTableMap::addInstanceToPool($obj, $key); + } // if key exists + } + + return $results; + } + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param Criteria $criteria object containing the columns to add. + * @param string $alias optional table alias + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria, $alias = null) + { + if (null === $alias) { + $criteria->addSelectColumn(FeatureTemplateTableMap::ID); + $criteria->addSelectColumn(FeatureTemplateTableMap::FEATURE_ID); + $criteria->addSelectColumn(FeatureTemplateTableMap::TEMPLATE_ID); + $criteria->addSelectColumn(FeatureTemplateTableMap::CREATED_AT); + $criteria->addSelectColumn(FeatureTemplateTableMap::UPDATED_AT); + } else { + $criteria->addSelectColumn($alias . '.ID'); + $criteria->addSelectColumn($alias . '.FEATURE_ID'); + $criteria->addSelectColumn($alias . '.TEMPLATE_ID'); + $criteria->addSelectColumn($alias . '.CREATED_AT'); + $criteria->addSelectColumn($alias . '.UPDATED_AT'); + } + } + + /** + * Returns the TableMap related to this object. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getServiceContainer()->getDatabaseMap(FeatureTemplateTableMap::DATABASE_NAME)->getTable(FeatureTemplateTableMap::TABLE_NAME); + } + + /** + * Add a TableMap instance to the database for this tableMap class. + */ + public static function buildTableMap() + { + $dbMap = Propel::getServiceContainer()->getDatabaseMap(FeatureTemplateTableMap::DATABASE_NAME); + if (!$dbMap->hasTable(FeatureTemplateTableMap::TABLE_NAME)) { + $dbMap->addTableObject(new FeatureTemplateTableMap()); + } + } + + /** + * Performs a DELETE on the database, given a FeatureTemplate or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or FeatureTemplate object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(FeatureTemplateTableMap::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + // rename for clarity + $criteria = $values; + } elseif ($values instanceof \Thelia\Model\FeatureTemplate) { // it's a model object + // create criteria based on pk values + $criteria = $values->buildPkeyCriteria(); + } else { // it's a primary key, or an array of pks + $criteria = new Criteria(FeatureTemplateTableMap::DATABASE_NAME); + $criteria->add(FeatureTemplateTableMap::ID, (array) $values, Criteria::IN); + } + + $query = FeatureTemplateQuery::create()->mergeWith($criteria); + + if ($values instanceof Criteria) { FeatureTemplateTableMap::clearInstancePool(); + } elseif (!is_object($values)) { // it's a primary key, or an array of pks + foreach ((array) $values as $singleval) { FeatureTemplateTableMap::removeInstanceFromPool($singleval); + } + } + + return $query->delete($con); + } + + /** + * Deletes all rows from the feature_template table. + * + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll(ConnectionInterface $con = null) + { + return FeatureTemplateQuery::create()->doDeleteAll($con); + } + + /** + * Performs an INSERT on the database, given a FeatureTemplate or Criteria object. + * + * @param mixed $criteria Criteria or FeatureTemplate object containing data that is used to create the INSERT statement. + * @param ConnectionInterface $con the ConnectionInterface connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($criteria, ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(FeatureTemplateTableMap::DATABASE_NAME); + } + + if ($criteria instanceof Criteria) { + $criteria = clone $criteria; // rename for clarity + } else { + $criteria = $criteria->buildCriteria(); // build Criteria from FeatureTemplate object + } + + if ($criteria->containsKey(FeatureTemplateTableMap::ID) && $criteria->keyContainsValue(FeatureTemplateTableMap::ID) ) { + throw new PropelException('Cannot insert a value for auto-increment primary key ('.FeatureTemplateTableMap::ID.')'); + } + + + // Set the correct dbName + $query = FeatureTemplateQuery::create()->mergeWith($criteria); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->beginTransaction(); + $pk = $query->doInsert($con); + $con->commit(); + } catch (PropelException $e) { + $con->rollBack(); + throw $e; + } + + return $pk; + } + +} // FeatureTemplateTableMap +// This is the static code needed to register the TableMap for this table with the main Propel class. +// +FeatureTemplateTableMap::buildTableMap(); diff --git a/core/lib/Thelia/Model/Map/ProductTableMap.php b/core/lib/Thelia/Model/Map/ProductTableMap.php index f69f6f702..17c4585f0 100644 --- a/core/lib/Thelia/Model/Map/ProductTableMap.php +++ b/core/lib/Thelia/Model/Map/ProductTableMap.php @@ -57,7 +57,7 @@ class ProductTableMap extends TableMap /** * The total number of columns */ - const NUM_COLUMNS = 10; + const NUM_COLUMNS = 11; /** * The number of lazy-loaded columns @@ -67,7 +67,7 @@ class ProductTableMap extends TableMap /** * The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */ - const NUM_HYDRATE_COLUMNS = 10; + const NUM_HYDRATE_COLUMNS = 11; /** * the column name for the ID field @@ -94,6 +94,11 @@ class ProductTableMap extends TableMap */ const POSITION = 'product.POSITION'; + /** + * the column name for the TEMPLATE_ID field + */ + const TEMPLATE_ID = 'product.TEMPLATE_ID'; + /** * the column name for the CREATED_AT field */ @@ -140,12 +145,12 @@ class ProductTableMap extends TableMap * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ protected static $fieldNames = array ( - self::TYPE_PHPNAME => array('Id', 'TaxRuleId', 'Ref', 'Visible', 'Position', 'CreatedAt', 'UpdatedAt', 'Version', 'VersionCreatedAt', 'VersionCreatedBy', ), - self::TYPE_STUDLYPHPNAME => array('id', 'taxRuleId', 'ref', 'visible', 'position', 'createdAt', 'updatedAt', 'version', 'versionCreatedAt', 'versionCreatedBy', ), - self::TYPE_COLNAME => array(ProductTableMap::ID, ProductTableMap::TAX_RULE_ID, ProductTableMap::REF, ProductTableMap::VISIBLE, ProductTableMap::POSITION, ProductTableMap::CREATED_AT, ProductTableMap::UPDATED_AT, ProductTableMap::VERSION, ProductTableMap::VERSION_CREATED_AT, ProductTableMap::VERSION_CREATED_BY, ), - self::TYPE_RAW_COLNAME => array('ID', 'TAX_RULE_ID', 'REF', 'VISIBLE', 'POSITION', 'CREATED_AT', 'UPDATED_AT', 'VERSION', 'VERSION_CREATED_AT', 'VERSION_CREATED_BY', ), - self::TYPE_FIELDNAME => array('id', 'tax_rule_id', 'ref', 'visible', 'position', 'created_at', 'updated_at', 'version', 'version_created_at', 'version_created_by', ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ) + self::TYPE_PHPNAME => array('Id', 'TaxRuleId', 'Ref', 'Visible', 'Position', 'TemplateId', 'CreatedAt', 'UpdatedAt', 'Version', 'VersionCreatedAt', 'VersionCreatedBy', ), + self::TYPE_STUDLYPHPNAME => array('id', 'taxRuleId', 'ref', 'visible', 'position', 'templateId', 'createdAt', 'updatedAt', 'version', 'versionCreatedAt', 'versionCreatedBy', ), + self::TYPE_COLNAME => array(ProductTableMap::ID, ProductTableMap::TAX_RULE_ID, ProductTableMap::REF, ProductTableMap::VISIBLE, ProductTableMap::POSITION, ProductTableMap::TEMPLATE_ID, ProductTableMap::CREATED_AT, ProductTableMap::UPDATED_AT, ProductTableMap::VERSION, ProductTableMap::VERSION_CREATED_AT, ProductTableMap::VERSION_CREATED_BY, ), + self::TYPE_RAW_COLNAME => array('ID', 'TAX_RULE_ID', 'REF', 'VISIBLE', 'POSITION', 'TEMPLATE_ID', 'CREATED_AT', 'UPDATED_AT', 'VERSION', 'VERSION_CREATED_AT', 'VERSION_CREATED_BY', ), + self::TYPE_FIELDNAME => array('id', 'tax_rule_id', 'ref', 'visible', 'position', 'template_id', 'created_at', 'updated_at', 'version', 'version_created_at', 'version_created_by', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ) ); /** @@ -155,12 +160,12 @@ class ProductTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'TaxRuleId' => 1, 'Ref' => 2, 'Visible' => 3, 'Position' => 4, 'CreatedAt' => 5, 'UpdatedAt' => 6, 'Version' => 7, 'VersionCreatedAt' => 8, 'VersionCreatedBy' => 9, ), - self::TYPE_STUDLYPHPNAME => array('id' => 0, 'taxRuleId' => 1, 'ref' => 2, 'visible' => 3, 'position' => 4, 'createdAt' => 5, 'updatedAt' => 6, 'version' => 7, 'versionCreatedAt' => 8, 'versionCreatedBy' => 9, ), - self::TYPE_COLNAME => array(ProductTableMap::ID => 0, ProductTableMap::TAX_RULE_ID => 1, ProductTableMap::REF => 2, ProductTableMap::VISIBLE => 3, ProductTableMap::POSITION => 4, ProductTableMap::CREATED_AT => 5, ProductTableMap::UPDATED_AT => 6, ProductTableMap::VERSION => 7, ProductTableMap::VERSION_CREATED_AT => 8, ProductTableMap::VERSION_CREATED_BY => 9, ), - self::TYPE_RAW_COLNAME => array('ID' => 0, 'TAX_RULE_ID' => 1, 'REF' => 2, 'VISIBLE' => 3, 'POSITION' => 4, 'CREATED_AT' => 5, 'UPDATED_AT' => 6, 'VERSION' => 7, 'VERSION_CREATED_AT' => 8, 'VERSION_CREATED_BY' => 9, ), - self::TYPE_FIELDNAME => array('id' => 0, 'tax_rule_id' => 1, 'ref' => 2, 'visible' => 3, 'position' => 4, 'created_at' => 5, 'updated_at' => 6, 'version' => 7, 'version_created_at' => 8, 'version_created_by' => 9, ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ) + self::TYPE_PHPNAME => array('Id' => 0, 'TaxRuleId' => 1, 'Ref' => 2, 'Visible' => 3, 'Position' => 4, 'TemplateId' => 5, 'CreatedAt' => 6, 'UpdatedAt' => 7, 'Version' => 8, 'VersionCreatedAt' => 9, 'VersionCreatedBy' => 10, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'taxRuleId' => 1, 'ref' => 2, 'visible' => 3, 'position' => 4, 'templateId' => 5, 'createdAt' => 6, 'updatedAt' => 7, 'version' => 8, 'versionCreatedAt' => 9, 'versionCreatedBy' => 10, ), + self::TYPE_COLNAME => array(ProductTableMap::ID => 0, ProductTableMap::TAX_RULE_ID => 1, ProductTableMap::REF => 2, ProductTableMap::VISIBLE => 3, ProductTableMap::POSITION => 4, ProductTableMap::TEMPLATE_ID => 5, ProductTableMap::CREATED_AT => 6, ProductTableMap::UPDATED_AT => 7, ProductTableMap::VERSION => 8, ProductTableMap::VERSION_CREATED_AT => 9, ProductTableMap::VERSION_CREATED_BY => 10, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'TAX_RULE_ID' => 1, 'REF' => 2, 'VISIBLE' => 3, 'POSITION' => 4, 'TEMPLATE_ID' => 5, 'CREATED_AT' => 6, 'UPDATED_AT' => 7, 'VERSION' => 8, 'VERSION_CREATED_AT' => 9, 'VERSION_CREATED_BY' => 10, ), + self::TYPE_FIELDNAME => array('id' => 0, 'tax_rule_id' => 1, 'ref' => 2, 'visible' => 3, 'position' => 4, 'template_id' => 5, 'created_at' => 6, 'updated_at' => 7, 'version' => 8, 'version_created_at' => 9, 'version_created_by' => 10, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ) ); /** @@ -184,6 +189,7 @@ class ProductTableMap extends TableMap $this->addColumn('REF', 'Ref', 'VARCHAR', true, 255, null); $this->addColumn('VISIBLE', 'Visible', 'TINYINT', true, null, 0); $this->addColumn('POSITION', 'Position', 'INTEGER', true, null, null); + $this->addForeignKey('TEMPLATE_ID', 'TemplateId', 'INTEGER', 'template', 'ID', true, null, null); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('VERSION', 'Version', 'INTEGER', false, null, 0); @@ -197,6 +203,7 @@ class ProductTableMap extends TableMap public function buildRelations() { $this->addRelation('TaxRule', '\\Thelia\\Model\\TaxRule', RelationMap::MANY_TO_ONE, array('tax_rule_id' => 'id', ), 'SET NULL', 'RESTRICT'); + $this->addRelation('Template', '\\Thelia\\Model\\Template', RelationMap::MANY_TO_ONE, array('template_id' => 'id', ), null, null); $this->addRelation('ProductCategory', '\\Thelia\\Model\\ProductCategory', RelationMap::ONE_TO_MANY, array('id' => 'product_id', ), 'CASCADE', 'RESTRICT', 'ProductCategories'); $this->addRelation('FeatureProduct', '\\Thelia\\Model\\FeatureProduct', RelationMap::ONE_TO_MANY, array('id' => 'product_id', ), 'CASCADE', 'RESTRICT', 'FeatureProducts'); $this->addRelation('ProductSaleElements', '\\Thelia\\Model\\ProductSaleElements', RelationMap::ONE_TO_MANY, array('id' => 'product_id', ), 'CASCADE', 'RESTRICT', 'ProductSaleElementss'); @@ -388,6 +395,7 @@ class ProductTableMap extends TableMap $criteria->addSelectColumn(ProductTableMap::REF); $criteria->addSelectColumn(ProductTableMap::VISIBLE); $criteria->addSelectColumn(ProductTableMap::POSITION); + $criteria->addSelectColumn(ProductTableMap::TEMPLATE_ID); $criteria->addSelectColumn(ProductTableMap::CREATED_AT); $criteria->addSelectColumn(ProductTableMap::UPDATED_AT); $criteria->addSelectColumn(ProductTableMap::VERSION); @@ -399,6 +407,7 @@ class ProductTableMap extends TableMap $criteria->addSelectColumn($alias . '.REF'); $criteria->addSelectColumn($alias . '.VISIBLE'); $criteria->addSelectColumn($alias . '.POSITION'); + $criteria->addSelectColumn($alias . '.TEMPLATE_ID'); $criteria->addSelectColumn($alias . '.CREATED_AT'); $criteria->addSelectColumn($alias . '.UPDATED_AT'); $criteria->addSelectColumn($alias . '.VERSION'); diff --git a/core/lib/Thelia/Model/Map/ProductVersionTableMap.php b/core/lib/Thelia/Model/Map/ProductVersionTableMap.php index d3e69b16f..4e84b4db8 100644 --- a/core/lib/Thelia/Model/Map/ProductVersionTableMap.php +++ b/core/lib/Thelia/Model/Map/ProductVersionTableMap.php @@ -57,7 +57,7 @@ class ProductVersionTableMap extends TableMap /** * The total number of columns */ - const NUM_COLUMNS = 10; + const NUM_COLUMNS = 11; /** * The number of lazy-loaded columns @@ -67,7 +67,7 @@ class ProductVersionTableMap extends TableMap /** * The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */ - const NUM_HYDRATE_COLUMNS = 10; + const NUM_HYDRATE_COLUMNS = 11; /** * the column name for the ID field @@ -94,6 +94,11 @@ class ProductVersionTableMap extends TableMap */ const POSITION = 'product_version.POSITION'; + /** + * the column name for the TEMPLATE_ID field + */ + const TEMPLATE_ID = 'product_version.TEMPLATE_ID'; + /** * the column name for the CREATED_AT field */ @@ -131,12 +136,12 @@ class ProductVersionTableMap extends TableMap * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ protected static $fieldNames = array ( - self::TYPE_PHPNAME => array('Id', 'TaxRuleId', 'Ref', 'Visible', 'Position', 'CreatedAt', 'UpdatedAt', 'Version', 'VersionCreatedAt', 'VersionCreatedBy', ), - self::TYPE_STUDLYPHPNAME => array('id', 'taxRuleId', 'ref', 'visible', 'position', 'createdAt', 'updatedAt', 'version', 'versionCreatedAt', 'versionCreatedBy', ), - self::TYPE_COLNAME => array(ProductVersionTableMap::ID, ProductVersionTableMap::TAX_RULE_ID, ProductVersionTableMap::REF, ProductVersionTableMap::VISIBLE, ProductVersionTableMap::POSITION, ProductVersionTableMap::CREATED_AT, ProductVersionTableMap::UPDATED_AT, ProductVersionTableMap::VERSION, ProductVersionTableMap::VERSION_CREATED_AT, ProductVersionTableMap::VERSION_CREATED_BY, ), - self::TYPE_RAW_COLNAME => array('ID', 'TAX_RULE_ID', 'REF', 'VISIBLE', 'POSITION', 'CREATED_AT', 'UPDATED_AT', 'VERSION', 'VERSION_CREATED_AT', 'VERSION_CREATED_BY', ), - self::TYPE_FIELDNAME => array('id', 'tax_rule_id', 'ref', 'visible', 'position', 'created_at', 'updated_at', 'version', 'version_created_at', 'version_created_by', ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ) + self::TYPE_PHPNAME => array('Id', 'TaxRuleId', 'Ref', 'Visible', 'Position', 'TemplateId', 'CreatedAt', 'UpdatedAt', 'Version', 'VersionCreatedAt', 'VersionCreatedBy', ), + self::TYPE_STUDLYPHPNAME => array('id', 'taxRuleId', 'ref', 'visible', 'position', 'templateId', 'createdAt', 'updatedAt', 'version', 'versionCreatedAt', 'versionCreatedBy', ), + self::TYPE_COLNAME => array(ProductVersionTableMap::ID, ProductVersionTableMap::TAX_RULE_ID, ProductVersionTableMap::REF, ProductVersionTableMap::VISIBLE, ProductVersionTableMap::POSITION, ProductVersionTableMap::TEMPLATE_ID, ProductVersionTableMap::CREATED_AT, ProductVersionTableMap::UPDATED_AT, ProductVersionTableMap::VERSION, ProductVersionTableMap::VERSION_CREATED_AT, ProductVersionTableMap::VERSION_CREATED_BY, ), + self::TYPE_RAW_COLNAME => array('ID', 'TAX_RULE_ID', 'REF', 'VISIBLE', 'POSITION', 'TEMPLATE_ID', 'CREATED_AT', 'UPDATED_AT', 'VERSION', 'VERSION_CREATED_AT', 'VERSION_CREATED_BY', ), + self::TYPE_FIELDNAME => array('id', 'tax_rule_id', 'ref', 'visible', 'position', 'template_id', 'created_at', 'updated_at', 'version', 'version_created_at', 'version_created_by', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ) ); /** @@ -146,12 +151,12 @@ class ProductVersionTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'TaxRuleId' => 1, 'Ref' => 2, 'Visible' => 3, 'Position' => 4, 'CreatedAt' => 5, 'UpdatedAt' => 6, 'Version' => 7, 'VersionCreatedAt' => 8, 'VersionCreatedBy' => 9, ), - self::TYPE_STUDLYPHPNAME => array('id' => 0, 'taxRuleId' => 1, 'ref' => 2, 'visible' => 3, 'position' => 4, 'createdAt' => 5, 'updatedAt' => 6, 'version' => 7, 'versionCreatedAt' => 8, 'versionCreatedBy' => 9, ), - self::TYPE_COLNAME => array(ProductVersionTableMap::ID => 0, ProductVersionTableMap::TAX_RULE_ID => 1, ProductVersionTableMap::REF => 2, ProductVersionTableMap::VISIBLE => 3, ProductVersionTableMap::POSITION => 4, ProductVersionTableMap::CREATED_AT => 5, ProductVersionTableMap::UPDATED_AT => 6, ProductVersionTableMap::VERSION => 7, ProductVersionTableMap::VERSION_CREATED_AT => 8, ProductVersionTableMap::VERSION_CREATED_BY => 9, ), - self::TYPE_RAW_COLNAME => array('ID' => 0, 'TAX_RULE_ID' => 1, 'REF' => 2, 'VISIBLE' => 3, 'POSITION' => 4, 'CREATED_AT' => 5, 'UPDATED_AT' => 6, 'VERSION' => 7, 'VERSION_CREATED_AT' => 8, 'VERSION_CREATED_BY' => 9, ), - self::TYPE_FIELDNAME => array('id' => 0, 'tax_rule_id' => 1, 'ref' => 2, 'visible' => 3, 'position' => 4, 'created_at' => 5, 'updated_at' => 6, 'version' => 7, 'version_created_at' => 8, 'version_created_by' => 9, ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ) + self::TYPE_PHPNAME => array('Id' => 0, 'TaxRuleId' => 1, 'Ref' => 2, 'Visible' => 3, 'Position' => 4, 'TemplateId' => 5, 'CreatedAt' => 6, 'UpdatedAt' => 7, 'Version' => 8, 'VersionCreatedAt' => 9, 'VersionCreatedBy' => 10, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'taxRuleId' => 1, 'ref' => 2, 'visible' => 3, 'position' => 4, 'templateId' => 5, 'createdAt' => 6, 'updatedAt' => 7, 'version' => 8, 'versionCreatedAt' => 9, 'versionCreatedBy' => 10, ), + self::TYPE_COLNAME => array(ProductVersionTableMap::ID => 0, ProductVersionTableMap::TAX_RULE_ID => 1, ProductVersionTableMap::REF => 2, ProductVersionTableMap::VISIBLE => 3, ProductVersionTableMap::POSITION => 4, ProductVersionTableMap::TEMPLATE_ID => 5, ProductVersionTableMap::CREATED_AT => 6, ProductVersionTableMap::UPDATED_AT => 7, ProductVersionTableMap::VERSION => 8, ProductVersionTableMap::VERSION_CREATED_AT => 9, ProductVersionTableMap::VERSION_CREATED_BY => 10, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'TAX_RULE_ID' => 1, 'REF' => 2, 'VISIBLE' => 3, 'POSITION' => 4, 'TEMPLATE_ID' => 5, 'CREATED_AT' => 6, 'UPDATED_AT' => 7, 'VERSION' => 8, 'VERSION_CREATED_AT' => 9, 'VERSION_CREATED_BY' => 10, ), + self::TYPE_FIELDNAME => array('id' => 0, 'tax_rule_id' => 1, 'ref' => 2, 'visible' => 3, 'position' => 4, 'template_id' => 5, 'created_at' => 6, 'updated_at' => 7, 'version' => 8, 'version_created_at' => 9, 'version_created_by' => 10, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ) ); /** @@ -175,6 +180,7 @@ class ProductVersionTableMap extends TableMap $this->addColumn('REF', 'Ref', 'VARCHAR', true, 255, null); $this->addColumn('VISIBLE', 'Visible', 'TINYINT', true, null, 0); $this->addColumn('POSITION', 'Position', 'INTEGER', true, null, null); + $this->addColumn('TEMPLATE_ID', 'TemplateId', 'INTEGER', true, null, null); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); $this->addPrimaryKey('VERSION', 'Version', 'INTEGER', true, null, 0); @@ -257,11 +263,11 @@ class ProductVersionTableMap extends TableMap public static function getPrimaryKeyHashFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM) { // If the PK cannot be derived from the row, return NULL. - if ($row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)] === null && $row[TableMap::TYPE_NUM == $indexType ? 7 + $offset : static::translateFieldName('Version', TableMap::TYPE_PHPNAME, $indexType)] === null) { + if ($row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)] === null && $row[TableMap::TYPE_NUM == $indexType ? 8 + $offset : static::translateFieldName('Version', TableMap::TYPE_PHPNAME, $indexType)] === null) { return null; } - return serialize(array((string) $row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)], (string) $row[TableMap::TYPE_NUM == $indexType ? 7 + $offset : static::translateFieldName('Version', TableMap::TYPE_PHPNAME, $indexType)])); + return serialize(array((string) $row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)], (string) $row[TableMap::TYPE_NUM == $indexType ? 8 + $offset : static::translateFieldName('Version', TableMap::TYPE_PHPNAME, $indexType)])); } /** @@ -382,6 +388,7 @@ class ProductVersionTableMap extends TableMap $criteria->addSelectColumn(ProductVersionTableMap::REF); $criteria->addSelectColumn(ProductVersionTableMap::VISIBLE); $criteria->addSelectColumn(ProductVersionTableMap::POSITION); + $criteria->addSelectColumn(ProductVersionTableMap::TEMPLATE_ID); $criteria->addSelectColumn(ProductVersionTableMap::CREATED_AT); $criteria->addSelectColumn(ProductVersionTableMap::UPDATED_AT); $criteria->addSelectColumn(ProductVersionTableMap::VERSION); @@ -393,6 +400,7 @@ class ProductVersionTableMap extends TableMap $criteria->addSelectColumn($alias . '.REF'); $criteria->addSelectColumn($alias . '.VISIBLE'); $criteria->addSelectColumn($alias . '.POSITION'); + $criteria->addSelectColumn($alias . '.TEMPLATE_ID'); $criteria->addSelectColumn($alias . '.CREATED_AT'); $criteria->addSelectColumn($alias . '.UPDATED_AT'); $criteria->addSelectColumn($alias . '.VERSION'); diff --git a/core/lib/Thelia/Model/Map/TemplateI18nTableMap.php b/core/lib/Thelia/Model/Map/TemplateI18nTableMap.php new file mode 100644 index 000000000..8db2f4fcf --- /dev/null +++ b/core/lib/Thelia/Model/Map/TemplateI18nTableMap.php @@ -0,0 +1,473 @@ + array('Id', 'Locale', 'Name', ), + self::TYPE_STUDLYPHPNAME => array('id', 'locale', 'name', ), + self::TYPE_COLNAME => array(TemplateI18nTableMap::ID, TemplateI18nTableMap::LOCALE, TemplateI18nTableMap::NAME, ), + self::TYPE_RAW_COLNAME => array('ID', 'LOCALE', 'NAME', ), + self::TYPE_FIELDNAME => array('id', 'locale', 'name', ), + self::TYPE_NUM => array(0, 1, 2, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 + */ + protected static $fieldKeys = array ( + self::TYPE_PHPNAME => array('Id' => 0, 'Locale' => 1, 'Name' => 2, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'locale' => 1, 'name' => 2, ), + self::TYPE_COLNAME => array(TemplateI18nTableMap::ID => 0, TemplateI18nTableMap::LOCALE => 1, TemplateI18nTableMap::NAME => 2, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'LOCALE' => 1, 'NAME' => 2, ), + self::TYPE_FIELDNAME => array('id' => 0, 'locale' => 1, 'name' => 2, ), + self::TYPE_NUM => array(0, 1, 2, ) + ); + + /** + * Initialize the table attributes and columns + * Relations are not initialized by this method since they are lazy loaded + * + * @return void + * @throws PropelException + */ + public function initialize() + { + // attributes + $this->setName('template_i18n'); + $this->setPhpName('TemplateI18n'); + $this->setClassName('\\Thelia\\Model\\TemplateI18n'); + $this->setPackage('Thelia.Model'); + $this->setUseIdGenerator(false); + // columns + $this->addForeignPrimaryKey('ID', 'Id', 'INTEGER' , 'template', 'ID', true, null, null); + $this->addPrimaryKey('LOCALE', 'Locale', 'VARCHAR', true, 5, 'en_US'); + $this->addColumn('NAME', 'Name', 'VARCHAR', false, 255, null); + } // initialize() + + /** + * Build the RelationMap objects for this table relationships + */ + public function buildRelations() + { + $this->addRelation('Template', '\\Thelia\\Model\\Template', RelationMap::MANY_TO_ONE, array('id' => 'id', ), 'CASCADE', null); + } // buildRelations() + + /** + * Adds an object to the instance pool. + * + * Propel keeps cached copies of objects in an instance pool when they are retrieved + * from the database. In some cases you may need to explicitly add objects + * to the cache in order to ensure that the same objects are always returned by find*() + * and findPk*() calls. + * + * @param \Thelia\Model\TemplateI18n $obj A \Thelia\Model\TemplateI18n object. + * @param string $key (optional) key to use for instance map (for performance boost if key was already calculated externally). + */ + public static function addInstanceToPool($obj, $key = null) + { + if (Propel::isInstancePoolingEnabled()) { + if (null === $key) { + $key = serialize(array((string) $obj->getId(), (string) $obj->getLocale())); + } // if key === null + self::$instances[$key] = $obj; + } + } + + /** + * Removes an object from the instance pool. + * + * Propel keeps cached copies of objects in an instance pool when they are retrieved + * from the database. In some cases -- especially when you override doDelete + * methods in your stub classes -- you may need to explicitly remove objects + * from the cache in order to prevent returning objects that no longer exist. + * + * @param mixed $value A \Thelia\Model\TemplateI18n object or a primary key value. + */ + public static function removeInstanceFromPool($value) + { + if (Propel::isInstancePoolingEnabled() && null !== $value) { + if (is_object($value) && $value instanceof \Thelia\Model\TemplateI18n) { + $key = serialize(array((string) $value->getId(), (string) $value->getLocale())); + + } elseif (is_array($value) && count($value) === 2) { + // assume we've been passed a primary key"; + $key = serialize(array((string) $value[0], (string) $value[1])); + } elseif ($value instanceof Criteria) { + self::$instances = []; + + return; + } else { + $e = new PropelException("Invalid value passed to removeInstanceFromPool(). Expected primary key or \Thelia\Model\TemplateI18n object; got " . (is_object($value) ? get_class($value) . ' object.' : var_export($value, true))); + throw $e; + } + + unset(self::$instances[$key]); + } + } + + /** + * 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. + * + * For tables with a single-column primary key, that simple pkey value will be returned. For tables with + * a multi-column primary key, a serialize()d version of the primary key will be returned. + * + * @param array $row resultset row. + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM + */ + public static function getPrimaryKeyHashFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + // If the PK cannot be derived from the row, return NULL. + if ($row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)] === null && $row[TableMap::TYPE_NUM == $indexType ? 1 + $offset : static::translateFieldName('Locale', TableMap::TYPE_PHPNAME, $indexType)] === null) { + return null; + } + + return serialize(array((string) $row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)], (string) $row[TableMap::TYPE_NUM == $indexType ? 1 + $offset : static::translateFieldName('Locale', TableMap::TYPE_PHPNAME, $indexType)])); + } + + /** + * Retrieves the primary key from the DB resultset row + * For tables with a single-column primary key, that simple pkey value will be returned. For tables with + * a multi-column primary key, an array of the primary key columns will be returned. + * + * @param array $row resultset row. + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM + * + * @return mixed The primary key of the row + */ + public static function getPrimaryKeyFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + + return $pks; + } + + /** + * The class that the tableMap will make instances of. + * + * If $withPrefix is true, the returned path + * uses a dot-path notation which is translated into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @param boolean $withPrefix Whether or not to return the path with the class name + * @return string path.to.ClassName + */ + public static function getOMClass($withPrefix = true) + { + return $withPrefix ? TemplateI18nTableMap::CLASS_DEFAULT : TemplateI18nTableMap::OM_CLASS; + } + + /** + * Populates an object of the default type or an object that inherit from the default. + * + * @param array $row row returned by DataFetcher->fetch(). + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType The index type of $row. Mostly DataFetcher->getIndexType(). + One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return array (TemplateI18n object, last column rank) + */ + public static function populateObject($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + $key = TemplateI18nTableMap::getPrimaryKeyHashFromRow($row, $offset, $indexType); + if (null !== ($obj = TemplateI18nTableMap::getInstanceFromPool($key))) { + // We no longer rehydrate the object, since this can cause data loss. + // See http://www.propelorm.org/ticket/509 + // $obj->hydrate($row, $offset, true); // rehydrate + $col = $offset + TemplateI18nTableMap::NUM_HYDRATE_COLUMNS; + } else { + $cls = TemplateI18nTableMap::OM_CLASS; + $obj = new $cls(); + $col = $obj->hydrate($row, $offset, false, $indexType); + TemplateI18nTableMap::addInstanceToPool($obj, $key); + } + + return array($obj, $col); + } + + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @param DataFetcherInterface $dataFetcher + * @return array + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(DataFetcherInterface $dataFetcher) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = static::getOMClass(false); + // populate the object(s) + while ($row = $dataFetcher->fetch()) { + $key = TemplateI18nTableMap::getPrimaryKeyHashFromRow($row, 0, $dataFetcher->getIndexType()); + if (null !== ($obj = TemplateI18nTableMap::getInstanceFromPool($key))) { + // We no longer rehydrate the object, since this can cause data loss. + // See http://www.propelorm.org/ticket/509 + // $obj->hydrate($row, 0, true); // rehydrate + $results[] = $obj; + } else { + $obj = new $cls(); + $obj->hydrate($row); + $results[] = $obj; + TemplateI18nTableMap::addInstanceToPool($obj, $key); + } // if key exists + } + + return $results; + } + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param Criteria $criteria object containing the columns to add. + * @param string $alias optional table alias + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria, $alias = null) + { + if (null === $alias) { + $criteria->addSelectColumn(TemplateI18nTableMap::ID); + $criteria->addSelectColumn(TemplateI18nTableMap::LOCALE); + $criteria->addSelectColumn(TemplateI18nTableMap::NAME); + } else { + $criteria->addSelectColumn($alias . '.ID'); + $criteria->addSelectColumn($alias . '.LOCALE'); + $criteria->addSelectColumn($alias . '.NAME'); + } + } + + /** + * Returns the TableMap related to this object. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getServiceContainer()->getDatabaseMap(TemplateI18nTableMap::DATABASE_NAME)->getTable(TemplateI18nTableMap::TABLE_NAME); + } + + /** + * Add a TableMap instance to the database for this tableMap class. + */ + public static function buildTableMap() + { + $dbMap = Propel::getServiceContainer()->getDatabaseMap(TemplateI18nTableMap::DATABASE_NAME); + if (!$dbMap->hasTable(TemplateI18nTableMap::TABLE_NAME)) { + $dbMap->addTableObject(new TemplateI18nTableMap()); + } + } + + /** + * Performs a DELETE on the database, given a TemplateI18n or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or TemplateI18n object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(TemplateI18nTableMap::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + // rename for clarity + $criteria = $values; + } elseif ($values instanceof \Thelia\Model\TemplateI18n) { // it's a model object + // create criteria based on pk values + $criteria = $values->buildPkeyCriteria(); + } else { // it's a primary key, or an array of pks + $criteria = new Criteria(TemplateI18nTableMap::DATABASE_NAME); + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey values + if (count($values) == count($values, COUNT_RECURSIVE)) { + // array is not multi-dimensional + $values = array($values); + } + foreach ($values as $value) { + $criterion = $criteria->getNewCriterion(TemplateI18nTableMap::ID, $value[0]); + $criterion->addAnd($criteria->getNewCriterion(TemplateI18nTableMap::LOCALE, $value[1])); + $criteria->addOr($criterion); + } + } + + $query = TemplateI18nQuery::create()->mergeWith($criteria); + + if ($values instanceof Criteria) { TemplateI18nTableMap::clearInstancePool(); + } elseif (!is_object($values)) { // it's a primary key, or an array of pks + foreach ((array) $values as $singleval) { TemplateI18nTableMap::removeInstanceFromPool($singleval); + } + } + + return $query->delete($con); + } + + /** + * Deletes all rows from the template_i18n table. + * + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll(ConnectionInterface $con = null) + { + return TemplateI18nQuery::create()->doDeleteAll($con); + } + + /** + * Performs an INSERT on the database, given a TemplateI18n or Criteria object. + * + * @param mixed $criteria Criteria or TemplateI18n object containing data that is used to create the INSERT statement. + * @param ConnectionInterface $con the ConnectionInterface connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($criteria, ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(TemplateI18nTableMap::DATABASE_NAME); + } + + if ($criteria instanceof Criteria) { + $criteria = clone $criteria; // rename for clarity + } else { + $criteria = $criteria->buildCriteria(); // build Criteria from TemplateI18n object + } + + + // Set the correct dbName + $query = TemplateI18nQuery::create()->mergeWith($criteria); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->beginTransaction(); + $pk = $query->doInsert($con); + $con->commit(); + } catch (PropelException $e) { + $con->rollBack(); + throw $e; + } + + return $pk; + } + +} // TemplateI18nTableMap +// This is the static code needed to register the TableMap for this table with the main Propel class. +// +TemplateI18nTableMap::buildTableMap(); diff --git a/core/lib/Thelia/Model/Map/TemplateTableMap.php b/core/lib/Thelia/Model/Map/TemplateTableMap.php new file mode 100644 index 000000000..f1509cbc7 --- /dev/null +++ b/core/lib/Thelia/Model/Map/TemplateTableMap.php @@ -0,0 +1,455 @@ + array('Id', 'CreatedAt', 'UpdatedAt', ), + self::TYPE_STUDLYPHPNAME => array('id', 'createdAt', 'updatedAt', ), + self::TYPE_COLNAME => array(TemplateTableMap::ID, TemplateTableMap::CREATED_AT, TemplateTableMap::UPDATED_AT, ), + self::TYPE_RAW_COLNAME => array('ID', 'CREATED_AT', 'UPDATED_AT', ), + self::TYPE_FIELDNAME => array('id', 'created_at', 'updated_at', ), + self::TYPE_NUM => array(0, 1, 2, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 + */ + protected static $fieldKeys = array ( + self::TYPE_PHPNAME => array('Id' => 0, 'CreatedAt' => 1, 'UpdatedAt' => 2, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'createdAt' => 1, 'updatedAt' => 2, ), + self::TYPE_COLNAME => array(TemplateTableMap::ID => 0, TemplateTableMap::CREATED_AT => 1, TemplateTableMap::UPDATED_AT => 2, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'CREATED_AT' => 1, 'UPDATED_AT' => 2, ), + self::TYPE_FIELDNAME => array('id' => 0, 'created_at' => 1, 'updated_at' => 2, ), + self::TYPE_NUM => array(0, 1, 2, ) + ); + + /** + * Initialize the table attributes and columns + * Relations are not initialized by this method since they are lazy loaded + * + * @return void + * @throws PropelException + */ + public function initialize() + { + // attributes + $this->setName('template'); + $this->setPhpName('Template'); + $this->setClassName('\\Thelia\\Model\\Template'); + $this->setPackage('Thelia.Model'); + $this->setUseIdGenerator(true); + // columns + $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); + $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); + $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); + } // initialize() + + /** + * Build the RelationMap objects for this table relationships + */ + public function buildRelations() + { + $this->addRelation('Product', '\\Thelia\\Model\\Product', RelationMap::ONE_TO_MANY, array('id' => 'template_id', ), null, null, 'Products'); + $this->addRelation('FeatureTemplate', '\\Thelia\\Model\\FeatureTemplate', RelationMap::ONE_TO_MANY, array('id' => 'template_id', ), null, null, 'FeatureTemplates'); + $this->addRelation('AttributeTemplate', '\\Thelia\\Model\\AttributeTemplate', RelationMap::ONE_TO_MANY, array('id' => 'template_id', ), null, null, 'AttributeTemplates'); + $this->addRelation('TemplateI18n', '\\Thelia\\Model\\TemplateI18n', RelationMap::ONE_TO_MANY, array('id' => 'id', ), 'CASCADE', null, 'TemplateI18ns'); + $this->addRelation('Feature', '\\Thelia\\Model\\Feature', RelationMap::MANY_TO_MANY, array(), 'CASCADE', 'RESTRICT', 'Features'); + $this->addRelation('Attribute', '\\Thelia\\Model\\Attribute', RelationMap::MANY_TO_MANY, array(), 'CASCADE', 'RESTRICT', 'Attributes'); + } // buildRelations() + + /** + * + * Gets the list of behaviors registered for this table + * + * @return array Associative array (name => parameters) of behaviors + */ + public function getBehaviors() + { + return array( + 'i18n' => array('i18n_table' => '%TABLE%_i18n', 'i18n_phpname' => '%PHPNAME%I18n', 'i18n_columns' => 'name', 'locale_column' => 'locale', 'locale_length' => '5', 'default_locale' => '', 'locale_alias' => '', ), + 'timestampable' => array('create_column' => 'created_at', 'update_column' => 'updated_at', ), + ); + } // getBehaviors() + /** + * Method to invalidate the instance pool of all tables related to template * by a foreign key with ON DELETE CASCADE + */ + public static function clearRelatedInstancePool() + { + // Invalidate objects in ".$this->getClassNameFromBuilder($joinedTableTableMapBuilder)." instance pool, + // since one or more of them may be deleted by ON DELETE CASCADE/SETNULL rule. + TemplateI18nTableMap::clearInstancePool(); + } + + /** + * 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. + * + * For tables with a single-column primary key, that simple pkey value will be returned. For tables with + * a multi-column primary key, a serialize()d version of the primary key will be returned. + * + * @param array $row resultset row. + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM + */ + public static function getPrimaryKeyHashFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + // If the PK cannot be derived from the row, return NULL. + if ($row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)] === null) { + return null; + } + + return (string) $row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)]; + } + + /** + * Retrieves the primary key from the DB resultset row + * For tables with a single-column primary key, that simple pkey value will be returned. For tables with + * a multi-column primary key, an array of the primary key columns will be returned. + * + * @param array $row resultset row. + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM + * + * @return mixed The primary key of the row + */ + public static function getPrimaryKeyFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + + return (int) $row[ + $indexType == TableMap::TYPE_NUM + ? 0 + $offset + : self::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType) + ]; + } + + /** + * The class that the tableMap will make instances of. + * + * If $withPrefix is true, the returned path + * uses a dot-path notation which is translated into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @param boolean $withPrefix Whether or not to return the path with the class name + * @return string path.to.ClassName + */ + public static function getOMClass($withPrefix = true) + { + return $withPrefix ? TemplateTableMap::CLASS_DEFAULT : TemplateTableMap::OM_CLASS; + } + + /** + * Populates an object of the default type or an object that inherit from the default. + * + * @param array $row row returned by DataFetcher->fetch(). + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType The index type of $row. Mostly DataFetcher->getIndexType(). + One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return array (Template object, last column rank) + */ + public static function populateObject($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + $key = TemplateTableMap::getPrimaryKeyHashFromRow($row, $offset, $indexType); + if (null !== ($obj = TemplateTableMap::getInstanceFromPool($key))) { + // We no longer rehydrate the object, since this can cause data loss. + // See http://www.propelorm.org/ticket/509 + // $obj->hydrate($row, $offset, true); // rehydrate + $col = $offset + TemplateTableMap::NUM_HYDRATE_COLUMNS; + } else { + $cls = TemplateTableMap::OM_CLASS; + $obj = new $cls(); + $col = $obj->hydrate($row, $offset, false, $indexType); + TemplateTableMap::addInstanceToPool($obj, $key); + } + + return array($obj, $col); + } + + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @param DataFetcherInterface $dataFetcher + * @return array + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(DataFetcherInterface $dataFetcher) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = static::getOMClass(false); + // populate the object(s) + while ($row = $dataFetcher->fetch()) { + $key = TemplateTableMap::getPrimaryKeyHashFromRow($row, 0, $dataFetcher->getIndexType()); + if (null !== ($obj = TemplateTableMap::getInstanceFromPool($key))) { + // We no longer rehydrate the object, since this can cause data loss. + // See http://www.propelorm.org/ticket/509 + // $obj->hydrate($row, 0, true); // rehydrate + $results[] = $obj; + } else { + $obj = new $cls(); + $obj->hydrate($row); + $results[] = $obj; + TemplateTableMap::addInstanceToPool($obj, $key); + } // if key exists + } + + return $results; + } + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param Criteria $criteria object containing the columns to add. + * @param string $alias optional table alias + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria, $alias = null) + { + if (null === $alias) { + $criteria->addSelectColumn(TemplateTableMap::ID); + $criteria->addSelectColumn(TemplateTableMap::CREATED_AT); + $criteria->addSelectColumn(TemplateTableMap::UPDATED_AT); + } else { + $criteria->addSelectColumn($alias . '.ID'); + $criteria->addSelectColumn($alias . '.CREATED_AT'); + $criteria->addSelectColumn($alias . '.UPDATED_AT'); + } + } + + /** + * Returns the TableMap related to this object. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getServiceContainer()->getDatabaseMap(TemplateTableMap::DATABASE_NAME)->getTable(TemplateTableMap::TABLE_NAME); + } + + /** + * Add a TableMap instance to the database for this tableMap class. + */ + public static function buildTableMap() + { + $dbMap = Propel::getServiceContainer()->getDatabaseMap(TemplateTableMap::DATABASE_NAME); + if (!$dbMap->hasTable(TemplateTableMap::TABLE_NAME)) { + $dbMap->addTableObject(new TemplateTableMap()); + } + } + + /** + * Performs a DELETE on the database, given a Template or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or Template object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(TemplateTableMap::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + // rename for clarity + $criteria = $values; + } elseif ($values instanceof \Thelia\Model\Template) { // it's a model object + // create criteria based on pk values + $criteria = $values->buildPkeyCriteria(); + } else { // it's a primary key, or an array of pks + $criteria = new Criteria(TemplateTableMap::DATABASE_NAME); + $criteria->add(TemplateTableMap::ID, (array) $values, Criteria::IN); + } + + $query = TemplateQuery::create()->mergeWith($criteria); + + if ($values instanceof Criteria) { TemplateTableMap::clearInstancePool(); + } elseif (!is_object($values)) { // it's a primary key, or an array of pks + foreach ((array) $values as $singleval) { TemplateTableMap::removeInstanceFromPool($singleval); + } + } + + return $query->delete($con); + } + + /** + * Deletes all rows from the template table. + * + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll(ConnectionInterface $con = null) + { + return TemplateQuery::create()->doDeleteAll($con); + } + + /** + * Performs an INSERT on the database, given a Template or Criteria object. + * + * @param mixed $criteria Criteria or Template object containing data that is used to create the INSERT statement. + * @param ConnectionInterface $con the ConnectionInterface connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($criteria, ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(TemplateTableMap::DATABASE_NAME); + } + + if ($criteria instanceof Criteria) { + $criteria = clone $criteria; // rename for clarity + } else { + $criteria = $criteria->buildCriteria(); // build Criteria from Template object + } + + if ($criteria->containsKey(TemplateTableMap::ID) && $criteria->keyContainsValue(TemplateTableMap::ID) ) { + throw new PropelException('Cannot insert a value for auto-increment primary key ('.TemplateTableMap::ID.')'); + } + + + // Set the correct dbName + $query = TemplateQuery::create()->mergeWith($criteria); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->beginTransaction(); + $pk = $query->doInsert($con); + $con->commit(); + } catch (PropelException $e) { + $con->rollBack(); + throw $e; + } + + return $pk; + } + +} // TemplateTableMap +// This is the static code needed to register the TableMap for this table with the main Propel class. +// +TemplateTableMap::buildTableMap(); diff --git a/core/lib/Thelia/Model/Template.php b/core/lib/Thelia/Model/Template.php new file mode 100644 index 000000000..881187573 --- /dev/null +++ b/core/lib/Thelia/Model/Template.php @@ -0,0 +1,68 @@ +dispatchEvent(TheliaEvents::BEFORE_CREATETEMPLATE, new TemplateEvent($this)); + + return true; + } + + /** + * {@inheritDoc} + */ + public function postInsert(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_CREATETEMPLATE, new TemplateEvent($this)); + } + + /** + * {@inheritDoc} + */ + public function preUpdate(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::BEFORE_UPDATETEMPLATE, new TemplateEvent($this)); + + return true; + } + + /** + * {@inheritDoc} + */ + public function postUpdate(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_UPDATETEMPLATE, new TemplateEvent($this)); + } + + /** + * {@inheritDoc} + */ + public function preDelete(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::BEFORE_DELETETEMPLATE, new TemplateEvent($this)); + + return true; + } + + /** + * {@inheritDoc} + */ + public function postDelete(ConnectionInterface $con = null) + { + $this->dispatchEvent(TheliaEvents::AFTER_DELETETEMPLATE, new TemplateEvent($this)); + } + +} diff --git a/core/lib/Thelia/Model/TemplateI18n.php b/core/lib/Thelia/Model/TemplateI18n.php new file mode 100644 index 000000000..19e88f692 --- /dev/null +++ b/core/lib/Thelia/Model/TemplateI18n.php @@ -0,0 +1,10 @@ +send(); + exit; } } diff --git a/install/faker.php b/install/faker.php index fdcf6212c..f15570e8a 100755 --- a/install/faker.php +++ b/install/faker.php @@ -240,6 +240,28 @@ try { } } + $template = new Thelia\Model\Template(); + setI18n($faker, $template, array("Name" => 20)); + $template->save(); + + foreach($attributeList as $attributeId => $attributeAvId) { + $at = new Thelia\Model\AttributeTemplate(); + + $at + ->setTemplate($template) + ->setAttributeId($attributeId) + ->save(); + } + + foreach($featureList as $featureId => $featureAvId) { + $ft = new Thelia\Model\FeatureTemplate(); + + $ft + ->setTemplate($template) + ->setFeatureId($featureId) + ->save(); + } + //folders and contents $contentIdList = array(); for($i=0; $i<4; $i++) { @@ -296,12 +318,12 @@ try { $subcategory = createCategory($faker, $category->getId(), $j, $categoryIdList, $contentIdList); for($k=0; $krollBack(); } -function createProduct($faker, $category, $position, &$productIdList) +function createProduct($faker, $category, $position, $template, &$productIdList) { $product = new Thelia\Model\Product(); $product->setRef($category->getId() . '_' . $position . '_' . $faker->randomNumber(8)); @@ -424,6 +446,8 @@ function createProduct($faker, $category, $position, &$productIdList) $product->setVisible(rand(1, 10)>7 ? 0 : 1); $product->setPosition($position); $product->setTaxRuleId(1); + $product->setTemplate($template); + setI18n($faker, $product); $product->save(); @@ -521,18 +545,18 @@ function generate_image($image, $position, $typeobj, $id) { $image->save($image_file); } -function setI18n($faker, &$object) +function setI18n($faker, &$object, $fields = array('Title' => 20, 'Description' => 50) ) { - $localeList = array('fr_FR', 'en_EN'); - - $title = $faker->text(20); - $description = $faker->text(50); + $localeList = $localeList = array('fr_FR', 'en_US', 'es_ES', 'it_IT'); foreach($localeList as $locale) { $object->setLocale($locale); - $object->setTitle($locale . ' : ' . $title); - $object->setDescription($locale . ' : ' . $description); + foreach($fields as $name => $length) { + $func = "set".ucfirst(strtolower($name)); + + $object->$func($locale . ' : ' . $faker->text($length)); + } } } /** diff --git a/install/faker_100categories_1000products_4locales.php b/install/faker_100categories_1000products_4locales.php index ce18aa5c7..eb98d3e10 100755 --- a/install/faker_100categories_1000products_4locales.php +++ b/install/faker_100categories_1000products_4locales.php @@ -156,18 +156,18 @@ try { $con->rollBack(); } -function setI18n($faker, &$object) +function setI18n($faker, &$object, $fields = array('Title' => 20, 'Description' => 50) ) { - $localeList = array('fr_FR', 'en_EN', 'es_ES', 'it_IT'); - - $title = $faker->text(20); - $description = $faker->text(50); + $localeList = array('fr_FR', 'en_US', 'es_ES', 'it_IT'); foreach($localeList as $locale) { $object->setLocale($locale); - $object->setTitle($locale . ' : ' . $title); - $object->setDescription($locale . ' : ' . $description); + foreach($fields as $name => $length) { + $func = "set$name"; + + $object->$func($locale . ' : ' . $faker->text($length)); + } } } diff --git a/install/insert.sql b/install/insert.sql index d91035382..1cc7c55e6 100755 --- a/install/insert.sql +++ b/install/insert.sql @@ -17,8 +17,14 @@ INSERT INTO `config` (`name`, `value`, `secured`, `hidden`, `created_at`, `updat ('image_cache_dir_from_web_root', 'cache/images', 0, 0, NOW(), NOW()), ('currency_rate_update_url', 'http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml', 0, 0, NOW(), NOW()), ('page_not_found_view', '404.html', 0, 0, NOW(), NOW()), -('use_tax_free_amounts', 0, 1, 0, NOW(), NOW()), -('process_assets', '1', 0, 0, NOW(), NOW()); +('use_tax_free_amounts', 0, 0, 0, NOW(), NOW()), +('process_assets', '1', 0, 0, NOW(), NOW()), +('thelia_admin_remember_me_cookie_name', 'tarmcn', 0, 0, NOW(), NOW()), +('thelia_admin_remember_me_cookie_expiration', 2592000, 0, 0, NOW(), NOW()), +('thelia_customer_remember_me_cookie_name', 'tcrmcn', 0, 0, NOW(), NOW()), +('thelia_customer_remember_me_cookie_expiration', 31536000, 0, 0, NOW(), NOW()), +('session_config.handlers', 'Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeFileSessionHandler', 0, 0, NOW(), NOW()) +; INSERT INTO `module` (`id`, `code`, `type`, `activate`, `position`, `full_namespace`, `created_at`, `updated_at`) VALUES diff --git a/install/thelia.sql b/install/thelia.sql index dd0e9a79c..5aa478da5 100755 --- a/install/thelia.sql +++ b/install/thelia.sql @@ -36,6 +36,7 @@ CREATE TABLE `product` `ref` VARCHAR(255) NOT NULL, `visible` TINYINT DEFAULT 0 NOT NULL, `position` INTEGER NOT NULL, + `template_id` INTEGER NOT NULL, `created_at` DATETIME, `updated_at` DATETIME, `version` INTEGER DEFAULT 0, @@ -44,11 +45,15 @@ CREATE TABLE `product` PRIMARY KEY (`id`), UNIQUE INDEX `ref_UNIQUE` (`ref`), INDEX `idx_product_tax_rule_id` (`tax_rule_id`), + INDEX `fk_product_template1_idx` (`template_id`), CONSTRAINT `fk_product_tax_rule_id` FOREIGN KEY (`tax_rule_id`) REFERENCES `tax_rule` (`id`) ON UPDATE RESTRICT - ON DELETE SET NULL + ON DELETE SET NULL, + CONSTRAINT `fk_product_template1` + FOREIGN KEY (`template_id`) + REFERENCES `template` (`id`) ) ENGINE=InnoDB; -- --------------------------------------------------------------------- @@ -243,31 +248,29 @@ CREATE TABLE `feature_product` ) ENGINE=InnoDB; -- --------------------------------------------------------------------- --- feature_category +-- feature_template -- --------------------------------------------------------------------- -DROP TABLE IF EXISTS `feature_category`; +DROP TABLE IF EXISTS `feature_template`; -CREATE TABLE `feature_category` +CREATE TABLE `feature_template` ( `id` INTEGER NOT NULL AUTO_INCREMENT, `feature_id` INTEGER NOT NULL, - `category_id` INTEGER NOT NULL, + `template_id` INTEGER NOT NULL, `created_at` DATETIME, `updated_at` DATETIME, PRIMARY KEY (`id`), - INDEX `idx_feature_category_category_id` (`category_id`), - INDEX `idx_feature_category_feature_id` (`feature_id`), - CONSTRAINT `fk_feature_category_category_id` - FOREIGN KEY (`category_id`) - REFERENCES `category` (`id`) - ON UPDATE RESTRICT - ON DELETE CASCADE, - CONSTRAINT `fk_feature_category_feature_id` + INDEX `idx_feature_template_id` (`feature_id`), + INDEX `fk_feature_template_idx` (`template_id`), + CONSTRAINT `fk_feature_template_id` FOREIGN KEY (`feature_id`) REFERENCES `feature` (`id`) ON UPDATE RESTRICT - ON DELETE CASCADE + ON DELETE CASCADE, + CONSTRAINT `fk_feature_template` + FOREIGN KEY (`template_id`) + REFERENCES `template` (`id`) ) ENGINE=InnoDB; -- --------------------------------------------------------------------- @@ -367,31 +370,29 @@ CREATE TABLE `product_sale_elements` ) ENGINE=InnoDB; -- --------------------------------------------------------------------- --- attribute_category +-- attribute_template -- --------------------------------------------------------------------- -DROP TABLE IF EXISTS `attribute_category`; +DROP TABLE IF EXISTS `attribute_template`; -CREATE TABLE `attribute_category` +CREATE TABLE `attribute_template` ( `id` INTEGER NOT NULL AUTO_INCREMENT, - `category_id` INTEGER NOT NULL, `attribute_id` INTEGER NOT NULL, + `template_id` INTEGER NOT NULL, `created_at` DATETIME, `updated_at` DATETIME, PRIMARY KEY (`id`), - INDEX `idx_attribute_category_category_id` (`category_id`), - INDEX `idx_attribute_category_attribute_id` (`attribute_id`), - CONSTRAINT `fk_attribute_category_category_id` - FOREIGN KEY (`category_id`) - REFERENCES `category` (`id`) - ON UPDATE RESTRICT - ON DELETE CASCADE, - CONSTRAINT `fk_attribute_category_attribute_id` + INDEX `idx_attribute_template_id` (`attribute_id`), + INDEX `fk_attribute_template_idx` (`template_id`), + CONSTRAINT `fk_attribute_template_id` FOREIGN KEY (`attribute_id`) REFERENCES `attribute` (`id`) ON UPDATE RESTRICT - ON DELETE CASCADE + ON DELETE CASCADE, + CONSTRAINT `fk_attribute_template` + FOREIGN KEY (`template_id`) + REFERENCES `template` (`id`) ) ENGINE=InnoDB; -- --------------------------------------------------------------------- @@ -433,6 +434,8 @@ CREATE TABLE `customer` `lang` VARCHAR(10), `sponsor` VARCHAR(50), `discount` FLOAT, + `remember_me_token` VARCHAR(255), + `remember_me_serial` VARCHAR(255), `created_at` DATETIME, `updated_at` DATETIME, PRIMARY KEY (`id`), @@ -923,6 +926,8 @@ CREATE TABLE `admin` `password` VARCHAR(128) NOT NULL, `algo` VARCHAR(128), `salt` VARCHAR(128), + `remember_me_token` VARCHAR(255), + `remember_me_serial` VARCHAR(255), `created_at` DATETIME, `updated_at` DATETIME, PRIMARY KEY (`id`) @@ -1482,6 +1487,20 @@ CREATE TABLE `rewriting_argument` ON DELETE CASCADE ) ENGINE=InnoDB; +-- --------------------------------------------------------------------- +-- template +-- --------------------------------------------------------------------- + +DROP TABLE IF EXISTS `template`; + +CREATE TABLE `template` +( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `created_at` DATETIME, + `updated_at` DATETIME, + PRIMARY KEY (`id`) +) ENGINE=InnoDB; + -- --------------------------------------------------------------------- -- category_i18n -- --------------------------------------------------------------------- @@ -2060,6 +2079,24 @@ CREATE TABLE `folder_document_i18n` ON DELETE CASCADE ) ENGINE=InnoDB; +-- --------------------------------------------------------------------- +-- template_i18n +-- --------------------------------------------------------------------- + +DROP TABLE IF EXISTS `template_i18n`; + +CREATE TABLE `template_i18n` +( + `id` INTEGER NOT NULL, + `locale` VARCHAR(5) DEFAULT 'en_US' NOT NULL, + `name` VARCHAR(255), + PRIMARY KEY (`id`,`locale`), + CONSTRAINT `template_i18n_FK_1` + FOREIGN KEY (`id`) + REFERENCES `template` (`id`) + ON DELETE CASCADE +) ENGINE=InnoDB; + -- --------------------------------------------------------------------- -- category_version -- --------------------------------------------------------------------- @@ -2097,6 +2134,7 @@ CREATE TABLE `product_version` `ref` VARCHAR(255) NOT NULL, `visible` TINYINT DEFAULT 0 NOT NULL, `position` INTEGER NOT NULL, + `template_id` INTEGER NOT NULL, `created_at` DATETIME, `updated_at` DATETIME, `version` INTEGER DEFAULT 0 NOT NULL, diff --git a/local/config/schema.xml b/local/config/schema.xml index 1d928bc7b..1ffeb028a 100755 --- a/local/config/schema.xml +++ b/local/config/schema.xml @@ -1,1143 +1,1162 @@ - - -
    - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - -
    - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - -
    - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - -
    - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - -
    - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - -
    - - - - - -
    - - - - - - - - - - - -
    - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - -
    - - - - - - - - - -
    - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - -
    - - - - - - - - -
    - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - -
    - + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + +
    + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + +
    + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + +
    + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + +
    + + + + + +
    + + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + +
    + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + +
    + + + + + + + + +
    + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + +
    + + + + + + + +
    +
    diff --git a/templates/admin/default/ajax/template-attribute-list.html b/templates/admin/default/ajax/template-attribute-list.html new file mode 100644 index 000000000..b6379672a --- /dev/null +++ b/templates/admin/default/ajax/template-attribute-list.html @@ -0,0 +1,15 @@ +
    + {ifloop rel="free_attributes"} + + {intl l='Select an attribute and click (+) to add it to this template'} + {/ifloop} + {elseloop rel="free_attributes"} +
    There is currently no available attributes.
    + {/elseloop} +
    + diff --git a/templates/admin/default/includes/thelia_news_feed.html b/templates/admin/default/ajax/thelia_news_feed.html similarity index 100% rename from templates/admin/default/includes/thelia_news_feed.html rename to templates/admin/default/ajax/thelia_news_feed.html diff --git a/templates/admin/default/attributes.html b/templates/admin/default/attributes.html index 57fd9c256..348219f5c 100644 --- a/templates/admin/default/attributes.html +++ b/templates/admin/default/attributes.html @@ -224,7 +224,7 @@ dialog_title = {intl l="Delete attribute"} dialog_message = {intl l="Do you really want to delete this attribute ? It will be removed from all product templates."} - form_action = {url path='/admin/configuration/attributes/remove_from-all-templates' attribute_id=$ID} + form_action = {url path='/admin/configuration/attributes/delete'} form_content = {$smarty.capture.delete_dialog nofilter} } diff --git a/templates/admin/default/login.html b/templates/admin/default/login.html index 07e238c88..682d2b954 100755 --- a/templates/admin/default/login.html +++ b/templates/admin/default/login.html @@ -64,7 +64,7 @@ {block name="javascript-initialization"} {/block} \ No newline at end of file diff --git a/templates/admin/default/template-edit.html b/templates/admin/default/template-edit.html new file mode 100644 index 000000000..0a073b719 --- /dev/null +++ b/templates/admin/default/template-edit.html @@ -0,0 +1,115 @@ +{extends file="admin-layout.tpl"} + +{block name="page-title"}{intl l='Edit a template'}{/block} + +{block name="check-permissions"}admin.configuration.templates.edit{/block} + +{block name="main-content"} +
    + +
    + + {loop name="template_edit" type="template" id="$template_id" backend_context="1" lang="$edit_language_id"} + + + +
    +
    +
    + +
    + {intl l="Edit template $NAME"} +
    + +
    +
    + + {form name="thelia.admin.template.modification"} + + + {* Be sure to get the template ID, even if the form could not be validated *} + + + {include file="includes/inner-form-toolbar.html" close_url="{url path='/admin/configuration/templates'}"} + + {form_hidden_fields form=$form} + + {form_field form=$form field='success_url'} + + {/form_field} + + {form_field form=$form field='locale'} + + {/form_field} + + {if $form_error}
    {$form_error_message}
    {/if} + + {form_field form=$form field='name'} +
    + + +
    + {/form_field} + + {/form} +
    +
    + +
    +
    +
    +

    {intl l='Attributes'}

    +

    Manage attributes included in this product templates

    + +
    +
    +
    + +
    + +
    +

    {intl l='Features'}

    +

    Manage features included in this product templates

    + +
    +
    +
    +
    +
    +
    + +
    +
    + +
    + + {/loop} + + {elseloop rel="template_edit"} +
    +
    +
    + {intl l="Sorry, template ID=$template_id was not found."} +
    +
    +
    + {/elseloop} + +
    +
    +{/block} + +{block name="javascript-initialization"} + + +{/block} \ No newline at end of file diff --git a/templates/admin/default/templates.html b/templates/admin/default/templates.html new file mode 100644 index 000000000..6f88bed47 --- /dev/null +++ b/templates/admin/default/templates.html @@ -0,0 +1,215 @@ +{extends file="admin-layout.tpl"} + +{block name="page-title"}{intl l='Thelia Product Templates'}{/block} + +{block name="check-permissions"}admin.configuration.templates.view{/block} + +{block name="main-content"} +
    + +
    + + + + {module_include location='templates_top'} + +
    +
    +
    +
    + + {if ! empty($general_error) } +
    {$general_error}
    + {/if} + + + + + + + + + + {module_include location='templates_table_header'} + + + + + + + {loop name="list" type="template" backend_context="1" lang=$lang_id order=$order} + + + + + + {module_include location='templates_table_row'} + + + + {/loop} + + {elseloop rel="list"} + + + + {/elseloop} + +
    + {intl l='Thelia product templates'} + + {loop type="auth" name="can_create" roles="ADMIN" permissions="admin.configuration.templates.create"} + + + + {/loop} +
    + {admin_sortable_header + current_order=$order + order='id' + reverse_order='id_reverse' + path='/admin/configuration/templates' + label="{intl l='ID'}" + } + + {admin_sortable_header + current_order=$order + order='alpha' + reverse_order='alpha_reverse' + path='/admin/configuration/templates' + label="{intl l='Title'}" + } + {intl l="Actions"}
    {$ID} + {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.templates.change"} + {$NAME} + {/loop} + {elseloop rel="can_change"} + {$NAME} + {/elseloop} + +
    + {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.templates.change"} + + {/loop} + + {loop type="auth" name="can_change" roles="ADMIN" permissions="admin.configuration.templates.delete"} + + {/loop} +
    +
    +
    + {intl l="No product template has been created yet. Click the + button to create one."} +
    +
    +
    +
    +
    +
    + + {module_include location='templates_bottom'} + +
    +
    + +{* Adding a new template *} + +{form name="thelia.admin.template.creation"} + + {* Capture the dialog body, to pass it to the generic dialog *} + {capture "creation_dialog"} + {form_hidden_fields form=$form} + + {form_field form=$form field='success_url'} + {* on success, redirect to the edition page, _ID_ is replaced with the created template ID, see controller *} + + {/form_field} + + {form_field form=$form field='name'} +
    + + + {loop type="lang" name="default-lang" default_only="1"} +
    + + {intl l=$TITLE} +
    + +
    {intl l="Enter here the template name in the default language ($TITLE)"}
    + + {* Switch edition to the current locale *} + + + {form_field form=$form field='locale'} + + {/form_field} + {/loop} +
    + {/form_field} + + {module_include location='template_create_form'} + + {/capture} + + {include + file = "includes/generic-create-dialog.html" + + dialog_id = "creation_dialog" + dialog_title = {intl l="Create a new product template"} + dialog_body = {$smarty.capture.creation_dialog nofilter} + + dialog_ok_label = {intl l="Create this product template"} + + form_action = {url path='/admin/configuration/templates/create'} + form_enctype = {form_enctype form=$form} + form_error_message = $form_error_message + } +{/form} + +{* Delete confirmation dialog *} + +{capture "delete_dialog"} + + + {module_include location='template_delete_form'} + +{/capture} + +{include + file = "includes/generic-confirm-dialog.html" + + dialog_id = "delete_dialog" + dialog_title = {intl l="Delete template"} + dialog_message = {intl l="Do you really want to delete this template ? It will be removed from all products."} + + form_action = {url path='/admin/configuration/templates/delete'} + form_content = {$smarty.capture.delete_dialog nofilter} +} +{/block} + +{block name="javascript-initialization"} + + {javascripts file='assets/js/bootstrap-editable/bootstrap-editable.js'} + + {/javascripts} + + +{/block} \ No newline at end of file